# Coder Documentation

> Coder is a self-hosted platform for running AI coding agents and cloud development environments on infrastructure you control. It works with any cloud, IDE, OS, Git provider, and IDP.

Every page below is also available as raw Markdown by appending `.md` to its URL or by sending `Accept: text/markdown`. Full corpus: https://coder.com/docs/llms-full.txt

## Pages

- [About](https://coder.com/docs.md): Coder docs
  - [Screenshots](https://coder.com/docs/about/screenshots.md): View screenshots of the Coder platform
  - [Quickstart](https://coder.com/docs/tutorials/quickstart.md): Learn how to install and run Coder quickly
  - [Support](https://coder.com/docs/support.md): How Coder supports your deployment and you
    - [Generate a Support Bundle](https://coder.com/docs/support/support-bundle.md): Generate and upload a Support Bundle to Coder Support
  - [Contributing](https://coder.com/docs/about/contributing/CONTRIBUTING.md): Learn how to contribute to Coder
    - [Code of Conduct](https://coder.com/docs/about/contributing/CODE_OF_CONDUCT.md): See the code of conduct for contributing to Coder
    - [Documentation](https://coder.com/docs/about/contributing/documentation.md): Our style guide for use when authoring documentation
    - [Modules](https://coder.com/docs/about/contributing/modules.md): Learn how to contribute modules to Coder
    - [Templates](https://coder.com/docs/about/contributing/templates.md): Learn how to contribute templates to Coder
    - [Backend](https://coder.com/docs/about/contributing/backend.md): Our guide for backend development
    - [Frontend](https://coder.com/docs/about/contributing/frontend.md): Our guide for frontend development
    - [Security](https://coder.com/docs/about/contributing/SECURITY.md): Security vulnerability disclosure policy
    - [AI Contribution Guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING.md): Guidelines for AI-generated contributions.
- [Install](https://coder.com/docs/install.md): Installing Coder
  - [Coder CLI](https://coder.com/docs/install/cli.md): Install the standalone binary
  - [Docker](https://coder.com/docs/install/docker.md): Install Coder using Docker
  - [Kubernetes](https://coder.com/docs/install/kubernetes.md): Install Coder on Kubernetes
    - [Deploy Coder on Azure with an Application Gateway](https://coder.com/docs/install/kubernetes/kubernetes-azure-app-gateway.md): Deploy Coder on Azure with an Application Gateway
  - [Rancher](https://coder.com/docs/install/rancher.md): Deploy Coder on Rancher
  - [OpenShift](https://coder.com/docs/install/openshift.md): Install Coder on OpenShift
  - [Cloud Providers](https://coder.com/docs/install/cloud.md): Install Coder on cloud providers
    - [AWS Marketplace](https://coder.com/docs/install/cloud/aws-marketplace.md): Install Coder via AWS Marketplace
    - [GCP Compute Engine](https://coder.com/docs/install/cloud/compute-engine.md): Install Coder on GCP Compute Engine
    - [Azure VM](https://coder.com/docs/install/cloud/azure-vm.md): Install Coder on an Azure VM
  - [Air-gapped Deployments](https://coder.com/docs/install/airgap.md): Run Coder in air-gapped / disconnected / offline environments
  - [Unofficial Install Methods](https://coder.com/docs/install/other.md): Other installation methods
  - [Upgrading](https://coder.com/docs/install/upgrade.md): Learn how to upgrade Coder
    - [Upgrading Best Practices](https://coder.com/docs/install/upgrade-best-practices.md): Best practices and troubleshooting for Coder upgrades
  - [Uninstall](https://coder.com/docs/install/uninstall.md): Learn how to uninstall Coder
  - [Releases](https://coder.com/docs/install/releases.md): Learn about the Coder release channels and schedule
    - [Feature stages](https://coder.com/docs/install/releases/feature-stages.md): Information about pre-GA stages.
    - [Upgrading from ESR 2.24 to 2.29](https://coder.com/docs/install/releases/esr-2.24-2.29-upgrade.md): Upgrade Guide for ESR Releases
- [User Guides](https://coder.com/docs/user-guides.md): Guides for end-users of Coder
  - [Access Workspaces](https://coder.com/docs/user-guides/workspace-access.md): Connect to your Coder workspaces
    - [Visual Studio Code](https://coder.com/docs/user-guides/workspace-access/vscode.md): Use VSCode with Coder in the desktop or browser
    - [Web Terminal](https://coder.com/docs/user-guides/workspace-access/web-terminal.md): Use the browser-based terminal to access your workspace
    - [JetBrains IDEs](https://coder.com/docs/user-guides/workspace-access/jetbrains.md): Use JetBrains IDEs with Coder
      - [JetBrains Fleet](https://coder.com/docs/user-guides/workspace-access/jetbrains/fleet.md): Connect JetBrains Fleet to a Coder workspace
      - [JetBrains Gateway](https://coder.com/docs/user-guides/workspace-access/jetbrains/gateway.md): Use JetBrains Gateway to connect to Coder workspaces
      - [JetBrains Toolbox](https://coder.com/docs/user-guides/workspace-access/jetbrains/toolbox.md): Access Coder workspaces from JetBrains Toolbox
    - [Remote Desktop](https://coder.com/docs/user-guides/workspace-access/remote-desktops.md): Use RDP in Coder
    - [Emacs TRAMP](https://coder.com/docs/user-guides/workspace-access/emacs-tramp.md): Use Emacs TRAMP in Coder
    - [Port Forwarding](https://coder.com/docs/user-guides/workspace-access/port-forwarding.md): Access ports on your workspace
    - [Filebrowser](https://coder.com/docs/user-guides/workspace-access/filebrowser.md): Access your workspace files
    - [Web IDEs and Coder Apps](https://coder.com/docs/user-guides/workspace-access/web-ides.md): Access your workspace with IDEs in the browser
    - [code-server](https://coder.com/docs/user-guides/workspace-access/code-server.md): Access your workspace with code-server
    - [Zed](https://coder.com/docs/user-guides/workspace-access/zed.md): Access your workspace with Zed
    - [Cursor](https://coder.com/docs/user-guides/workspace-access/cursor.md): Access your workspace with Cursor
    - [Windsurf](https://coder.com/docs/user-guides/workspace-access/windsurf.md): Access your workspace with Windsurf
    - [Antigravity](https://coder.com/docs/user-guides/workspace-access/antigravity.md): Access your workspace with Antigravity
  - [Coder Desktop](https://coder.com/docs/user-guides/desktop.md): Transform remote workspaces into seamless local development environments with no port forwarding required
    - [Coder Desktop Connect and Sync](https://coder.com/docs/user-guides/desktop/desktop-connect-sync.md): Use Coder Desktop to manage your workspace code and files locally
  - [Workspace Management](https://coder.com/docs/user-guides/workspace-management.md): Manage workspaces
  - [Workspace Sharing](https://coder.com/docs/user-guides/shared-workspaces.md): Sharing workspaces
  - [Workspace Scheduling](https://coder.com/docs/user-guides/workspace-scheduling.md): Cost control with workspace schedules
  - [Workspace Lifecycle](https://coder.com/docs/user-guides/workspace-lifecycle.md): A guide to the workspace lifecycle, from creation and status through stopping and deletion.
  - [Dev Containers](https://coder.com/docs/user-guides/devcontainers.md): Run containerized development environments in your Coder workspace using the dev containers specification.
    - [Working with dev containers](https://coder.com/docs/user-guides/devcontainers/working-with-dev-containers.md): Access dev containers via SSH, your IDE, or web terminal.
    - [Customizing dev containers](https://coder.com/docs/user-guides/devcontainers/customizing-dev-containers.md): Configure custom agent names, apps, and display options in devcontainer.json.
    - [Troubleshooting dev containers](https://coder.com/docs/user-guides/devcontainers/troubleshooting-dev-containers.md): Diagnose and resolve common issues with dev containers in your Coder workspace.
  - [Dotfiles](https://coder.com/docs/user-guides/workspace-dotfiles.md): Personalize your environment with dotfiles
  - [User secrets](https://coder.com/docs/user-guides/user-secrets.md): Store secret values in Coder and automatically inject them into workspaces
- [Administration](https://coder.com/docs/admin.md): Guides for template and deployment administrators
  - [Setup](https://coder.com/docs/admin/setup.md): Configure user access to your control plane.
    - [Appearance](https://coder.com/docs/admin/setup/appearance.md): Learn how to configure the appearance of Coder
    - [Telemetry](https://coder.com/docs/admin/setup/telemetry.md): Learn what usage telemetry Coder collects
    - [Data Retention](https://coder.com/docs/admin/setup/data-retention.md): Configure data retention policies for database tables
  - [Infrastructure](https://coder.com/docs/admin/infrastructure.md): How to integrate Coder with your organization's compute
    - [Architecture](https://coder.com/docs/admin/infrastructure/architecture.md): Learn about Coder's architecture
    - [Validated Architectures](https://coder.com/docs/admin/infrastructure/validated-architectures.md): Architectures for large Coder deployments
      - [Up to 1,000 Users](https://coder.com/docs/admin/infrastructure/validated-architectures/1k-users.md): Hardware specifications and architecture guidance for Coder deployments that support up to 1,000 users
      - [Up to 2,000 Users](https://coder.com/docs/admin/infrastructure/validated-architectures/2k-users.md): Hardware specifications and architecture guidance for Coder deployments that support up to 2,000 users
      - [Up to 3,000 Users](https://coder.com/docs/admin/infrastructure/validated-architectures/3k-users.md): Enterprise-scale architecture recommendations for Coder deployments that support up to 3,000 users
      - [Up to 10,000 Users](https://coder.com/docs/admin/infrastructure/validated-architectures/10k-users.md): Enterprise-scale architecture recommendations for Coder deployments that support up to 10,000 users
    - [Scale Testing](https://coder.com/docs/admin/infrastructure/scale-testing.md): Ensure your deployment can handle your organization's needs
    - [Scaling Utilities](https://coder.com/docs/admin/infrastructure/scale-utility.md): Tools to help you scale your deployment
    - [Scaling best practices](https://coder.com/docs/tutorials/best-practices/scale-coder.md): How to prepare a Coder deployment for scale
  - [Users](https://coder.com/docs/admin/users.md): Learn how to manage and audit users
    - [OIDC Authentication](https://coder.com/docs/admin/users/oidc-auth.md): Configure OpenID Connect authentication with identity providers like Okta or Active Directory
      - [Google](https://coder.com/docs/admin/users/oidc-auth/google.md): Configure Google as an OIDC provider
      - [Microsoft](https://coder.com/docs/admin/users/oidc-auth/microsoft.md): Configure Microsoft Entra ID as an OIDC provider
      - [Configure OIDC refresh tokens](https://coder.com/docs/admin/users/oidc-auth/refresh-tokens.md): How to configure OIDC refresh tokens
    - [GitHub Authentication](https://coder.com/docs/admin/users/github-auth.md): Set up authentication through GitHub OAuth to enable secure user login and sign-up
    - [Password Authentication](https://coder.com/docs/admin/users/password-auth.md): Manage username/password authentication settings and user password reset workflows
    - [Headless Authentication](https://coder.com/docs/admin/users/headless-auth.md): Create and manage headless service accounts for automated systems and API integrations
    - [Groups & Roles](https://coder.com/docs/admin/users/groups-roles.md): Manage access control with user groups and role-based permissions for Coder resources
    - [IdP Sync](https://coder.com/docs/admin/users/idp-sync.md): Synchronize user groups, roles, and organizations from your identity provider to Coder
    - [Organizations](https://coder.com/docs/admin/users/organizations.md): Segment and isolate resources by creating separate organizations for different teams or projects
    - [Quotas](https://coder.com/docs/admin/users/quotas.md): Control resource usage by implementing workspace budgets and credit-based cost management
    - [Sessions & API Tokens](https://coder.com/docs/admin/users/sessions-tokens.md): Manage authentication tokens for API access and configure session duration policies
  - [Templates](https://coder.com/docs/admin/templates.md): Learn how to author and maintain Coder templates
    - [Creating Templates](https://coder.com/docs/admin/templates/creating-templates.md): Learn how to create templates with Terraform
    - [Managing Templates](https://coder.com/docs/admin/templates/managing-templates.md): Learn how to manage templates and best practices
      - [Image Management](https://coder.com/docs/admin/templates/managing-templates/image-management.md): Learn about template image management
      - [Change Management](https://coder.com/docs/admin/templates/managing-templates/change-management.md): Learn about template change management and versioning
      - [Envbuilder](https://coder.com/docs/admin/templates/managing-templates/envbuilder.md): Shift environment definition to repositories
      - [Template Dependencies](https://coder.com/docs/admin/templates/managing-templates/dependencies.md): Learn how to manage template dependencies
      - [Workspace Scheduling](https://coder.com/docs/admin/templates/managing-templates/schedule.md): Learn how to control how workspaces are started and stopped
      - [External Workspaces](https://coder.com/docs/admin/templates/managing-templates/external-workspaces.md): Learn how to manage external workspaces
    - [Extending Templates](https://coder.com/docs/admin/templates/extending-templates.md): Learn best practices in extending templates
      - [Agent Metadata](https://coder.com/docs/admin/templates/extending-templates/agent-metadata.md): Retrieve real-time stats from the workspace agent
      - [Build Parameters](https://coder.com/docs/admin/templates/extending-templates/parameters.md): Use parameters to customize workspaces at build
      - [Dynamic Parameters](https://coder.com/docs/admin/templates/extending-templates/dynamic-parameters.md): Conditional, identity-aware parameter syntax for advanced users.
      - [Prebuilt workspaces](https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces.md): Pre-provision a ready-to-deploy workspace with a defined set of parameters
      - [Icons](https://coder.com/docs/admin/templates/extending-templates/icons.md): Customize your template with built-in icons
      - [Resource Metadata](https://coder.com/docs/admin/templates/extending-templates/resource-metadata.md): Display resource state in the workspace dashboard
      - [Resource Monitoring](https://coder.com/docs/admin/templates/extending-templates/resource-monitoring.md): Monitor resources in the workspace dashboard
      - [Resource Ordering](https://coder.com/docs/admin/templates/extending-templates/resource-ordering.md): Design the UI of workspaces
      - [Resource Persistence](https://coder.com/docs/admin/templates/extending-templates/resource-persistence.md): Control resource persistence
      - [Environment Variables](https://coder.com/docs/admin/templates/extending-templates/environment-variables.md): Inject environment variables into workspaces using coder_env
      - [Terraform Variables](https://coder.com/docs/admin/templates/extending-templates/variables.md): Use variables to manage template state
      - [Terraform Modules](https://coder.com/docs/admin/templates/extending-templates/modules.md): Reuse terraform code across templates
      - [Web IDEs and Coder Apps](https://coder.com/docs/admin/templates/extending-templates/web-ides.md): Add and configure Web IDEs in your templates as coder apps
      - [Pre-install JetBrains IDEs](https://coder.com/docs/admin/templates/extending-templates/jetbrains-preinstall.md): Pre-install JetBrains IDEs in a template for faster IDE startup
      - [JetBrains IDEs in Air-Gapped Deployments](https://coder.com/docs/admin/templates/extending-templates/jetbrains-airgapped.md): Configure JetBrains IDEs for air-gapped deployments
      - [Docker in Workspaces](https://coder.com/docs/admin/templates/extending-templates/docker-in-workspaces.md): Use Docker in your workspaces
      - [Workspace Tags](https://coder.com/docs/admin/templates/extending-templates/workspace-tags.md): Control provisioning using Workspace Tags and Parameters
      - [Provider Authentication](https://coder.com/docs/admin/templates/extending-templates/provider-authentication.md): Authenticate with provider APIs to provision workspaces
      - [Dev Containers](https://coder.com/docs/admin/templates/extending-templates/devcontainers.md): Extend templates with containerized dev environments
      - [Improving Agent Resiliency](https://coder.com/docs/admin/templates/extending-templates/process-priority.md): Manage agent child process CPU and OOM priority
      - [Process Logging](https://coder.com/docs/admin/templates/extending-templates/process-logging.md): Log workspace processes
      - [Startup Dependencies](https://coder.com/docs/admin/templates/startup-coordination.md): Coordinate workspace startup with dependency management
        - [Usage](https://coder.com/docs/admin/templates/startup-coordination/usage.md): How to use startup coordination
        - [Troubleshooting](https://coder.com/docs/admin/templates/startup-coordination/troubleshooting.md): Troubleshoot startup coordination
        - [Examples](https://coder.com/docs/admin/templates/startup-coordination/example.md): Examples of startup coordination
    - [Open in Coder](https://coder.com/docs/admin/templates/open-in-coder.md): Open workspaces in Coder
    - [Permissions & Policies](https://coder.com/docs/admin/templates/template-permissions.md): Learn how to create templates with Terraform
    - [Troubleshooting Templates](https://coder.com/docs/admin/templates/troubleshooting.md): Learn how to troubleshoot template issues
  - [External Provisioners](https://coder.com/docs/admin/provisioners.md): Learn how to run external provisioners with Coder
    - [Manage Provisioner Jobs](https://coder.com/docs/admin/provisioners/manage-provisioner-jobs.md): Learn how to run external provisioners with Coder
  - [External Authentication](https://coder.com/docs/admin/external-auth.md): Learn how to configure external authentication
  - [Integrations](https://coder.com/docs/admin/integrations.md): Use integrations to extend Coder
    - [Prometheus](https://coder.com/docs/admin/integrations/prometheus.md): Collect deployment metrics with Prometheus
    - [Kubernetes Logging](https://coder.com/docs/admin/integrations/kubernetes-logs.md): Stream K8s event logs on workspace startup
    - [Additional Kubernetes Clusters](https://coder.com/docs/admin/integrations/multiple-kube-clusters.md): Deploy workspaces on additional Kubernetes clusters
    - [JFrog Artifactory](https://coder.com/docs/admin/integrations/jfrog-artifactory.md): Integrate Coder with JFrog Artifactory
    - [Island Secure Browser](https://coder.com/docs/admin/integrations/island.md): Integrate Coder with Island's Secure Browser
    - [DX PlatformX](https://coder.com/docs/admin/integrations/platformx.md): Integrate Coder with DX PlatformX
    - [DX Data Cloud](https://coder.com/docs/admin/integrations/dx-data-cloud.md): Tag Coder Users with DX Data Cloud
    - [Hashicorp Vault](https://coder.com/docs/admin/integrations/vault.md): Integrate Coder with Hashicorp Vault
    - [OAuth2 Provider](https://coder.com/docs/admin/integrations/oauth2-provider.md): Use Coder as an OAuth2 provider
    - [Dev Containers](https://coder.com/docs/admin/integrations/devcontainers.md): Configure dev container support using Docker or Envbuilder
      - [Dev Containers Integration](https://coder.com/docs/admin/integrations/devcontainers/integration.md): Configure native dev containers with Docker
      - [Envbuilder](https://coder.com/docs/admin/integrations/devcontainers/envbuilder.md): Build dev containers without Docker
        - [Add an Envbuilder template](https://coder.com/docs/admin/integrations/devcontainers/envbuilder/add-envbuilder.md): How to add an Envbuilder template
        - [Security and caching](https://coder.com/docs/admin/integrations/devcontainers/envbuilder/envbuilder-security-caching.md): Configure authentication and caching
        - [Releases and known issues](https://coder.com/docs/admin/integrations/devcontainers/envbuilder/envbuilder-releases-known-issues.md): Release channels and known issues
  - [Networking](https://coder.com/docs/admin/networking.md): Understand Coder's networking layer
    - [Port Forwarding](https://coder.com/docs/admin/networking/port-forwarding.md): Learn how to forward ports in Coder
    - [STUN and NAT](https://coder.com/docs/admin/networking/stun.md): Learn how to forward ports in Coder
    - [Workspace Proxies](https://coder.com/docs/admin/networking/workspace-proxies.md): Run geo distributed workspace proxies
    - [High Availability](https://coder.com/docs/admin/networking/high-availability.md): Learn how to configure Coder for High Availability
    - [Wildcard Access URL](https://coder.com/docs/admin/networking/wildcard-access-url.md): Learn about wildcard access URL in Coder deployments
    - [Troubleshooting](https://coder.com/docs/admin/networking/troubleshooting.md): Troubleshoot networking issues in Coder
  - [Monitoring](https://coder.com/docs/admin/monitoring.md): Configure security policy and audit your deployment
    - [Logs](https://coder.com/docs/admin/monitoring/logs.md): Learn about Coder's logs
    - [Metrics](https://coder.com/docs/admin/monitoring/metrics.md): Learn about Coder's logs
    - [Health Check](https://coder.com/docs/admin/monitoring/health-check.md): Learn about Coder's automated health checks
    - [Connection Logs](https://coder.com/docs/admin/monitoring/connection-logs.md): Monitor connections to workspaces
    - [Notifications](https://coder.com/docs/admin/monitoring/notifications.md): Configure notifications for your deployment
      - [Slack Notifications](https://coder.com/docs/admin/monitoring/notifications/slack.md): Learn how to setup Slack notifications
      - [Microsoft Teams Notifications](https://coder.com/docs/admin/monitoring/notifications/teams.md): Learn how to setup Microsoft Teams notifications
  - [Security](https://coder.com/docs/admin/security.md): Configure security policy and audit your deployment
    - [Audit Logs](https://coder.com/docs/admin/security/audit-logs.md): Audit actions taken inside Coder
    - [Secrets](https://coder.com/docs/admin/security/secrets.md): Use sensitive variables in your workspaces
    - [Database Encryption](https://coder.com/docs/admin/security/database-encryption.md): Encrypt the database to prevent unauthorized access
  - [Licensing](https://coder.com/docs/admin/licensing.md): Configure licensing for your deployment
- [Run AI Coding Agents in Coder](https://coder.com/docs/ai-coder.md): Learn how to run and integrate agentic AI coding agents like GPT-Code, OpenDevin, or SWE-Agent in Coder workspaces to boost developer productivity.
  - [Best Practices](https://coder.com/docs/ai-coder/best-practices.md): Best Practices running Coding Agents
  - [In the IDE](https://coder.com/docs/ai-coder/ide-agents.md): Run IDE agents with Coder
  - [Coder Agents](https://coder.com/docs/ai-coder/agents.md): Self-hosted agent by Coder
    - [Getting Started](https://coder.com/docs/ai-coder/agents/getting-started.md): Enable Coder Agents, prepare your deployment, and run your first Coder Agent
    - [Architecture](https://coder.com/docs/ai-coder/agents/architecture.md): How the agent in the control plane communicates with workspaces
    - [Models](https://coder.com/docs/ai-coder/agents/models.md): Configure LLM providers and models for Coder Agents
    - [Platform Controls](https://coder.com/docs/ai-coder/agents/platform-controls.md): How platform teams control agent behavior, models, and policies
      - [Template Optimization](https://coder.com/docs/ai-coder/agents/platform-controls/template-optimization.md): Best practices for creating templates that are discoverable and useful to Coder Agents
      - [MCP Servers](https://coder.com/docs/ai-coder/agents/platform-controls/mcp-servers.md): Configure external MCP servers that provide additional tools for agent chat sessions
      - [Spend Management](https://coder.com/docs/ai-coder/agents/platform-controls/usage-insights.md): Spend limits and cost tracking for Coder Agents
      - [Git Providers](https://coder.com/docs/ai-coder/agents/platform-controls/git-providers.md): Git provider configuration for the in-chat diff viewer
      - [Data Retention](https://coder.com/docs/ai-coder/agents/platform-controls/chat-retention.md): Automatic cleanup of old conversation data
      - [Debug Data Retention](https://coder.com/docs/ai-coder/agents/platform-controls/chat-debug-retention.md): Automatic cleanup of old chat debug data
      - [Auto-Archive](https://coder.com/docs/ai-coder/agents/platform-controls/chat-auto-archive.md): Automatic archiving of inactive conversations
      - [Experiments](https://coder.com/docs/ai-coder/agents/platform-controls/experiments.md): Experimental Coder Agents features admins can opt in to: virtual desktop, advisor, and chat debug logging
    - [Extending Agents](https://coder.com/docs/ai-coder/agents/extending-agents.md): Add custom skills and MCP tools to agent workspaces
    - [Tasks to Chats API Migration](https://coder.com/docs/ai-coder/agents/tasks-to-chats-migration.md): Guide for migrating from the Tasks API to the Chats API
  - [AI Governance Add-On](https://coder.com/docs/ai-coder/ai-governance.md): Features around managing agents at scale
    - [Agent Firewall](https://coder.com/docs/ai-coder/agent-firewall.md): Understanding Agent Firewall in Coder Tasks
      - [NS Jail](https://coder.com/docs/ai-coder/agent-firewall/nsjail.md): Documentation for Namespace Jail
        - [NS Jail on Docker](https://coder.com/docs/ai-coder/agent-firewall/nsjail/docker.md): Runtime and permission requirements for running NS Jail on Docker
        - [NS Jail on Kubernetes](https://coder.com/docs/ai-coder/agent-firewall/nsjail/k8s.md): Runtime and permission requirements for running NS Jail on Kubernetes
        - [NS Jail on ECS](https://coder.com/docs/ai-coder/agent-firewall/nsjail/ecs.md): Runtime and permission requirements for running NS Jail on ECS
      - [LandJail](https://coder.com/docs/ai-coder/agent-firewall/landjail.md): Documentation for LandJail
      - [Rules Engine](https://coder.com/docs/ai-coder/agent-firewall/rules-engine.md): Documentation for the Agent Firewall rules engine
      - [Version Compatibility](https://coder.com/docs/ai-coder/agent-firewall/version.md): Version requirements and compatibility information
    - [AI Gateway](https://coder.com/docs/ai-coder/ai-gateway.md): AI Gateway for Enterprise Governance & Observability
      - [Setup](https://coder.com/docs/ai-coder/ai-gateway/setup.md): How to set up and configure AI Gateway
      - [Client Configuration](https://coder.com/docs/ai-coder/ai-gateway/clients.md): How to configure your AI coding tools to use AI Gateway
        - [Coder Agents](https://coder.com/docs/ai-coder/ai-gateway/clients/coder-agents.md): Route Coder Agents traffic through AI Gateway
        - [Claude Code](https://coder.com/docs/ai-coder/ai-gateway/clients/claude-code.md): Configure Claude Code to use AI Gateway
        - [Codex](https://coder.com/docs/ai-coder/ai-gateway/clients/codex.md): Configure Codex to use AI Gateway
        - [Mux](https://coder.com/docs/ai-coder/ai-gateway/clients/mux.md): Configure Mux to use AI Gateway
        - [OpenCode](https://coder.com/docs/ai-coder/ai-gateway/clients/opencode.md): Configure OpenCode to use AI Gateway
        - [Factory](https://coder.com/docs/ai-coder/ai-gateway/clients/factory.md): Configure Factory to use AI Gateway
        - [Cline](https://coder.com/docs/ai-coder/ai-gateway/clients/cline.md): Configure Cline to use AI Gateway
        - [Kilo Code](https://coder.com/docs/ai-coder/ai-gateway/clients/kilo-code.md): Configure Kilo Code to use AI Gateway
        - [Roo Code](https://coder.com/docs/ai-coder/ai-gateway/clients/roo-code.md): Configure Roo Code to use AI Gateway
        - [VS Code](https://coder.com/docs/ai-coder/ai-gateway/clients/vscode.md): Configure VS Code to use AI Gateway
        - [JetBrains](https://coder.com/docs/ai-coder/ai-gateway/clients/jetbrains.md): Configure JetBrains IDEs to use AI Gateway
        - [Zed](https://coder.com/docs/ai-coder/ai-gateway/clients/zed.md): Configure Zed to use AI Gateway
        - [GitHub Copilot](https://coder.com/docs/ai-coder/ai-gateway/clients/copilot.md): Configure GitHub Copilot to use AI Gateway via AI Gateway Proxy
      - [MCP Tools Injection](https://coder.com/docs/ai-coder/ai-gateway/mcp.md): How to configure MCP servers for tools injection through AI Gateway
      - [AI Gateway Proxy](https://coder.com/docs/ai-coder/ai-gateway/ai-gateway-proxy.md): Proxy for AI coding tools without base URL override support
        - [Setup](https://coder.com/docs/ai-coder/ai-gateway/ai-gateway-proxy/setup.md): How to set up and configure AI Gateway Proxy
      - [Auditing AI Sessions](https://coder.com/docs/ai-coder/ai-gateway/audit.md): How to audit AI sessions
      - [Monitoring](https://coder.com/docs/ai-coder/ai-gateway/monitoring.md): How to monitor AI Gateway
      - [Reference](https://coder.com/docs/ai-coder/ai-gateway/reference.md): Technical reference for AI Gateway
    - [Usage Data Reporting](https://coder.com/docs/ai-coder/usage-data-reporting.md): Configure AI usage data reporting
  - [MCP Server](https://coder.com/docs/ai-coder/mcp-server.md): Connect AI coding agents to Coder using the MCP server
  - [Coder Tasks](https://coder.com/docs/ai-coder/tasks.md): Run Coding Agents on your Own Infrastructure
    - [Understanding Coder Tasks](https://coder.com/docs/ai-coder/tasks-core-principles.md): Core principles and concepts behind Coder Tasks
    - [Custom Agents](https://coder.com/docs/ai-coder/custom-agents.md): Run custom agents with Coder Tasks
    - [Task Lifecycle](https://coder.com/docs/ai-coder/tasks-lifecycle.md): How tasks pause and resume, and what gets preserved
    - [Agent Compatibility](https://coder.com/docs/ai-coder/agent-compatibility.md): Which AI agents support session persistence across workspace restarts
    - [Tasks Migration Guide](https://coder.com/docs/ai-coder/tasks-migration.md): Changes to Coder Tasks made in v2.28
    - [Security & Agent Firewall](https://coder.com/docs/ai-coder/security.md): Learn about security and the Agent Firewall when running AI coding agents in Coder
    - [Create a GitHub to Coder Tasks Workflow](https://coder.com/docs/ai-coder/github-to-tasks.md): How to setup Coder Tasks to run in GitHub
    - [Tasks to Chats API Migration](https://coder.com/docs/ai-coder/agents/tasks-to-chats-migration.md): Guide for migrating from the Tasks API to the Chats API
- [Tutorials](https://coder.com/docs/tutorials.md): Coder knowledgebase for administrating your deployment
  - [Quickstart](https://coder.com/docs/tutorials/quickstart.md): Learn how to install and run Coder quickly
  - [Write a Template from Scratch](https://coder.com/docs/tutorials/template-from-scratch.md): Learn how to author Coder templates
  - [Using an External Database](https://coder.com/docs/tutorials/external-database.md): Use Coder with an external database
  - [Image Management](https://coder.com/docs/admin/templates/managing-templates/image-management.md): Learn about image management with Coder
  - [Configuring Okta](https://coder.com/docs/tutorials/configuring-okta.md): Custom claims/scopes with Okta for group/role sync
  - [Persistent Shared Workspaces](https://coder.com/docs/tutorials/persistent-shared-workspaces.md): Set up long-lived shared workspaces with service accounts and workspace sharing
  - [Google to AWS Federation](https://coder.com/docs/tutorials/gcp-to-aws.md): Federating a Google Cloud service account to AWS
  - [JFrog Artifactory Integration](https://coder.com/docs/admin/integrations/jfrog-artifactory.md): Integrate Coder with JFrog Artifactory
  - [Mirror Coder Registry with Artifactory](https://coder.com/docs/install/registry-mirror-artifactory.md): Use JFrog Artifactory to mirror the Coder Registry for air-gapped deployments
  - [Istio Integration](https://coder.com/docs/admin/integrations/istio.md): Integrate Coder with Istio
  - [Island Secure Browser Integration](https://coder.com/docs/admin/integrations/island.md): Integrate Coder with Island's Secure Browser
  - [Template ImagePullSecrets](https://coder.com/docs/tutorials/image-pull-secret.md): Creating ImagePullSecrets for private registries
  - [Postgres SSL](https://coder.com/docs/tutorials/postgres-ssl.md): Configure Coder to connect to Postgres over SSL
  - [Azure Federation](https://coder.com/docs/tutorials/azure-federation.md): Federating Coder to Azure
  - [Deploy Coder on Azure with an Application Gateway](https://coder.com/docs/install/kubernetes/kubernetes-azure-app-gateway.md): Deploy Coder on Azure with an Application Gateway
  - [Cloning Git Repositories](https://coder.com/docs/tutorials/cloning-git-repositories.md): Learn how to clone Git repositories in Coder
  - [Test Templates Through CI/CD](https://coder.com/docs/tutorials/testing-templates.md): Learn how to test and publish Coder templates in a CI/CD pipeline
  - [Use Apache as a Reverse Proxy](https://coder.com/docs/tutorials/reverse-proxy-apache.md): Learn how to use Apache as a reverse proxy
  - [Use Caddy as a Reverse Proxy](https://coder.com/docs/tutorials/reverse-proxy-caddy.md): Learn how to use Caddy as a reverse proxy
  - [Use NGINX as a Reverse Proxy](https://coder.com/docs/tutorials/reverse-proxy-nginx.md): Learn how to use NGINX as a reverse proxy
  - [Pre-install JetBrains IDEs in Workspaces](https://coder.com/docs/admin/templates/extending-templates/jetbrains-preinstall.md): Pre-install JetBrains IDEs in workspaces
  - [Use JetBrains IDEs in Air-Gapped Deployments](https://coder.com/docs/admin/templates/extending-templates/jetbrains-airgapped.md): Configure JetBrains IDEs for air-gapped deployments
  - [FAQs](https://coder.com/docs/tutorials/faqs.md): Miscellaneous FAQs from our community
  - [Best practices](https://coder.com/docs/tutorials/best-practices.md): Guides to help you make the most of your Coder experience
    - [Organizations - best practices](https://coder.com/docs/tutorials/best-practices/organizations.md): How to make the best use of Coder Organizations
    - [Scale Coder](https://coder.com/docs/tutorials/best-practices/scale-coder.md): How to prepare a Coder deployment for scale
    - [Security - best practices](https://coder.com/docs/tutorials/best-practices/security-best-practices.md): Make your Coder deployment more secure
    - [Speed up your workspaces](https://coder.com/docs/tutorials/best-practices/speed-up-templates.md): Speed up your Coder templates and workspaces
- [Reference](https://coder.com/docs/reference.md): Reference
  - [REST API](https://coder.com/docs/reference/api.md): Learn how to use Coderd API
    - [General](https://coder.com/docs/reference/api/general.md)
    - [AI Bridge](https://coder.com/docs/reference/api/aibridge.md)
    - [Agents](https://coder.com/docs/reference/api/agents.md)
    - [Applications](https://coder.com/docs/reference/api/applications.md)
    - [Audit](https://coder.com/docs/reference/api/audit.md)
    - [Authentication](https://coder.com/docs/reference/api/authentication.md)
    - [Authorization](https://coder.com/docs/reference/api/authorization.md)
    - [Builds](https://coder.com/docs/reference/api/builds.md)
    - [Chats](https://coder.com/docs/reference/api/chats.md)
    - [Debug](https://coder.com/docs/reference/api/debug.md)
    - [Enterprise](https://coder.com/docs/reference/api/enterprise.md)
    - [Files](https://coder.com/docs/reference/api/files.md)
    - [Git](https://coder.com/docs/reference/api/git.md)
    - [InitScript](https://coder.com/docs/reference/api/initscript.md)
    - [Insights](https://coder.com/docs/reference/api/insights.md)
    - [Members](https://coder.com/docs/reference/api/members.md)
    - [Notifications](https://coder.com/docs/reference/api/notifications.md)
    - [Organizations](https://coder.com/docs/reference/api/organizations.md)
    - [PortSharing](https://coder.com/docs/reference/api/portsharing.md)
    - [Prebuilds](https://coder.com/docs/reference/api/prebuilds.md)
    - [Provisioning](https://coder.com/docs/reference/api/provisioning.md)
    - [Schemas](https://coder.com/docs/reference/api/schemas.md)
    - [Secrets](https://coder.com/docs/reference/api/secrets.md)
    - [Tasks](https://coder.com/docs/reference/api/tasks.md)
    - [Templates](https://coder.com/docs/reference/api/templates.md)
    - [Users](https://coder.com/docs/reference/api/users.md)
    - [WorkspaceProxies](https://coder.com/docs/reference/api/workspaceproxies.md)
    - [Workspaces](https://coder.com/docs/reference/api/workspaces.md)
  - [Command Line](https://coder.com/docs/reference/cli.md): Learn how to use Coder CLI
    - [aibridge](https://coder.com/docs/reference/cli/aibridge.md): Manage AI Bridge.
    - [aibridge interceptions](https://coder.com/docs/reference/cli/aibridge_interceptions.md): Manage AI Bridge interceptions.
    - [aibridge interceptions list](https://coder.com/docs/reference/cli/aibridge_interceptions_list.md): List AI Bridge interceptions as JSON.
    - [autoupdate](https://coder.com/docs/reference/cli/autoupdate.md): Toggle auto-update policy for a workspace
    - [boundary](https://coder.com/docs/reference/cli/boundary.md): Network isolation tool for monitoring and restricting HTTP/HTTPS requests
    - [coder](https://coder.com/docs/reference/cli.md)
    - [completion](https://coder.com/docs/reference/cli/completion.md): Install or update shell completion scripts for the detected or chosen shell.
    - [config-ssh](https://coder.com/docs/reference/cli/config-ssh.md): Add an SSH Host entry for your workspaces "ssh workspace.coder"
    - [create](https://coder.com/docs/reference/cli/create.md): Create a workspace
    - [delete](https://coder.com/docs/reference/cli/delete.md): Delete a workspace
    - [dotfiles](https://coder.com/docs/reference/cli/dotfiles.md): Personalize your workspace by applying a canonical dotfiles repository
    - [external-auth](https://coder.com/docs/reference/cli/external-auth.md): Manage external authentication
    - [external-auth access-token](https://coder.com/docs/reference/cli/external-auth_access-token.md): Print auth for an external provider
    - [external-workspaces](https://coder.com/docs/reference/cli/external-workspaces.md): Create or manage external workspaces
    - [external-workspaces agent-instructions](https://coder.com/docs/reference/cli/external-workspaces_agent-instructions.md): Get the instructions for an external agent
    - [external-workspaces create](https://coder.com/docs/reference/cli/external-workspaces_create.md): Create a new external workspace
    - [external-workspaces list](https://coder.com/docs/reference/cli/external-workspaces_list.md): List external workspaces
    - [favorite](https://coder.com/docs/reference/cli/favorite.md): Add a workspace to your favorites
    - [features](https://coder.com/docs/reference/cli/features.md): List Enterprise features
    - [features list](https://coder.com/docs/reference/cli/features_list.md)
    - [groups](https://coder.com/docs/reference/cli/groups.md): Manage groups
    - [groups create](https://coder.com/docs/reference/cli/groups_create.md): Create a user group
    - [groups delete](https://coder.com/docs/reference/cli/groups_delete.md): Delete a user group
    - [groups edit](https://coder.com/docs/reference/cli/groups_edit.md): Edit a user group
    - [groups list](https://coder.com/docs/reference/cli/groups_list.md): List user groups
    - [licenses](https://coder.com/docs/reference/cli/licenses.md): Add, delete, and list licenses
    - [licenses add](https://coder.com/docs/reference/cli/licenses_add.md): Add license to Coder deployment
    - [licenses delete](https://coder.com/docs/reference/cli/licenses_delete.md): Delete license by ID
    - [licenses list](https://coder.com/docs/reference/cli/licenses_list.md): List licenses (including expired)
    - [list](https://coder.com/docs/reference/cli/list.md): List workspaces
    - [login](https://coder.com/docs/reference/cli/login.md): Authenticate with Coder deployment
    - [login token](https://coder.com/docs/reference/cli/login_token.md): Print the current session token
    - [logout](https://coder.com/docs/reference/cli/logout.md): Unauthenticate your local session
    - [logs](https://coder.com/docs/reference/cli/logs.md): View logs for a workspace
    - [netcheck](https://coder.com/docs/reference/cli/netcheck.md): Print network debug information for DERP and STUN
    - [notifications](https://coder.com/docs/reference/cli/notifications.md): Manage Coder notifications
    - [notifications custom](https://coder.com/docs/reference/cli/notifications_custom.md): Send a custom notification
    - [notifications pause](https://coder.com/docs/reference/cli/notifications_pause.md): Pause notifications
    - [notifications resume](https://coder.com/docs/reference/cli/notifications_resume.md): Resume notifications
    - [notifications test](https://coder.com/docs/reference/cli/notifications_test.md): Send a test notification
    - [open](https://coder.com/docs/reference/cli/open.md): Open a workspace
    - [open app](https://coder.com/docs/reference/cli/open_app.md): Open a workspace application.
    - [open vscode](https://coder.com/docs/reference/cli/open_vscode.md): Open a workspace in VS Code Desktop
    - [organizations](https://coder.com/docs/reference/cli/organizations.md): Organization related commands
    - [organizations create](https://coder.com/docs/reference/cli/organizations_create.md): Create a new organization.
    - [organizations delete](https://coder.com/docs/reference/cli/organizations_delete.md): Delete an organization
    - [organizations list](https://coder.com/docs/reference/cli/organizations_list.md): List all organizations
    - [organizations members](https://coder.com/docs/reference/cli/organizations_members.md): Manage organization members
    - [organizations members add](https://coder.com/docs/reference/cli/organizations_members_add.md): Add a new member to the current organization
    - [organizations members edit-roles](https://coder.com/docs/reference/cli/organizations_members_edit-roles.md): Edit organization member's roles
    - [organizations members list](https://coder.com/docs/reference/cli/organizations_members_list.md): List all organization members
    - [organizations members remove](https://coder.com/docs/reference/cli/organizations_members_remove.md): Remove a new member to the current organization
    - [organizations roles](https://coder.com/docs/reference/cli/organizations_roles.md): Manage organization roles.
    - [organizations roles create](https://coder.com/docs/reference/cli/organizations_roles_create.md): Create a new organization custom role
    - [organizations roles show](https://coder.com/docs/reference/cli/organizations_roles_show.md): Show role(s)
    - [organizations roles update](https://coder.com/docs/reference/cli/organizations_roles_update.md): Update an organization custom role
    - [organizations settings](https://coder.com/docs/reference/cli/organizations_settings.md): Manage organization settings.
    - [organizations settings set](https://coder.com/docs/reference/cli/organizations_settings_set.md): Update specified organization setting.
    - [organizations settings set group-sync](https://coder.com/docs/reference/cli/organizations_settings_set_group-sync.md): Group sync settings to sync groups from an IdP.
    - [organizations settings set organization-sync](https://coder.com/docs/reference/cli/organizations_settings_set_organization-sync.md): Organization sync settings to sync organization memberships from an IdP.
    - [organizations settings set role-sync](https://coder.com/docs/reference/cli/organizations_settings_set_role-sync.md): Role sync settings to sync organization roles from an IdP.
    - [organizations settings set workspace-sharing](https://coder.com/docs/reference/cli/organizations_settings_set_workspace-sharing.md): Workspace sharing settings for the organization.
    - [organizations settings show](https://coder.com/docs/reference/cli/organizations_settings_show.md): Outputs specified organization setting.
    - [organizations settings show group-sync](https://coder.com/docs/reference/cli/organizations_settings_show_group-sync.md): Group sync settings to sync groups from an IdP.
    - [organizations settings show organization-sync](https://coder.com/docs/reference/cli/organizations_settings_show_organization-sync.md): Organization sync settings to sync organization memberships from an IdP.
    - [organizations settings show role-sync](https://coder.com/docs/reference/cli/organizations_settings_show_role-sync.md): Role sync settings to sync organization roles from an IdP.
    - [organizations settings show workspace-sharing](https://coder.com/docs/reference/cli/organizations_settings_show_workspace-sharing.md): Workspace sharing settings for the organization.
    - [organizations show](https://coder.com/docs/reference/cli/organizations_show.md): Show the organization. Using "selected" will show the selected organization from the "--org" flag. Using "me" will show all organizations you are a member of.
    - [ping](https://coder.com/docs/reference/cli/ping.md): Ping a workspace
    - [port-forward](https://coder.com/docs/reference/cli/port-forward.md): Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".
    - [prebuilds](https://coder.com/docs/reference/cli/prebuilds.md): Manage Coder prebuilds
    - [prebuilds pause](https://coder.com/docs/reference/cli/prebuilds_pause.md): Pause prebuilds
    - [prebuilds resume](https://coder.com/docs/reference/cli/prebuilds_resume.md): Resume prebuilds
    - [provisioner](https://coder.com/docs/reference/cli/provisioner.md): View and manage provisioner daemons and jobs
    - [provisioner jobs](https://coder.com/docs/reference/cli/provisioner_jobs.md): View and manage provisioner jobs
    - [provisioner jobs cancel](https://coder.com/docs/reference/cli/provisioner_jobs_cancel.md): Cancel a provisioner job
    - [provisioner jobs list](https://coder.com/docs/reference/cli/provisioner_jobs_list.md): List provisioner jobs
    - [provisioner keys](https://coder.com/docs/reference/cli/provisioner_keys.md): Manage provisioner keys
    - [provisioner keys create](https://coder.com/docs/reference/cli/provisioner_keys_create.md): Create a new provisioner key
    - [provisioner keys delete](https://coder.com/docs/reference/cli/provisioner_keys_delete.md): Delete a provisioner key
    - [provisioner keys list](https://coder.com/docs/reference/cli/provisioner_keys_list.md): List provisioner keys in an organization
    - [provisioner list](https://coder.com/docs/reference/cli/provisioner_list.md): List provisioner daemons in an organization
    - [provisioner start](https://coder.com/docs/reference/cli/provisioner_start.md): Run a provisioner daemon
    - [publickey](https://coder.com/docs/reference/cli/publickey.md): Output your Coder public key used for Git operations
    - [rename](https://coder.com/docs/reference/cli/rename.md): Rename a workspace
    - [reset-password](https://coder.com/docs/reference/cli/reset-password.md): Directly connect to the database to reset a user's password
    - [restart](https://coder.com/docs/reference/cli/restart.md): Restart a workspace
    - [schedule](https://coder.com/docs/reference/cli/schedule.md): Schedule automated start and stop times for workspaces
    - [schedule extend](https://coder.com/docs/reference/cli/schedule_extend.md): Extend the stop time of a currently running workspace instance.
    - [schedule show](https://coder.com/docs/reference/cli/schedule_show.md): Show workspace schedules
    - [schedule start](https://coder.com/docs/reference/cli/schedule_start.md): Edit workspace start schedule
    - [schedule stop](https://coder.com/docs/reference/cli/schedule_stop.md): Edit workspace stop schedule
    - [secret](https://coder.com/docs/reference/cli/secret.md): Manage secrets
    - [secret create](https://coder.com/docs/reference/cli/secret_create.md): Create a secret
    - [secret update](https://coder.com/docs/reference/cli/secret_update.md): Update a secret
    - [secret list](https://coder.com/docs/reference/cli/secret_list.md): List secrets, or show one by name
    - [secret delete](https://coder.com/docs/reference/cli/secret_delete.md): Delete a secret
    - [server](https://coder.com/docs/reference/cli/server.md): Start a Coder server
    - [server create-admin-user](https://coder.com/docs/reference/cli/server_create-admin-user.md): Create a new admin user with the given username, email and password and adds it to every organization.
    - [server dbcrypt](https://coder.com/docs/reference/cli/server_dbcrypt.md): Manage database encryption.
    - [server dbcrypt decrypt](https://coder.com/docs/reference/cli/server_dbcrypt_decrypt.md): Decrypt a previously encrypted database.
    - [server dbcrypt delete](https://coder.com/docs/reference/cli/server_dbcrypt_delete.md): Delete all encrypted data from the database. THIS IS A DESTRUCTIVE OPERATION.
    - [server dbcrypt rotate](https://coder.com/docs/reference/cli/server_dbcrypt_rotate.md): Rotate database encryption keys.
    - [server postgres-builtin-serve](https://coder.com/docs/reference/cli/server_postgres-builtin-serve.md): Run the built-in PostgreSQL deployment.
    - [server postgres-builtin-url](https://coder.com/docs/reference/cli/server_postgres-builtin-url.md): Output the connection URL for the built-in PostgreSQL deployment.
    - [show](https://coder.com/docs/reference/cli/show.md): Display details of a workspace's resources and agents
    - [speedtest](https://coder.com/docs/reference/cli/speedtest.md): Run upload and download tests from your machine to a workspace
    - [ssh](https://coder.com/docs/reference/cli/ssh.md): Start a shell into a workspace or run a command
    - [start](https://coder.com/docs/reference/cli/start.md): Start a workspace
    - [stat](https://coder.com/docs/reference/cli/stat.md): Show resource usage for the current workspace.
    - [stat cpu](https://coder.com/docs/reference/cli/stat_cpu.md): Show CPU usage, in cores.
    - [stat disk](https://coder.com/docs/reference/cli/stat_disk.md): Show disk usage, in gigabytes.
    - [stat mem](https://coder.com/docs/reference/cli/stat_mem.md): Show memory usage, in gigabytes.
    - [state](https://coder.com/docs/reference/cli/state.md): Manually manage Terraform state to fix broken workspaces
    - [state pull](https://coder.com/docs/reference/cli/state_pull.md): Pull a Terraform state file from a workspace.
    - [state push](https://coder.com/docs/reference/cli/state_push.md): Push a Terraform state file to a workspace.
    - [stop](https://coder.com/docs/reference/cli/stop.md): Stop a workspace
    - [support](https://coder.com/docs/reference/cli/support.md): Commands for troubleshooting issues with a Coder deployment.
    - [support bundle](https://coder.com/docs/reference/cli/support_bundle.md): Generate a support bundle to troubleshoot issues connecting to a workspace.
    - [task](https://coder.com/docs/reference/cli/task.md): Manage tasks
    - [task create](https://coder.com/docs/reference/cli/task_create.md): Create a task
    - [task delete](https://coder.com/docs/reference/cli/task_delete.md): Delete tasks
    - [task list](https://coder.com/docs/reference/cli/task_list.md): List tasks
    - [task logs](https://coder.com/docs/reference/cli/task_logs.md): Show a task's logs
    - [task pause](https://coder.com/docs/reference/cli/task_pause.md): Pause a task
    - [task resume](https://coder.com/docs/reference/cli/task_resume.md): Resume a task
    - [task send](https://coder.com/docs/reference/cli/task_send.md): Send input to a task
    - [task status](https://coder.com/docs/reference/cli/task_status.md): Show the status of a task.
    - [templates](https://coder.com/docs/reference/cli/templates.md): Manage templates
    - [templates archive](https://coder.com/docs/reference/cli/templates_archive.md): Archive unused or failed template versions from a given template(s)
    - [templates create](https://coder.com/docs/reference/cli/templates_create.md): DEPRECATED: Create a template from the current directory or as specified by flag
    - [templates delete](https://coder.com/docs/reference/cli/templates_delete.md): Delete templates
    - [templates edit](https://coder.com/docs/reference/cli/templates_edit.md): Edit the metadata of a template by name.
    - [templates init](https://coder.com/docs/reference/cli/templates_init.md): Get started with a templated template.
    - [templates list](https://coder.com/docs/reference/cli/templates_list.md): List all the templates available for the organization
    - [templates presets](https://coder.com/docs/reference/cli/templates_presets.md): Manage presets of the specified template
    - [templates presets list](https://coder.com/docs/reference/cli/templates_presets_list.md): List all presets of the specified template. Defaults to the active template version.
    - [templates pull](https://coder.com/docs/reference/cli/templates_pull.md): Download the active, latest, or specified version of a template to a path.
    - [templates push](https://coder.com/docs/reference/cli/templates_push.md): Create or update a template from the current directory or as specified by flag
    - [templates versions](https://coder.com/docs/reference/cli/templates_versions.md): Manage different versions of the specified template
    - [templates versions archive](https://coder.com/docs/reference/cli/templates_versions_archive.md): Archive a template version(s).
    - [templates versions list](https://coder.com/docs/reference/cli/templates_versions_list.md): List all the versions of the specified template
    - [templates versions promote](https://coder.com/docs/reference/cli/templates_versions_promote.md): Promote a template version to active.
    - [templates versions unarchive](https://coder.com/docs/reference/cli/templates_versions_unarchive.md): Unarchive a template version(s).
    - [tokens](https://coder.com/docs/reference/cli/tokens.md): Manage personal access tokens
    - [tokens create](https://coder.com/docs/reference/cli/tokens_create.md): Create a token
    - [tokens list](https://coder.com/docs/reference/cli/tokens_list.md): List tokens
    - [tokens remove](https://coder.com/docs/reference/cli/tokens_remove.md): Expire or delete a token
    - [tokens view](https://coder.com/docs/reference/cli/tokens_view.md): Display detailed information about a token
    - [unfavorite](https://coder.com/docs/reference/cli/unfavorite.md): Remove a workspace from your favorites
    - [update](https://coder.com/docs/reference/cli/update.md): Will update and start a given workspace if it is out of date. If the workspace is already running, it will be stopped first.
    - [users](https://coder.com/docs/reference/cli/users.md): Manage users
    - [users activate](https://coder.com/docs/reference/cli/users_activate.md): Update a user's status to 'active'. Active users can fully interact with the platform
    - [users create](https://coder.com/docs/reference/cli/users_create.md): Create a new user.
    - [users delete](https://coder.com/docs/reference/cli/users_delete.md): Delete a user by username or user_id.
    - [users edit-roles](https://coder.com/docs/reference/cli/users_edit-roles.md): Edit a user's roles by username or id
    - [users list](https://coder.com/docs/reference/cli/users_list.md): Prints the list of users.
    - [users show](https://coder.com/docs/reference/cli/users_show.md): Show a single user. Use 'me' to indicate the currently authenticated user.
    - [users suspend](https://coder.com/docs/reference/cli/users_suspend.md): Update a user's status to 'suspended'. A suspended user cannot log into the platform
    - [version](https://coder.com/docs/reference/cli/version.md): Show coder version
    - [whoami](https://coder.com/docs/reference/cli/whoami.md): Fetch authenticated user info for Coder deployment
  - [Agent API](https://coder.com/docs/reference/agent-api.md): Learn how to use Coder Agent API
    - [Debug](https://coder.com/docs/reference/agent-api/debug.md)
    - [Schemas](https://coder.com/docs/reference/agent-api/schemas.md)

---

# About

Source: https://coder.com/docs

# About

<!-- Warning for docs contributors: The first route in manifest.json must be titled "About" for the static landing page to work correctly. -->

Coder is a self-hosted platform for running AI coding agents and cloud
development environments on infrastructure you control. It works with any
cloud, IDE, OS, Git provider, and IDP.

![Coder platform showing templates and a running workspace](./images/hero-image.png)

## Coder Workspaces

[Coder Workspaces](./user-guides/index.md) are cloud development environments
defined with Terraform, connected through a secure Wireguard tunnel, and
automatically shut down when not in use. Agents and developers share the same
workspace infrastructure.

- **Defined in Terraform**: Templates describe the infrastructure for each
  workspace, from EC2 VMs and Kubernetes Pods to Docker containers.
- **Any architecture and OS**: Support ARM and x86-64 across Windows, Linux,
  and macOS from a single deployment.
- **Managed by admins**: Platform teams create and maintain templates that
  enforce approved images, resource limits, and security policies.
- **Accessed from any IDE**: Connect through VS Code, JetBrains, Cursor,
  a web terminal, remote desktop, or SSH.
- **Automatic shutdown**: Idle workspaces stop automatically to reduce
  cloud spend, and restart in seconds when needed.

## Coder Agents

[Coder Agents](./ai-coder/agents/index.md) is a native AI coding agent built
into Coder. The agent loop runs in the Coder control plane on your
infrastructure, not in the workspace and not in a vendor's cloud. Developers
interact with agents through the web UI, the CLI (`coder agents`), or the REST
API for programmatic and CI-driven workflows.

- **Self-hosted agent loop**: The control plane handles planning, model
  calls, and tool dispatch. Workspaces have zero AI awareness.
- **No API keys in workspaces**: LLM credentials stay in the control plane.
- **Any model**: Anthropic, OpenAI, Google, Bedrock, or self-hosted
  endpoints. Switching is a configuration change.
- **Governance and cost controls**: Centralized model approval, per-user
  spend limits, and audit logging.
- **Open source and inspectable**: The full platform is available to audit
  and extend.

![Coder Agents chat interface with git diff sidebar](./images/agents-hero-image.png)

## IDE support

![IDE icons](./images/ide-icons.svg)

You can use:

- Any Web IDE, such as

  - [code-server](https://github.com/coder/code-server)
  - [JetBrains Projector](https://github.com/JetBrains/projector-server)
  - [Jupyter](https://jupyter.org/)
  - And others

- Your existing remote development environment:

  - [JetBrains Gateway](https://www.jetbrains.com/remote-development/gateway/)
  - [VS Code Remote](https://code.visualstudio.com/docs/remote/ssh-tutorial)
  - [Emacs](./user-guides/workspace-access/emacs-tramp.md)

- A file sync such as [Mutagen](https://mutagen.io/)

## Why remote development

Provisioning consistent development environments for a large engineering team
is difficult. Each developer has preferences for operating systems, editors,
and toolchains, and ensuring a reliable build environment across all of them
is a maintenance burden. A missed step during onboarding or an unsupported
local configuration can cost hours of debugging.

Remote development solves this by moving the environment off the developer's
machine and into managed infrastructure. The developer's laptop becomes a
portal into the actual compute where work happens. If a device is lost or
replaced, access is simply revoked; no source code or credentials are stored
locally.

This approach provides:

- **Speed**: Server-grade hardware accelerates builds, tests, and large
  workloads without requiring expensive local machines.
- **Consistency**: Infrastructure tools such as Terraform, nix, Docker, and
  Dev Containers produce identical environments for every developer.
- **Security**: Source code stays on private servers. Users and groups are
  managed through [SSO](./admin/users/oidc-auth/index.md) and
  [RBAC](./admin/users/groups-roles.md#roles).
- **Compatibility**: Workspaces share infrastructure configurations with
  staging and production, reducing configuration drift.
- **Accessibility**: Browser-based IDEs and remote IDE extensions let
  developers work from any device, including lightweight laptops,
  Chromebooks, and tablets.

Read more on the [Coder blog](https://coder.com/blog), the
[Slack engineering blog](https://slack.engineering/development-environments-at-slack),
or from [Alex Ellis at OpenFaaS](https://blog.alexellis.io/the-internet-is-my-computer/).

## Why Coder

The key difference between Coder and other platforms is that the entire system,
agent loop, control plane, model routing, and workspace provisioning, runs on
infrastructure you control.

For agents, this means platform teams can:

- Run the entire agent loop on their infrastructure, with no SaaS
  dependency for orchestration.
- Define MCP servers, skills, and system prompts centrally so every agent
  session starts with the same tools, policies, and context.
- Keep LLM credentials out of workspaces entirely.
- Tie every agent action to an authenticated user identity.
- Support air-gapped and restricted-network deployments with self-hosted models.

For workspaces, this means admins can:

- Support any architecture (ARM, x86-64) and operating system
  (Windows, Linux, macOS).
- Modify pod/container specs, such as adding disks, managing network policies, or
  setting/updating environment variables.
- Use VM or dedicated workspaces, developing with Kernel features (no container
  knowledge required).
- Enable persistent workspaces, which are like local machines, but faster and
  hosted by a cloud service.

## Pricing

Coder is free and open source under the
[GNU Affero General Public License v3.0](https://github.com/coder/coder/blob/main/LICENSE).
All developer productivity features are included in the open source version.
A [Premium license](https://coder.com/pricing#compare-plans) is available for
enhanced support and custom deployments.

## How Coder works

Coder workspaces are represented with Terraform, but you do not need to know
Terraform to get started. The
[Coder Registry](https://registry.coder.com/templates) provides production-ready
templates for AWS EC2, Azure, Google Cloud, Kubernetes, and other providers.

![Providers and compute environments](./images/providers-compute.png)_Providers and compute environments_

Workspaces can include more than just compute. Terraform can add storage
buckets, secrets, sidecars, and
[other resources](https://developer.hashicorp.com/terraform/tutorials).

See the [templates documentation](./admin/templates/index.md) for details.

## What Coder is not

- Coder is not an infrastructure as code (IaC) platform.

  - Terraform is the first IaC _provisioner_ in Coder, allowing Coder admins to
    define Terraform resources as Coder workspaces.

- Coder is not a DevOps/CI platform.

  - Coder workspaces can be configured to follow best practices for
    cloud-service-based workloads, but Coder is not responsible for how you
    define or deploy the software you write.

- Coder is not an online IDE.

  - Coder supports common editors, such as VS Code, vim, and JetBrains,
    all over HTTPS or SSH.

- Coder is not a collaboration platform.

  - You can use Git with your favorite Git platform and dedicated IDE
    extensions for pull requests, code reviews, and pair programming.

- Coder is not a SaaS/fully-managed offering.
  - Coder is a [self-hosted](<https://en.wikipedia.org/wiki/Self-hosting_(web_services)>)
    solution.
    You must host Coder in a private data center or on a cloud service, such as
    AWS, Azure, or GCP.

## Learn more

- [Coder Agents](./ai-coder/agents/index.md)
- [Templates](./admin/templates/index.md)
- [Installing Coder](./install/index.md)
- [Quickstart tutorial](./tutorials/quickstart.md)

---

# Screenshots

Source: https://coder.com/docs/about/screenshots

# Screenshots

## Log in

![Install Coder in your cloud or air-gapped on-premises. Developers simply log in via their browser to access their Workspaces.](../images/screenshots/coder-login.png)

Install Coder in your cloud or air-gapped on-premises. Developers simply log in
via their browser to access their Workspaces.

## Templates

![Developers provision their own ephemeral Workspaces in minutes using pre-defined Templates that include approved tooling and infrastructure.](../images/screenshots/templates-listing.png)

Developers provision their own ephemeral Workspaces in minutes using pre-defined
Templates that include approved tooling and infrastructure.

![Template administrators can either create a new Template from scratch or choose a Starter Template](../images/screenshots/starter-templates.png)

Template administrators can either create a new Template from scratch or choose
a Starter Template.

![Templates define the underlying infrastructure that Coder Workspaces run on.](../images/screenshots/terraform.png)

Template administrators build Templates using Terraform. Templates define the
underlying infrastructure that Coder Workspaces run on.

## Workspaces

![Developers create and delete their own workspaces. Coder administrators can easily enforce Workspace scheduling and autostop policies to ensure idle Workspaces don’t burn unnecessary cloud budget.](../images/screenshots/workspaces-listing.png)

Developers create and delete their own workspaces. Coder administrators can
easily enforce Workspace scheduling and autostop policies to ensure idle
Workspaces don’t burn unnecessary cloud budget.

![Developers launch their favorite web-based or desktop IDE, browse files, or access their Workspace’s Terminal.](../images/screenshots/workspace-running-with-topbar.png)

Developers launch their favorite web-based or desktop IDE, browse files, or
access their Workspace’s Terminal.

## Administration

![Coder administrators can access Template usage insights to understand which Templates are most popular and how well they perform for developers.](../images/screenshots/template-insights.png)

Coder administrators can access Template usage insights to understand which
Templates are most popular and how well they perform for developers.

![Coder administrators can control *every* aspect of their Coder deployment.](../images/screenshots/admin-settings.png)

Coder administrators can control *every* aspect of their Coder deployment.

![Coder administrators and auditor roles can review how users are interacting with their Coder Workspaces and Templates.](../images/screenshots/audit.png)

Coder administrators and auditor roles can review how users are interacting with
their Coder Workspaces and Templates.

![Coder administrators can monitor the health of their Coder deployment, including database latency, active provisioners, and more.](../images/screenshots/healthcheck.png)

Coder administrators can monitor the health of their Coder deployment, including
database latency, active provisioners, and more.

---

# Quickstart

Source: https://coder.com/docs/tutorials/quickstart

# Quickstart

Follow this guide to get your first Coder development environment
running in under 10 minutes. This guide covers the essential concepts and shows
you how to create your first workspace and open it in your preferred editor.
This workspace includes a basic set of tools to edit most code bases.

## What you'll do

In this quickstart, you'll:

- ✅ Install Coder server.
- ✅ Create a **template** (blueprint for dev environments).
- ✅ Launch a **workspace** (your actual dev environment).
- ✅ Connect from your favorite IDE.

## A 30-second metaphor for Coder

Before diving in, the following table breaks down the core concepts that power Coder,
explained through a cooking analogy:

| Component      | What It Is                                                                           | Real-World Analogy             |
|----------------|--------------------------------------------------------------------------------------|--------------------------------|
| **You**        | The engineer/developer/builder working                                               | The head chef cooking the meal |
| **Templates**  | A Terraform blueprint that defines your dev environment (OS, tools, resources)       | Recipe for a meal              |
| **Workspaces** | The actual running environment created from the template                             | The cooked meal                |
| **Users**      | A developer who launches the workspace from a template and does their work inside it | The people eating the meal     |

**Putting it Together:** Coder separates who _defines_ environments from who _uses_ them. Admins create and manage Templates, the recipes, while developers use those Templates to launch Workspaces, the meals.

## Prerequisites

- A machine with 2+ CPU cores and 4GB+ RAM
- Familiarity with running commands in the terminal
- 10 minutes of your time

## Step 1: Install Docker and set up permissions

<div class="tabs">

### Linux

1. Install Docker:

   ```bash
   curl -sSL https://get.docker.com | sh
   ```

   For more details, visit [Docker's docs on installing Docker on Linux](https://docs.docker.com/desktop/install/linux-install/).

1. Assign your user to the Docker group:

   ```shell
   sudo usermod -aG docker $USER
   ```

1. Run `newgrp` to activate the groups changes:

   ```shell
   newgrp docker
   ```

   You might need to log out of and back into your machine or restart your
   machine for changes to take effect.

1. Launch the Docker daemon:

   ```shell
   sudo systemctl start docker
   ```

### macOS

1. [Install Docker](https://docs.docker.com/desktop/setup/install/mac-install/).
There is a Homebrew formula for the Docker command and a Homebrew cask of Docker
Desktop if you prefer:

   ```shell
   brew install --cask docker-desktop
   ```

1. Open Docker Desktop.

### Windows

If you plan to use the built-in PostgreSQL database, ensure that the
[Visual C++ Runtime](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist#latest-microsoft-visual-c-redistributable-version)
is installed.

1. [Install Docker](https://docs.docker.com/desktop/install/windows-install/).

1. Open Docker Desktop.

</div>

## Step 2: Install and start Coder

Install the `coder` CLI to get started:

<div class="tabs">

### Linux/macOS

1. Install Coder:

   ```shell
   curl -L https://coder.com/install.sh | sh
   ```

   - For standalone binaries, system packages, or other alternate installation
     methods, refer to the
     [latest release on GitHub](https://github.com/coder/coder/releases/latest).

1. Start Coder:

   ```shell
   coder server
   ```

### Windows

If you plan to use the built-in PostgreSQL database, ensure that the
[Visual C++ Runtime](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist#latest-microsoft-visual-c-redistributable-version)
is installed.

1. Use the
   [`winget`](https://learn.microsoft.com/en-us/windows/package-manager/winget/#use-winget)
   package manager to install Coder:

   ```powershell
   winget install Coder.Coder
   ```

1. Start Coder:

   ```shell
   coder server
   ```

</div>

Coder will attempt to open the setup page in your browser. If it doesn't open
automatically, go to <http://localhost:3000>.

- If you get a browser warning similar to `Secure Site Not Available`, you can
  ignore the warning and continue to the setup page.

If your Coder server is on a network or cloud device, or you are having trouble
viewing the page, locate the web UI URL in Coder logs in your terminal. It looks
like `https://<CUSTOM-STRING>.<TUNNEL>.try.coder.app`. It's one of the first
lines of output, so you might have to scroll up to find it.

## Step 3: Initial setup

1. Create your admin account:
   - Email: `your.email@example.com`
   - Password: Choose a strong password.

   You can also choose to **Continue with GitHub** instead of creating an admin
   account. Coder automatically grants admin permissions to the first user that signs in.

   ![Welcome to Coder - Create admin user](../images/screenshots/welcome-create-admin-user.png)

## Step 4: Create your first template and workspace

> [!TIP]
> If you use an AI coding assistant, the [coder-templates](https://github.com/coder/registry/blob/main/.agents/skills/coder-templates/SKILL.md) agent skill can guide you through creating and customizing templates with best practices built-in.

Templates define what's in your development environment. The following is a basic example:

1. Select **Templates** → **New Template**.

2. Select the **Coder Quickstart** template from the list of starter templates.

   **Note:** running this template requires Docker to be running in the background, so make sure Docker is running!

3. Name your template:
   - Name: `quickstart`
   - Display name: `quickstart doc template`
   - Description: `Provision Docker containers as Coder workspaces`

4. Select **Save**.

   ![Create template](../images/screenshots/create-template.png)

**What just happened?** You defined a template — a reusable blueprint for dev
environments — in your Coder deployment. It's now stored in your organization's
template list, where you and any teammates in the same org can create workspaces
from it. Now it's time launch a workspace.

## Step 5: Launch your workspace

1. After the template is ready, select **+ Create Workspace**.

2. Give the workspace a name. If you need a suggestion for a workspace, you can select the automatically generated name next to the **Need a suggestion?** label.

3. In this window are [parameters](../admin/templates/extending-templates/parameters.md) that customize the workspace's behavior. Set the following based on your needs:

   - **Programming Languages**: the languages to pre-install in your workspace. You can use more than one if you want.
   - **IDEs & Editors**: the IDEs and editors you want to configure for quick access once the workspace is running. You can choose more than one if you want.
   - **Git Repository (Optional)**: the Git repository you want to clone into your workspace. Leave this field blank to skip it.

   **Note:** If you use any of the JetBrains IDEs as your preferred IDE (such as PyCharm, GoLand, or RustRover), select **JetBrains IDEs** as the value. A new parameter will appear, with which you can choose your preferred JetBrains IDE.

4. Launch your workspace by selecting **Create workspace**.

After a short wait (10-15 seconds on most modern computers), Coder will start your new workspace:

![getting-started-workspace is running](../images/screenshots/workspace-running-with-topbar.png)_Workspace is running_

## Step 6: Connect your IDE

Each of the buttons in the workspace view is a different **agent app**
(more on this in a later section). Select your preferred IDE from the
list of agent apps. This guide assumes you'll use Visual Studio Code,
but the process is similar for other IDEs and editors.

After VS Code loads the remote environment, you can select **Open Folder** to
explore directories in the Docker container or work on something new.

![Changing directories in VS Code](../images/screenshots/change-directory-vscode.png)

If you didn't clone an existing Git repository when you created your
workspace, you can clone it manually if you want:

1. Select **Clone Repository** and enter the repository URL.

   For example, to clone the Coder repo, enter
   `https://github.com/coder/coder.git`.

   Learn more about how to find the repository URL in the
   [GitHub documentation](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository).

2. Choose the folder to which VS Code should clone the repo. It will be in its
   own directory within this folder.

   Note that you cannot create a new parent directory in this step.

3. After VS Code completes the clone, select **Open** to open the directory.

4. You are now using VS Code in your Coder environment!

## Success! You're coding in Coder

You now have:

- A Coder server running locally.
- A template defining your environment.
- A workspace running that environment.
- IDE access to code remotely.

### What's next?

Now that you have your own workspace running, you can start exploring more
advanced capabilities that Coder offers.

- [Try Coder Agents](../ai-coder/agents/getting-started.md), the chat
  interface and API for delegating development work to coding agents in your
  Coder deployment.

- [Read about managing Workspaces for your team](../user-guides/workspace-management.md)

- [Read about implementing monitoring tools for your Coder Deployment](../admin/monitoring/index.md)

## Troubleshooting

### Cannot connect to the Docker daemon

When creating a workspace from a Docker template, you may see an error like:

```text
Error: Error pinging Docker server: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

This means Docker is either not installed or not running on the machine where
Coder is running. Docker must be running before you create a workspace from a
Docker-based template.

<div class="tabs">

#### macOS

1. If Docker Desktop is not installed,
   [install it](https://docs.docker.com/desktop/setup/install/mac-install/) or
   use Homebrew:

   ```shell
   brew install --cask docker-desktop
   ```

1. Open Docker Desktop and verify that it is running.

#### Linux

1. Install Docker, if you haven't already:

   ```shell
   curl -sSL https://get.docker.com | sh
   ```

1. Start the Docker daemon:

   ```shell
   sudo systemctl start docker
   ```

1. Assign your user to the `docker` group so Coder can access the daemon
   without root:

   ```shell
   sudo usermod -aG docker $USER
   newgrp docker
   ```

1. Confirm the group membership:

   ```console
   $ groups
   docker sudo users
   ```

#### Windows

1. If Docker Desktop is not installed,
   [install it](https://docs.docker.com/desktop/install/windows-install/).

1. Open Docker Desktop and verify that it is running.

</div>

### Can't start Coder server: Address already in use

```shell
Encountered an error running "coder server", see "coder server --help" for more information
error: configure http(s): listen tcp 127.0.0.1:3000: bind: address already in use
```

Another process is already listening on port 3000. Identify and stop it,
then start the server again.

#### Linux

1. Stop the process:

   ```shell
   sudo systemctl stop coder
   ```

1. Start Coder:

   ```shell
   coder server
   ```

#### macOS

1. Identify the process using port 3000:

   ```shell
   lsof -i :3000
   ```

1. Stop the process using the PID from the previous command:

   ```shell
   kill <PID>
   ```

   If the process does not exit, force-kill it:

   ```shell
   kill -9 <PID>
   ```

1. Start Coder:

   ```shell
   coder server
   ```

#### Windows

1. Identify the process using port 3000 in PowerShell:

   ```powershell
   Get-NetTCPConnection -LocalPort 3000 | Select-Object OwningProcess
   ```

1. Stop the process using the PID from the previous command:

   ```powershell
   Stop-Process -Id <PID>
   ```

1. Start Coder:

   ```shell
   coder server
   ```

---

# Support

Source: https://coder.com/docs/support

# Support

If you have questions, encounter an issue or bug, or if you have a feature request, [open a GitHub issue](https://github.com/coder/coder/issues/new) or [join our Discord](https://discord.gg/coder).

<children></children>

---

# Generate a Support Bundle

Source: https://coder.com/docs/support/support-bundle

# Generate and upload a Support Bundle to Coder Support

When you engage with Coder support to diagnose an issue with your deployment,
you may be asked to generate and upload a "Support Bundle" for offline analysis.
This document explains the contents of a support bundle and the steps to submit
a support bundle to Coder staff.

## What is a Support Bundle?

A support bundle is an archive containing a snapshot of information about your
Coder deployment.

It contains information about the workspace, the template it uses, running
agents in the workspace, and other detailed information useful for
troubleshooting.

It is primarily intended for troubleshooting connectivity issues to workspaces,
but can be useful for diagnosing other issues as well.

**While we attempt to redact sensitive information from support bundles, they
may contain information deemed sensitive by your organization and should be
treated as such.**

A brief overview of all files contained in the bundle is provided below:

> [!NOTE]
> Detailed descriptions of all the information available in the bundle is
> out of scope, as support bundles are primarily intended for internal use.

| Filename                          | Description                                                                                                                       |
|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
| `agent/agent.json`                | The agent used to connect to the workspace with environment variables stripped.                                                   |
| `agent/agent_magicsock.html`      | The contents of the HTTP debug endpoint of the agent's Tailscale Wireguard connection.                                            |
| `agent/client_magicsock.html`     | The contents of the HTTP debug endpoint of the client's Tailscale Wireguard connection.                                           |
| `agent/listening_ports.json`      | The listening ports detected by the selected agent running in the workspace.                                                      |
| `agent/logs.txt`                  | The logs of the selected agent running in the workspace.                                                                          |
| `agent/manifest.json`             | The manifest of the selected agent with environment variables stripped.                                                           |
| `agent/startup_logs.txt`          | Startup logs of the workspace agent.                                                                                              |
| `agent/prometheus.txt`            | The contents of the agent's Prometheus endpoint.                                                                                  |
| `cli_logs.txt`                    | Logs from running the `coder support bundle` command.                                                                             |
| `deployment/buildinfo.json`       | Coder version and build information.                                                                                              |
| `deployment/config.json`          | Deployment [configuration](../reference/api/general.md#get-deployment-config), with secret values removed. *Requires Owner role.* |
| `deployment/experiments.json`     | Any [experiments](../reference/cli/server.md#--experiments) currently enabled for the deployment.                                 |
| `deployment/health.json`          | A snapshot of the [health status](../admin/monitoring/health-check.md) of the deployment. *Requires Owner role.*                  |
| `logs.txt`                        | Logs from the `codersdk.Client` used to generate the bundle.                                                                      |
| `network/connection_info.json`    | Information used by workspace agents used to connect to Coder (DERP map etc.)                                                     |
| `network/coordinator_debug.html`  | Peers currently connected to each Coder instance and the tunnels established between peers. *Requires Owner role.*                |
| `network/netcheck.json`           | Results of running `coder netcheck` locally.                                                                                      |
| `network/tailnet_debug.html`      | Tailnet coordinators, their heartbeat ages, connected peers, and tunnels. *Requires Owner role.*                                  |
| `workspace/build_logs.txt`        | Build logs of the selected workspace.                                                                                             |
| `workspace/workspace.json`        | Details of the selected workspace.                                                                                                |
| `workspace/parameters.json`       | Build parameters of the selected workspace.                                                                                       |
| `workspace/template.json`         | The template currently in use by the selected workspace.                                                                          |
| `workspace/template_file.zip`     | The source code of the template currently in use by the selected workspace.                                                       |
| `workspace/template_version.json` | The template version currently in use by the selected workspace.                                                                  |

## How do I generate a Support Bundle?

1. Ensure your deployment is up and running. Generating a support bundle
   requires the Coder deployment to be available.

2. Ensure you have the Coder CLI installed on a local machine. See
   [installation](../install/index.md) for steps on how to do this.

   > [!NOTE]
   > It is recommended to generate a support bundle from a location
   > experiencing workspace connectivity issues.

3. Ensure you are [logged in](../reference/cli/login.md#login) to your Coder
   deployment. Any authenticated user can generate a support bundle. Users with
   the Owner role will get the most complete bundle; non-admin users will still
   get a useful bundle but some admin-only data will be omitted (see the note
   below).

4. Run `coder support bundle [owner/workspace]`, and respond `yes` to the
   prompt. The support bundle will be generated in the current directory with
   the filename `coder-support-$TIMESTAMP.zip`.

   > [!NOTE]
   > While support bundles can be generated without a running workspace, it is
   > recommended to specify one to maximize troubleshooting information.

5. (Recommended) Extract the support bundle and review its contents, redacting
   any information you deem necessary.

6. Coder staff will provide you a link where you can upload the bundle along
   with any other necessary supporting files.

   > [!NOTE]
   > It is helpful to leave an informative message regarding the nature of
   > supporting files.

Coder support will then review the information you provided and respond to you
with next steps.

---

# Contributing

Source: https://coder.com/docs/about/contributing/CONTRIBUTING

# Contributing

## Requirements

<div class="tabs">

To get started with Coder, the easiest way to set up the required environment is to use the provided [Nix environment](https://github.com/coder/coder/tree/main/nix).
Learn more [how Nix works](https://nixos.org/guides/how-nix-works).

### Nix

1. [Install Nix](https://nix.dev/install-nix#install-nix)

1. After you've installed Nix, instantiate the development with the `nix-shell`
   command:

   ```shell
   cd ~/code/coder

   # https://nix.dev/tutorials/declarative-and-reproducible-developer-environments
   nix-shell

   ...
   copying path '/nix/store/3ms6cs5210n8vfb5a7jkdvzrzdagqzbp-iana-etc-20210225' from 'https://   cache.nixos.org'...
   copying path '/nix/store/dxg5aijpyy36clz05wjsyk90gqcdzbam-iana-etc-20220520' from 'https://   cache.nixos.org'...
   copying path '/nix/store/v2gvj8whv241nj4lzha3flq8pnllcmvv-ignore-5.2.0.tgz' from 'https://cache.   nixos.org'...
   ...
   ```

1. Optional: If you have [direnv](https://direnv.net/) installed with
   [hooks configured](https://direnv.net/docs/hook.html), you can add `use nix`
   to `.envrc` to automatically instantiate the development environment:

   ```shell
   cd ~/code/coder
   echo "use nix" >.envrc
   direnv allow
   ```

   Now, whenever you enter the project folder,
   [`direnv`](https://direnv.net/docs/hook.html) will prepare the environment
   for you:

   ```shell
   cd ~/code/coder

   direnv: loading ~/code/coder/.envrc
   direnv: using nix
   direnv: export +AR +AS +CC +CONFIG_SHELL +CXX +HOST_PATH +IN_NIX_SHELL +LD +NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_BUILD_CORES +NIX_BUILD_TOP +NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_CFLAGS_COMPILE +NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE +NIX_INDENT_MAKE +NIX_LDFLAGS +NIX_STORE +NM +NODE_PATH +OBJCOPY +OBJDUMP +RANLIB +READELF +SIZE +SOURCE_DATE_EPOCH +STRINGS +STRIP +TEMP +TEMPDIR +TMP +TMPDIR +XDG_DATA_DIRS +buildInputs +buildPhase +builder +cmakeFlags +configureFlags +depsBuildBuild +depsBuildBuildPropagated +depsBuildTarget +depsBuildTargetPropagated +depsHostHost +depsHostHostPropagated +depsTargetTarget +depsTargetTargetPropagated +doCheck +doInstallCheck +mesonFlags +name +nativeBuildInputs +out +outputs +patches +phases +propagatedBuildInputs +propagatedNativeBuildInputs +shell +shellHook +stdenv +strictDeps +system ~PATH

   🎉
   ```

   - If you encounter a `creating directory` error on macOS, check the
     [troubleshooting](#troubleshooting) section below.

### Without Nix

If you're not using the Nix environment, you can launch a local [DevContainer](https://github.com/coder/coder/tree/main/.devcontainer) to get a fully configured development environment.

DevContainers are supported in tools like **VS Code** and **GitHub Codespaces**, and come preloaded with all required dependencies: Docker, Go, Node.js with `pnpm`, and `make`.

</div>

## Development workflow

Use the following `make` commands and scripts in development:

- `./scripts/develop.sh` runs the frontend and backend development server
- `make build` compiles binaries and release packages
- `make install` installs binaries to `$GOPATH/bin`
- `make test`
- `make pre-commit` runs gen, fmt, lint, typos, and builds a slim binary
- `make pre-commit-light` runs fmt and lint for shell, terraform, markdown,
  helm, actions, and typos (skips gen, Go/TS lint+fmt, and binary build)
- `make pre-push` runs heavier CI checks including tests (allowlisted)

Install the git hooks to run these automatically:

```sh
git config core.hooksPath scripts/githooks
```

The hooks classify staged/changed files and select the appropriate target.
Commits that only touch docs, shell, terraform, or other lightweight files
run `make pre-commit-light` instead of the full `make pre-commit`, and
`pre-push` is skipped entirely. Changes to Go, TypeScript, SQL, proto, or
the Makefile trigger the full targets as before.

### Running Coder on development mode

1. Run the development script to spin up the local environment:

   ```sh
   ./scripts/develop.sh
   ```

   This will start two processes:

   - http://localhost:3000 — the backend API server. Primarily used for backend development and also serves the *static* frontend build.
   - http://localhost:8080 — the Node.js frontend development server. Supports *hot reloading* and is useful if you're working on the frontend as well.

   Additionally, it starts a local PostgreSQL instance, creates both an admin and a member user account, and installs a default Docker-based template.

1. Verify Your Session

   Confirm that you're logged in by running:

   ```sh
   ./scripts/coder-dev.sh list
      ```

   This should return an empty list of workspaces. If you encounter an error, review the output from the [develop.sh](https://github.com/coder/coder/blob/main/scripts/develop.sh) script for issues.

   > [!NOTE]
   > `coder-dev.sh` is a helper script that behaves like the regular coder CLI, but uses the binary built from your local source and shares the same configuration directory set up by `develop.sh`. This ensures your local changes are reflected when testing.
   >
   > The default user is `admin@coder.com` and the default password is `SomeSecurePassword!`

1. Create Your First Workspace

   A template named `docker` is created automatically. To spin up a workspace quickly, use:

   ```sh
   ./scripts/coder-dev.sh create my-workspace -t docker
   ```

### Deploying a PR

You need to be a member or collaborator of the [coder](https://github.com/coder) GitHub organization to be able to deploy a PR.

You can test your changes by creating a PR deployment. There are two ways to do
this:

- Run `./scripts/deploy-pr.sh`
- Manually trigger the
  [`pr-deploy.yaml`](https://github.com/coder/coder/actions/workflows/pr-deploy.yaml)
  GitHub Action workflow.

#### Available options

- `-d` or `--deploy`, force deploys the PR by deleting the existing deployment.
- `-b` or `--build`, force builds the Docker image. (generally not needed as we
  are intelligently checking if the image needs to be built)
- `-e EXPERIMENT1,EXPERIMENT2` or `--experiments EXPERIMENT1,EXPERIMENT2`, will
  enable the specified experiments. (defaults to `*`)
- `-n` or `--dry-run` will display the context without deployment. e.g., branch
  name and PR number, etc.
- `-y` or `--yes`, will skip the CLI confirmation prompt.

> [!NOTE]
> PR deployment will be re-deployed automatically when the PR is updated.
> It will use the last values automatically for redeployment.

Once the deployment is finished, a unique link and credentials will be posted in
the [#pr-deployments](https://codercom.slack.com/archives/C05DNE982E8) Slack
channel.

## Styling

- [Documentation style guide](./documentation.md)

- [Frontend styling guide](./frontend.md#styling)

## Pull Requests

We welcome pull requests (PRs) from community members including (but not limited to) open source users, enthusiasts, and enterprise customers.

We will ask that you sign a Contributor License Agreement before we accept any contributions into our repo.

Please keep PRs small and self-contained. This allows code reviewers (see below) to focus and fully understand the PR. A good rule of thumb is less than 1000 lines changed. (One exception is a mechanistic refactor, like renaming, that is conceptually trivial but might have a large line count.)

If your intended feature or refactor will be larger than this:

 1. Open an issue explaining what you intend to build, how it will work, and that you are volunteering to do the development. Include `@coder/community-triage` in the body.
 2. Give the maintainers a chance to respond. Changes to the visual, interaction, or software design are easier to adjust before you start laying down code.
 3. Break your work up into a series of smaller PRs.

Stacking tools like [Graphite](https://www.graphite.dev) are useful for keeping a series of PRs that build on each other up to date as they are reviewed and merged.

Each PR:

- Must individually build and pass all tests, including formatting and linting.
- Must not introduce regressions or backward-compatibility issues, even if a subsequent PR in your series would resolve the issue.
- Should be a conceptually coherent change set.

In practice, many of these smaller PRs will be invisible to end users, and that is ok. For example, you might introduce
a new Go package that implements the core business logic of a feature in one PR, but only later actually "wire it up"
to a new API route in a later PR. Or, you might implement a new React component in one PR, and only in a later PR place it on a page.

## Reviews

The following information has been borrowed from [Go's review philosophy](https://go.dev/doc/contribute#reviews).

Coder values thorough reviews. For each review comment that you receive, please
"close" it by implementing the suggestion or providing an explanation on why the
suggestion isn't the best option. Be sure to do this for each comment; you can
click **Done** to indicate that you've implemented the suggestion, or you can
add a comment explaining why you aren't implementing the suggestion (or what you
chose to implement instead).

It is perfectly normal for changes to go through several rounds of reviews, with
one or more reviewers making new comments every time, then waiting for an
updated change before reviewing again. All contributors, including those from
maintainers, are subject to the same review cycle; this process is not meant to
be applied selectively or to discourage anyone from contributing.

## Releases

Coder releases are initiated via
[`./scripts/release.sh`](https://github.com/coder/coder/blob/main/scripts/release.sh)
and automated via GitHub Actions. Specifically, the
[`release.yaml`](https://github.com/coder/coder/blob/main/.github/workflows/release.yaml)
workflow.

Release notes are automatically generated from commit titles and PR metadata.

### Release types

| Type                   | Tag           | Branch        | Purpose                                 |
|------------------------|---------------|---------------|-----------------------------------------|
| RC (release candidate) | `vX.Y.0-rc.W` | `main`        | Ad-hoc pre-release for customer testing |
| Release                | `vX.Y.0`      | `release/X.Y` | First release of a minor version        |
| Patch                  | `vX.Y.Z`      | `release/X.Y` | Bug fixes and security patches          |

### Workflow

RC tags are created directly on `main`. The `release/X.Y` branch is only cut
when the release is ready. This avoids cherry-picking main's progress onto
a release branch between the first RC and the release.

```text
main:  ──●──●──●──●──●──●──●──●──●──
              ↑           ↑     ↑
           rc.0        rc.1    cut release/2.34, tag v2.34.0
                                     \
                               release/2.34:  ──●── v2.34.1 (patch)
```

1. **RC:** On `main`, run `./scripts/release.sh`. The tool suggests the next
   RC version and tags it on `main`.
2. **Release:** When the RC is blessed, create `release/X.Y` from `main` (or
   the specific RC commit). Switch to that branch and run
   `./scripts/release.sh`, which suggests `vX.Y.0`.
3. **Patch:** Cherry-pick fixes onto `release/X.Y` and run
   `./scripts/release.sh` from that branch.

The release tool warns if you try to tag a non-RC on `main` or an RC on a
release branch.

### Creating a release (via workflow dispatch)

If the
[`release.yaml`](https://github.com/coder/coder/actions/workflows/release.yaml)
workflow fails after the tag has been pushed, retry it from the GitHub Actions
UI: press "Run workflow", set "Use workflow from" to the tag (e.g.
`Tag: v2.34.0`), select the correct release channel, and do **not** select
dry-run.

To test the workflow without publishing, select dry-run.

### Commit messages

Commit messages should follow the
[Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/)
specification.

Allowed commit types (`feat`, `fix`, etc.) are listed in
[conventional-commit-types](https://github.com/commitizen/conventional-commit-types/blob/c3a9be4c73e47f2e8197de775f41d981701407fb/index.json).
Note that these types are also used to automatically sort and organize the
release notes.

A good commit message title uses the imperative, present tense and is ~50
characters long (no more than 72).

Examples:

- Good: `feat(coderd): add feature X`
- Bad: `feat(coderd): added feature X` (past tense)

Scopes must reference a real path in the repository (a directory or file stem)
and must contain all changed files. For example, use `coderd/database` if all
changes are within that directory. If changes span multiple top-level
directories, omit the scope.

A good rule of thumb for writing good commit messages is to recite:
[If applied, this commit will ...](https://reflectoring.io/meaningful-commit-messages/).

**Note:** We lint PR titles to ensure they follow the Conventional Commits
specification, however, it's still possible to merge PRs on GitHub with a badly
formatted title. Take care when merging single-commit PRs as GitHub may prefer
to use the original commit title instead of the PR title.

### Backporting fixes to release branches

When a merged PR on `main` should also ship in older releases, add the
`backport` label to the PR. The
[backport workflow](https://github.com/coder/coder/blob/main/.github/workflows/backport.yaml)
will automatically detect the latest three `release/*` branches,
cherry-pick the merge commit onto each one, and open PRs for
review.

The label can be added before or after the PR is merged. Each backport
PR reuses the original title (e.g.
`fix(site): correct button alignment (#12345)`) so the change is
meaningful in release notes.

If the cherry-pick encounters conflicts, the backport PR is still created
with instructions for manual resolution — no conflict markers are committed.

### Breaking changes

Breaking changes can be triggered in two ways:

- Add `!` to the commit message title, e.g.
  `feat(coderd)!: remove deprecated endpoint /test`
- Add the
  [`release/breaking`](https://github.com/coder/coder/issues?q=sort%3Aupdated-desc+label%3Arelease%2Fbreaking)
  label to a PR that has, or will be, merged into `main`.

### Generative AI

Using AI to help with contributions is acceptable, but only if the [AI Contribution Guidelines](./AI_CONTRIBUTING.md)
are followed. If most of your PR was generated by AI, please read and comply with these rules before submitting.

### Security

> [!CAUTION]
> If you find a vulnerability, **DO NOT FILE AN ISSUE**. Instead, send an email
> to <security@coder.com>.

The
[`security`](https://github.com/coder/coder/issues?q=sort%3Aupdated-desc+label%3Asecurity)
label can be added to PRs that have, or will be, merged into `main`. Doing so
will make sure the change stands out in the release notes.

### Experimental

The
[`release/experimental`](https://github.com/coder/coder/issues?q=sort%3Aupdated-desc+label%3Arelease%2Fexperimental)
label can be used to move the note to the bottom of the release notes under a
separate title.

## Troubleshooting

### Database migration mismatch after switching branches

If `./scripts/develop.sh` exits with a "database migration conflict" error,
it means the database has migrations from another branch that don't exist
on the current one. You have two options:

```shell
# Roll back the mismatched migrations (preserves your dev data):
./scripts/develop.sh --db-rollback

# Or wipe the database and start fresh:
./scripts/develop.sh --db-reset
```

### Nix on macOS: `error: creating directory`

On macOS, a [direnv bug](https://github.com/direnv/direnv/issues/1345) can cause
`nix-shell` to fail to build or run `coder`. If you encounter
`error: creating directory` when you attempt to run, build, or test, add a
`mkdir` line to your `.envrc`:

```shell
use nix
mkdir -p "$TMPDIR"
```

---

# Code of Conduct

Source: https://coder.com/docs/about/contributing/CODE_OF_CONDUCT

# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and
expression, level of experience, education, socio-economic status, nationality,
personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

- The use of sexualized language or imagery and unwelcome sexual attention or
  advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
  address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <opensource@coder.com>. All complaints
will be reviewed and investigated and will result in a response that is deemed
necessary and appropriate to the circumstances. The project team is obligated to
maintain confidentiality with regard to the reporter of an incident. Further
details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at
<https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
<https://www.contributor-covenant.org/faq>

---

# Documentation

Source: https://coder.com/docs/about/contributing/documentation

# Documentation

This style guide is primarily for use with authoring documentation.

## General guidelines

- Use sentence case, even in titles (do not punctuate the title, though)
- Use the second person
- Use the active voice
- Use plural nouns and pronouns (_they_, _their_, or _them_), especially when
  the specific number is uncertain (i.e., "Set up your environments" even though
  you don't know if the user will have one or many environments)
- When writing documentation titles, use the noun form, not the gerund form
  (e.g., "Environment Management" instead of "Managing Environments")
- Context matters when you decide whether to capitalize something or not. For
  example,
  ["A Job creates one or more Pods..."](https://kubernetes.io/docs/concepts/workloads/controllers/job/)
  is correct when writing about Kubernetes. However, in other contexts, neither
  _job_ nor _pods_ would be capitalized. Please follow the conventions set forth
  by the relevant companies and open source communities.

## Third-party references

If you have questions that aren't explicitly covered by this guide, consult the
following third-party references:

| **Type of guidance** | **Third-party reference**                                                              |
|----------------------|----------------------------------------------------------------------------------------|
| Spelling             | [Merriam-Webster.com](https://www.merriam-webster.com/)                                |
| Style - nontechnical | [The Chicago Manual of Style](https://www.chicagomanualofstyle.org/home.html)          |
| Style - technical    | [Microsoft Writing Style Guide](https://docs.microsoft.com/en-us/style-guide/welcome/) |

## Tools

The following are tools that you can use to edit your writing. However, take the
suggestions provided with a grain of salt.

- [alex.js](https://alexjs.com/)
- [Grammarly](https://app.grammarly.com/)
- [Hemingway Editor](https://hemingwayapp.com/)

## How to format text

Below summarizes the text-formatting conventions you should follow.

### Bold

Use **bold** formatting when referring to UI elements.

### Italics

Use _italics_ for:

- Parameter names
- Mathematical and version variables

### Code font

Use _code font_ for:

- User text input
- Command-line utility names
- DNS record types
- Environment variable names (e.g., `PATH`)
- Filenames, filename extensions, and paths
- Folders and directories
- HTTP verbs, status codes, and content-type values
- Placeholder variables

Use _code blocks_ for code samples and other blocks of code. Be sure to indicate
the language your using to apply the proper syntax highlighting.

```text
This is a codeblock.
```

For code that you want users to enter via a command-line interface, use
`console`, not `bash`.

### Punctuation

Do not use the ampersand (&) as a shorthand for _and_ unless you're referring to
a UI element or the name of something that uses _&_.

You can use the symbol `~` in place of the word _approximately_.

### UI elements

When referring to UI elements, including the names for buttons, menus, dialogs,
and anything that has a name visible to the user, use bold font.

**Example:** On the **Environment Overview** page, click **Configure SSH**.

Don't use code font for UI elements unless it is rendered based on previously
entered text. For example, if you tell the user to provide the environment name
as `myEnvironment`, then use both bold and cold font when referring to the name.

**Example**: Click **`myEnvironment`**.

When writing out instructions that involve UI elements, both of the following
options are acceptable:

- Go to **Manage** > **Users**.
- In the **Manage** menu, click **Users**.

## Product-specific references

Below summarizes the guidelines regarding how Coder terms should be used.

### Capitalized terms

The only Coder-specific terms that should be capitalized are the names of
products (e.g., Coder).

The exception is **code-server**, which is always lowercase. If it appears at
the beginning of the sentence, rewrite the sentence to avoid this usage.

### Uncapitalized terms

In general, we do not capitalize the names of features (unless the situation
calls for it, such as the word appearing at the beginning of a sentence):

- account dormancy
- audit logs
- autostart
- command-line interface
- dev URLs
- environment
- image
- metrics
- organizations
- progressive web app
- registries
- single sign-on
- telemetry
- workspace
- workspace providers
- workspaces as code

We also do not capitalize the names of user roles:

- auditor
- member
- site admin
- site manager

## Standardized spellings

- WiFi

---

# Modules

Source: https://coder.com/docs/about/contributing/modules

# Contributing modules

Learn how to create and contribute Terraform modules to the Coder Registry. Modules provide reusable components that extend Coder workspaces with IDEs, development tools, login tools, and other features.

## What are Coder modules

Coder modules are Terraform modules that integrate with Coder workspaces to provide specific functionality. They are published to the Coder Registry at [registry.coder.com](https://registry.coder.com) and can be consumed in any Coder template using standard Terraform module syntax.

Examples of modules include:

- **Desktop IDEs**: [`jetbrains-fleet`](https://registry.coder.com/modules/coder/jetbrains-fleet), [`cursor`](https://registry.coder.com/modules/coder/cursor), [`windsurf`](https://registry.coder.com/modules/coder/windsurf), [`zed`](https://registry.coder.com/modules/coder/zed)
- **Web IDEs**: [`code-server`](https://registry.coder.com/modules/coder/code-server), [`vscode-web`](https://registry.coder.com/modules/coder/vscode-web), [`jupyter-notebook`](https://registry.coder.com/modules/coder/jupyter-notebook), [`jupyter-lab`](https://registry.coder.com/modules/coder/jupyterlab)
- **Integrations**: [`devcontainers-cli`](https://registry.coder.com/modules/coder/devcontainers-cli), [`vault-github`](https://registry.coder.com/modules/coder/vault-github), [`jfrog-oauth`](https://registry.coder.com/modules/coder/jfrog-oauth), [`jfrog-token`](https://registry.coder.com/modules/coder/jfrog-token)
- **Workspace utilities**: [`git-clone`](https://registry.coder.com/modules/coder/git-clone), [`dotfiles`](https://registry.coder.com/modules/coder/dotfiles), [`filebrowser`](https://registry.coder.com/modules/coder/filebrowser), [`coder-login`](https://registry.coder.com/modules/coder/coder-login), [`personalize`](https://registry.coder.com/modules/coder/personalize)

## Prerequisites

Before contributing modules, ensure you have:

- Basic Terraform knowledge
- [Terraform installed](https://developer.hashicorp.com/terraform/install)
- [Docker installed](https://docs.docker.com/get-docker/) (for running tests)
- [Bun installed](https://bun.sh/docs/installation) (for running tests and tooling)

## Setup your development environment

1. **Fork and clone the repository**:

   ```bash
   git clone https://github.com/your-username/registry.git
   cd registry
   ```

2. **Install dependencies**:

   ```bash
   bun install
   ```

3. **Understand the structure**:

   ```text
   registry/[namespace]/
   ├── modules/         # Your modules
   ├── .images/         # Namespace avatar and screenshots
   └── README.md        # Namespace description
   ```

## Create your first module

### 1. Set up your namespace

If you're a new contributor, create your namespace directory:

```bash
mkdir -p registry/[your-username]
mkdir -p registry/[your-username]/.images
```

Add your namespace avatar by downloading your GitHub avatar and saving it as `avatar.png`:

```bash
curl -o registry/[your-username]/.images/avatar.png https://github.com/[your-username].png
```

Create your namespace README at `registry/[your-username]/README.md`:

```markdown
---
display_name: "Your Name"
bio: "Brief description of what you do"
github: "your-username"
avatar: "./.images/avatar.png"
linkedin: "https://www.linkedin.com/in/your-username"
website: "https://your-website.com"
support_email: "support@your-domain.com"
status: "community"
---

# Your Name

Brief description of who you are and what you do.
```

> [!NOTE]
> The `linkedin`, `website`, and `support_email` fields are optional and can be omitted or left empty if not applicable.

### 2. Generate module scaffolding

Use the provided script to generate your module structure:

```bash
./scripts/new_module.sh [your-username]/[module-name]
cd registry/[your-username]/modules/[module-name]
```

This creates:

- `main.tf` - Terraform configuration template
- `README.md` - Documentation template with frontmatter
- `run.sh` - Optional execution script

### 3. Implement your module

Edit `main.tf` to build your module's features. Here's an example based on the `git-clone` module structure:

```terraform
terraform {
  required_providers {
    coder = {
      source = "coder/coder"
    }
  }
}

# Input variables
variable "agent_id" {
  description = "The ID of a Coder agent"
  type        = string
}

variable "url" {
  description = "Git repository URL to clone"
  type        = string
  validation {
    condition = can(regex("^(https?://|git@)", var.url))
    error_message = "URL must be a valid git repository URL."
  }
}

variable "base_dir" {
  description = "Directory to clone the repository into"
  type        = string
  default     = "~"
}

# Resources
resource "coder_script" "clone_repo" {
  agent_id     = var.agent_id
  display_name = "Clone Repository"
  script = <<-EOT
    #!/bin/bash
    set -e
    
    # Ensure git is installed
    if ! command -v git &> /dev/null; then
        echo "Installing git..."
        sudo apt-get update && sudo apt-get install -y git
    fi
    
    # Clone repository if it doesn't exist
    if [ ! -d "${var.base_dir}/$(basename ${var.url} .git)" ]; then
        echo "Cloning ${var.url}..."
        git clone ${var.url} ${var.base_dir}/$(basename ${var.url} .git)
    fi
  EOT
  run_on_start = true
}

# Outputs
output "repo_dir" {
  description = "Path to the cloned repository"
  value       = "${var.base_dir}/$(basename ${var.url} .git)"
}
```

### 4. Write complete tests

Create `main.test.ts` to test your module features:

```typescript
import { runTerraformApply, runTerraformInit, testRequiredVariables } from "~test"

describe("git-clone", async () => {
  await testRequiredVariables("registry/[your-username]/modules/git-clone")
  
  it("should clone repository successfully", async () => {
    await runTerraformInit("registry/[your-username]/modules/git-clone")
    await runTerraformApply("registry/[your-username]/modules/git-clone", {
      agent_id: "test-agent-id",
      url: "https://github.com/coder/coder.git",
      base_dir: "/tmp"
    })
  })
  
  it("should work with SSH URLs", async () => {
    await runTerraformInit("registry/[your-username]/modules/git-clone")
    await runTerraformApply("registry/[your-username]/modules/git-clone", {
      agent_id: "test-agent-id",
      url: "git@github.com:coder/coder.git"
    })
  })
})
```

### 5. Document your module

Update `README.md` with complete documentation:

```markdown
---
display_name: "Git Clone"
description: "Clone a Git repository into your Coder workspace"
icon: "../../../../.icons/git.svg"
verified: false
tags: ["git", "development", "vcs"]
---

# Git Clone

This module clones a Git repository into your Coder workspace and ensures Git is installed.

## Usage

```tf
module "git_clone" {
  source   = "registry.coder.com/[your-username]/git-clone/coder"
  version  = "~> 1.0"
  
  agent_id = coder_agent.main.id
  url      = "https://github.com/coder/coder.git"
  base_dir = "/home/coder/projects"
}
```

## Module best practices

### Design principles

- **Single responsibility**: Each module should have one clear purpose
- **Reusability**: Design for use across different workspace types
- **Flexibility**: Provide sensible defaults but allow customization
- **Safe to rerun**: Ensure modules can be applied multiple times safely

### Terraform conventions

- Use descriptive variable names and include descriptions
- Provide default values for optional variables
- Include helpful outputs for working with other modules
- Use proper resource dependencies
- Follow [Terraform style conventions](https://developer.hashicorp.com/terraform/language/syntax/style)

### Documentation standards

Your module README should include:

- **Frontmatter**: Required metadata for the registry
- **Description**: Clear explanation of what the module does
- **Usage example**: Working Terraform code snippet
- **Additional context**: Setup requirements, known limitations, etc.

> [!NOTE]
> Do not include variables tables in your README. The registry automatically generates variable documentation from your `main.tf` file.

## Test your module

Run tests to ensure your module works correctly:

```bash
# Test your specific module
bun test -t 'git-clone'

# Test all modules
bun test

# Format code
bun fmt
```

> [!IMPORTANT]
> Tests require Docker with `--network=host` support, which typically requires Linux. macOS users can use [Colima](https://github.com/abiosoft/colima) or [OrbStack](https://orbstack.dev/) instead of Docker Desktop.

## Contribute to existing modules

### Types of contributions

**Bug fixes**:

- Fix installation or configuration issues
- Resolve compatibility problems
- Correct documentation errors

**Feature additions**:

- Add new configuration options
- Support additional platforms or versions
- Add new features

**Maintenance**:

- Update dependencies
- Improve error handling
- Optimize performance

### Making changes

1. **Identify the issue**: Reproduce the problem or identify the improvement needed
2. **Make focused changes**: Keep modifications minimal and targeted
3. **Maintain compatibility**: Ensure existing users aren't broken
4. **Add tests**: Test new features and edge cases
5. **Update documentation**: Reflect changes in the README

### Backward compatibility

When modifying existing modules:

- Add new variables with sensible defaults
- Don't remove existing variables without a migration path
- Don't change variable types or meanings
- Test that basic configurations still work

## Versioning

When you modify a module, update its version following semantic versioning:

- **Patch** (1.0.0 → 1.0.1): Bug fixes, documentation updates
- **Minor** (1.0.0 → 1.1.0): New features, new variables
- **Major** (1.0.0 → 2.0.0): Breaking changes, removing variables

Use the version bump script to update versions:

```bash
./.github/scripts/version-bump.sh patch|minor|major
```

## Submit your contribution

1. **Create a feature branch**:

   ```bash
   git checkout -b feat/modify-git-clone-module
   ```

2. **Test thoroughly**:

   ```bash
   bun test -t 'git-clone'
   bun fmt
   ```

3. **Commit with clear messages**:

   ```bash
   git add .
   git commit -m "feat(git-clone):add git-clone module"
   ```

4. **Open a pull request**:
   - Use a descriptive title
   - Explain what the module does and why it's useful
   - Reference any related issues

## Common issues and solutions

### Testing problems

**Issue**: Tests fail with network errors
**Solution**: Ensure Docker is running with `--network=host` support

### Module development

**Issue**: Icon not displaying
**Solution**: Verify icon path is correct and file exists in `.icons/` directory

### Documentation

**Issue**: Code blocks not syntax highlighted
**Solution**: Use `tf` language identifier for Terraform code blocks

## Get help

- **Examples**: Review existing modules like [`code-server`](https://registry.coder.com/modules/coder/code-server), [`git-clone`](https://registry.coder.com/modules/coder/git-clone), and [`jetbrains`](https://registry.coder.com/modules/coder/jetbrains)
- **Issues**: Open an issue at [github.com/coder/registry](https://github.com/coder/registry/issues)
- **Community**: Join the [Coder Discord](https://discord.gg/coder) for questions
- **Documentation**: Check the [Coder docs](https://coder.com/docs) for help on Coder.

## Next steps

After creating your first module:

1. **Share with the community**: Announce your module on Discord or social media
2. **Iterate based on feedback**: Improve based on user suggestions
3. **Create more modules**: Build a collection of related tools
4. **Contribute to existing modules**: Help maintain and improve the ecosystem

Happy contributing! 🚀

---

# Templates

Source: https://coder.com/docs/about/contributing/templates

# Contributing templates

Learn how to create and contribute complete Coder workspace templates to the Coder Registry. Templates provide ready-to-use workspace configurations that users can deploy directly to create development environments.

## What are Coder templates

Coder templates are complete Terraform configurations that define entire workspace environments. Unlike modules (which are reusable components), templates provide full infrastructure definitions that include:

- Infrastructure setup (containers, VMs, cloud resources)
- Coder agent configuration
- Development tools and IDE integrations
- Networking and security settings
- Complete startup automation

Templates appear on the Coder Registry and can be deployed directly by users.

> [!TIP]
> If you use an AI coding assistant, the [coder-templates](https://github.com/coder/registry/blob/main/.agents/skills/coder-templates/SKILL.md) agent skill from the Coder Registry can guide you through creating and updating templates with best practices built-in.

## Prerequisites

Before contributing templates, ensure you have:

- Strong Terraform knowledge
- [Terraform installed](https://developer.hashicorp.com/terraform/install)
- [Coder CLI installed](https://coder.com/docs/install)
- Access to your target infrastructure platform (Docker, AWS, GCP, etc.)
- [Bun installed](https://bun.sh/docs/installation) (for tooling)

## Setup your development environment

1. **Fork and clone the repository**:

   ```bash
   git clone https://github.com/your-username/registry.git
   cd registry
   ```

2. **Install dependencies**:

   ```bash
   bun install
   ```

3. **Understand the structure**:

   ```text
   registry/[namespace]/
   ├── templates/       # Your templates
   ├── .images/         # Namespace avatar and screenshots
   └── README.md        # Namespace description
   ```

## Create your first template

### 1. Set up your namespace

If you're a new contributor, create your namespace directory:

```bash
mkdir -p registry/[your-username]
mkdir -p registry/[your-username]/.images
```

Add your namespace avatar by downloading your GitHub avatar and saving it as `avatar.png`:

```bash
curl -o registry/[your-username]/.images/avatar.png https://github.com/[your-username].png
```

Create your namespace README at `registry/[your-username]/README.md`:

```markdown
---
display_name: "Your Name"
bio: "Brief description of what you do"
github: "your-username"
avatar: "./.images/avatar.png"
linkedin: "https://www.linkedin.com/in/your-username"
website: "https://your-website.com"
support_email: "support@your-domain.com"
status: "community"
---

# Your Name

Brief description of who you are and what you do.
```

> [!NOTE]
> The `linkedin`, `website`, and `support_email` fields are optional and can be omitted or left empty if not applicable.

### 2. Create your template directory

Create a directory for your template:

```bash
mkdir -p registry/[your-username]/templates/[template-name]
cd registry/[your-username]/templates/[template-name]
```

### 3. Build your template

Create `main.tf` with your complete Terraform configuration:

```terraform
terraform {
  required_providers {
    coder = {
      source = "coder/coder"
    }
    docker = {
      source = "kreuzwerker/docker"
    }
  }
}

# Coder data sources
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

# Coder agent
resource "coder_agent" "main" {
  arch                   = "amd64"
  os                     = "linux"
  startup_script_timeout = 180
  startup_script = <<-EOT
    set -e

    # Install development tools
    sudo apt-get update
    sudo apt-get install -y curl wget git

    # Additional setup here
  EOT
}

# Registry modules for IDEs and tools
module "code-server" {
  source   = "registry.coder.com/coder/code-server/coder"
  version  = "~> 1.0"
  agent_id = coder_agent.main.id
}

module "git-clone" {
  source   = "registry.coder.com/coder/git-clone/coder"
  version  = "~> 1.0"
  agent_id = coder_agent.main.id
  url      = "https://github.com/example/repo.git"
}

# Infrastructure resources
resource "docker_image" "main" {
  name = "codercom/enterprise-base:ubuntu"
}

resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = docker_image.main.name
  name  = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"

  command = ["sh", "-c", coder_agent.main.init_script]
  env     = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]

  host {
    host = "host.docker.internal"
    ip   = "host-gateway"
  }
}

# Metadata
resource "coder_metadata" "workspace_info" {
  count       = data.coder_workspace.me.start_count
  resource_id = docker_container.workspace[0].id

  item {
    key   = "memory"
    value = "4 GB"
  }

  item {
    key   = "cpu"
    value = "2 cores"
  }
}
```

### 4. Document your template

Create `README.md` with comprehensive documentation:

```markdown
---
display_name: "Ubuntu Development Environment"
description: "Complete Ubuntu workspace with VS Code, Git, and development tools"
icon: "../../../../.icons/ubuntu.svg"
verified: false
tags: ["ubuntu", "docker", "vscode", "git"]
---

# Ubuntu Development Environment

A complete Ubuntu-based development workspace with VS Code, Git, and essential development tools pre-installed.

## Features

- **Ubuntu 24.04 LTS** base image
- **VS Code** with code-server for browser-based development
- **Git** with automatic repository cloning
- **Node.js** and **npm** for JavaScript development
- **Python 3** with pip
- **Docker** for containerized development

## Requirements

- Docker runtime
- 4 GB RAM minimum
- 2 CPU cores recommended

## Usage

1. Deploy this template in your Coder instance
2. Create a new workspace from the template
3. Access VS Code through the workspace dashboard
4. Start developing in your fully configured environment

## Customization

You can customize this template by:

- Modifying the base image in `docker_image.main`
- Adding additional registry modules
- Adjusting resource allocations
- Including additional development tools

## Troubleshooting

**Issue**: Workspace fails to start
**Solution**: Ensure Docker is running and accessible

**Issue**: VS Code not accessible
**Solution**: Check agent logs and ensure code-server module is properly configured
```

## Template best practices

### Design principles

- **Complete environments**: Templates should provide everything needed for development
- **Platform-specific**: Focus on one platform or use case per template
- **Production-ready**: Include proper error handling and resource management
- **User-friendly**: Provide clear documentation and sensible defaults

### Infrastructure setup

- **Resource efficiency**: Use appropriate resource allocations
- **Network configuration**: Ensure proper connectivity for development tools
- **Security**: Follow security best practices for your platform
- **Scalability**: Design for multiple concurrent users

### Module integration

Use registry modules for common features:

```terraform
# VS Code in browser
module "code-server" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/code-server/coder"
  version  = "1.3.0"
  agent_id = coder_agent.example.id
}

# JetBrains IDEs
module "jetbrains" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/jetbrains/coder"
  version  = "1.0.0"
  agent_id = coder_agent.example.id
  folder   = "/home/coder/project"
}

# Git repository cloning
module "git-clone" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/git-clone/coder"
  version  = "1.1.0"
  agent_id = coder_agent.example.id
  url      = "https://github.com/coder/coder"
  base_dir = "~/projects/coder"
}

# File browser interface
module "filebrowser" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/filebrowser/coder"
  version  = "1.1.1"
  agent_id = coder_agent.example.id
}

# Dotfiles management
module "dotfiles" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/dotfiles/coder"
  version  = "1.2.0"
  agent_id = coder_agent.example.id
}
```

### Variables

Provide meaningful customization options:

```terraform
variable "git_repo_url" {
  description = "Git repository to clone"
  type        = string
  default     = ""
}

variable "instance_type" {
  description = "Instance type for the workspace"
  type        = string
  default     = "t3.medium"
}

variable "workspace_name" {
  description = "Name for the workspace"
  type        = string
  default     = "dev-workspace"
}
```

## Test your template

### Local testing

Test your template locally with Coder:

```bash
# Navigate to your template directory
cd registry/[your-username]/templates/[template-name]

# Push to Coder for testing
coder templates push test-template -d .

# Create a test workspace
coder create test-workspace --template test-template
```

### Validation checklist

Before submitting your template, verify:

- [ ] Template provisions successfully
- [ ] Agent connects properly
- [ ] All registry modules work correctly
- [ ] VS Code/IDEs are accessible
- [ ] Networking functions properly
- [ ] Resource metadata is accurate
- [ ] Documentation is complete and accurate

## Contribute to existing templates

### Types of improvements

**Bug fixes**:

- Fix setup issues
- Resolve agent connectivity problems
- Correct resource configurations

**Feature additions**:

- Add new registry modules
- Include additional development tools
- Improve startup automation

**Platform updates**:

- Update base images or AMIs
- Adapt to new platform features
- Improve security configurations

**Documentation improvements**:

- Clarify setup requirements
- Add troubleshooting guides
- Improve usage examples

### Making changes

1. **Test thoroughly**: Always test template changes in a Coder instance
2. **Maintain compatibility**: Ensure existing workspaces continue to function
3. **Document changes**: Update the README with new features or requirements
4. **Follow versioning**: Update version numbers for significant changes
5. **Modernize**: Use latest provider versions, best practices, and current software versions

## Submit your contribution

1. **Create a feature branch**:

   ```bash
   git checkout -b feat/add-python-template
   ```

2. **Test thoroughly**:

   ```bash
   # Test with Coder
   coder templates push test-python-template -d .
   coder create test-workspace --template test-python-template

   # Format code
   bun fmt
   ```

3. **Commit with clear messages**:

   ```bash
   git add .
   git commit -m "Add Python development template with FastAPI setup"
   ```

4. **Open a pull request**:
   - Use a descriptive title
   - Explain what the template provides
   - Include testing instructions
   - Reference any related issues

## Template examples

### Docker-based template

```terraform
# Simple Docker template
resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = "ubuntu:24.04"
  name  = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"

  command = ["sh", "-c", coder_agent.main.init_script]
  env     = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
}
```

### AWS EC2 template

```terraform
# AWS EC2 template
resource "aws_instance" "workspace" {
  count         = data.coder_workspace.me.start_count
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  user_data = coder_agent.main.init_script

  tags = {
    Name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
  }
}
```

### Kubernetes template

```terraform
# Kubernetes template
resource "kubernetes_pod" "workspace" {
  count = data.coder_workspace.me.start_count

  metadata {
    name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
  }

  spec {
    container {
      name  = "workspace"
      image = "ubuntu:24.04"

      command = ["sh", "-c", coder_agent.main.init_script]
      env {
        name  = "CODER_AGENT_TOKEN"
        value = coder_agent.main.token
      }
    }
  }
}
```

## Common issues and solutions

### Template development

**Issue**: Template fails to create resources
**Solution**: Check Terraform syntax and provider configuration

**Issue**: Agent doesn't connect
**Solution**: Verify agent token and network connectivity

### Documentation

**Issue**: Icon not displaying
**Solution**: Verify icon path and file existence

### Platform-specific

**Issue**: Docker containers not starting
**Solution**: Verify Docker daemon is running and accessible

**Issue**: Cloud resources failing
**Solution**: Check credentials and permissions

## Get help

- **Examples**: Review real-world examples from the [official Coder templates](https://registry.coder.com/contributors/coder?tab=templates):
  - [AWS EC2 (Devcontainer)](https://registry.coder.com/templates/aws-devcontainer) - AWS EC2 VMs with Envbuilder
  - [Docker (Devcontainer)](https://registry.coder.com/templates/docker-devcontainer) - Docker-in-Docker with Dev Containers integration
  - [Kubernetes (Devcontainer)](https://registry.coder.com/templates/kubernetes-devcontainer) - Kubernetes pods with Envbuilder
  - [Docker Containers](https://registry.coder.com/templates/docker) - Basic Docker container workspaces
  - [AWS EC2 (Linux)](https://registry.coder.com/templates/aws-linux) - AWS EC2 VMs for Linux development
  - [Google Compute Engine (Linux)](https://registry.coder.com/templates/gcp-vm-container) - GCP VM instances
  - [Scratch](https://registry.coder.com/templates/scratch) - Minimal starter template
- **Modules**: Browse available modules at [registry.coder.com/modules](https://registry.coder.com/modules)
- **Issues**: Open an issue at [github.com/coder/registry](https://github.com/coder/registry/issues)
- **Community**: Join the [Coder Discord](https://discord.gg/coder) for questions
- **Documentation**: Check the [Coder docs](https://coder.com/docs) for template guidance

## Next steps

After creating your first template:

1. **Share with the community**: Announce your template on Discord or social media
2. **Gather feedback**: Iterate based on user suggestions and issues
3. **Create variations**: Build templates for different use cases or platforms
4. **Contribute to existing templates**: Help maintain and improve the ecosystem

Your templates help developers get productive faster by providing ready-to-use development environments. Happy contributing! 🚀

---

# Backend

Source: https://coder.com/docs/about/contributing/backend

# Backend

This guide is designed to support both Coder engineers and community contributors in understanding our backend systems and getting started with development.

Coder’s backend powers the core infrastructure behind workspace provisioning, access control, and the overall developer experience. As the backbone of our platform, it plays a critical role in enabling reliable and scalable remote development environments.

The purpose of this guide is to help you:

* Understand how the various backend components fit together.
* Navigate the codebase with confidence and adhere to established best practices.
* Contribute meaningful changes - whether you're fixing bugs, implementing features, or reviewing code.

Need help or have questions? Join the conversation on our [Discord server](https://discord.com/invite/coder) — we’re always happy to support contributors.

## Platform Architecture

To understand how the backend fits into the broader system, we recommend reviewing the following resources:

* [General Concepts](../../admin/infrastructure/validated-architectures/index.md#general-concepts): Essential concepts and language used to describe how Coder is structured and operated.

* [Architecture](../../admin/infrastructure/architecture.md): A high-level overview of the infrastructure layout, key services, and how components interact.

These sections provide the necessary context for navigating and contributing to the backend effectively.

## Tech Stack

Coder's backend is built using a collection of robust, modern Go libraries and internal packages. Familiarity with these technologies will help you navigate the codebase and contribute effectively.

### Core Libraries & Frameworks

* [go-chi/chi](https://github.com/go-chi/chi): lightweight HTTP router for building RESTful APIs in Go
* [golang-migrate/migrate](https://github.com/golang-migrate/migrate): manages database schema migrations across environments
* [coder/terraform-config-inspect](https://github.com/coder/terraform-config-inspect) *(forked)*: used for parsing and analyzing Terraform configurations, forked to include [PR #74](https://github.com/hashicorp/terraform-config-inspect/pull/74)
* [coder/pq](https://github.com/coder/pq) *(forked)*: PostgreSQL driver forked to support rotating authentication tokens via `driver.Connector`
* [coder/tailscale](https://github.com/coder/tailscale) *(forked)*: enables secure, peer-to-peer connectivity, forked to apply internal patches pending upstreaming
* [coder/wireguard-go](https://github.com/coder/wireguard-go) *(forked)*: WireGuard networking implementation, forked to fix a data race and adopt the latest gVisor changes
* [coder/ssh](https://github.com/coder/ssh) *(forked)*: customized SSH server based on `gliderlabs/ssh`, forked to include Tailscale-specific patches and avoid complex subpath dependencies
* [coder/bubbletea](https://github.com/coder/bubbletea) *(forked)*: terminal UI framework for CLI apps, forked to remove an `init()` function that interfered with web terminal output

### Coder libraries

* [coder/terraform-provider-coder](https://github.com/coder/terraform-provider-coder): official Terraform provider for managing Coder resources via infrastructure-as-code
* [coder/websocket](https://github.com/coder/websocket): minimal WebSocket library for real-time communication
* [coder/serpent](https://github.com/coder/serpent): CLI framework built on `cobra`, used for large, complex CLIs
* [coder/guts](https://github.com/coder/guts): generates TypeScript types from Go for shared type definitions
* [coder/wgtunnel](https://github.com/coder/wgtunnel): WireGuard tunnel server for secure backend networking

## Repository Structure

The Coder backend is organized into multiple packages and directories, each with a specific purpose. Here's a high-level overview of the most important ones:

* [agent](https://github.com/coder/coder/tree/main/agent): core logic of a workspace agent, supports DevContainers, remote SSH, startup/shutdown script execution. Protobuf definitions for DRPC communication with `coderd` are kept in [proto](https://github.com/coder/coder/tree/main/agent/proto).
* [cli](https://github.com/coder/coder/tree/main/cli): CLI interface for `coder` command built on [coder/serpent](https://github.com/coder/serpent). Input controls are defined in [cliui](https://github.com/coder/coder/tree/docs-backend-contrib-guide/cli/cliui), and [testdata](https://github.com/coder/coder/tree/docs-backend-contrib-guide/cli/testdata) contains golden files for common CLI calls
* [cmd](https://github.com/coder/coder/tree/main/cmd): entry points for CLI and services, including `coderd`
* [coderd](https://github.com/coder/coder/tree/main/coderd): the main API server implementation with [chi](https://github.com/go-chi/chi) endpoints
  * [audit](https://github.com/coder/coder/tree/main/coderd/audit): audit log logic, defines target resources, actions and extra fields
  * [autobuild](https://github.com/coder/coder/tree/main/coderd/autobuild): core logic of the workspace autobuild executor, periodically evaluates workspaces for next transition actions
  * [httpmw](https://github.com/coder/coder/tree/main/coderd/httpmw): HTTP middlewares mainly used to extract parameters from HTTP requests (e.g. current user, template, workspace, OAuth2 account, etc.) and storing them in the request context
  * [prebuilds](https://github.com/coder/coder/tree/main/coderd/prebuilds): common interfaces for prebuild workspaces, feature implementation is in [enterprise/prebuilds](https://github.com/coder/coder/tree/main/enterprise/coderd/prebuilds)
  * [provisionerdserver](https://github.com/coder/coder/tree/main/coderd/provisionerdserver): DRPC server for [provisionerd](https://github.com/coder/coder/tree/main/provisionerd) instances, used to validate and extract Terraform data and resources, and store them in the database.
  * [rbac](https://github.com/coder/coder/tree/main/coderd/rbac): RBAC engine for `coderd`, including authz layer, role definitions and custom roles. Built on top of [Open Policy Agent](https://github.com/open-policy-agent/opa) and Rego policies.
  * [telemetry](https://github.com/coder/coder/tree/main/coderd/telemetry): records a snapshot with various workspace data for telemetry purposes. Once recorded the reporter sends it to the configured telemetry endpoint.
  * [tracing](https://github.com/coder/coder/tree/main/coderd/tracing): extends telemetry with tracing data consistent with [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md)
  * [workspaceapps](https://github.com/coder/coder/tree/main/coderd/workspaceapps): core logic of a secure proxy to expose workspace apps deployed in a workspace
  * [wsbuilder](https://github.com/coder/coder/tree/main/coderd/wsbuilder): wrapper for business logic of creating a workspace build. It encapsulates all database operations required to insert a build record in a transaction.
* [database](https://github.com/coder/coder/tree/main/coderd/database): schema migrations, query logic, in-memory database, etc.
  * [db2sdk](https://github.com/coder/coder/tree/main/coderd/database/db2sdk): translation between database structures and [codersdk](https://github.com/coder/coder/tree/main/codersdk) objects used by coderd API.
  * [dbauthz](https://github.com/coder/coder/tree/main/coderd/database/dbauthz): AuthZ wrappers for database queries, ideally, every query should verify first if the accessor is eligible to see the query results.
  * [dbfake](https://github.com/coder/coder/tree/main/coderd/database/dbfake): helper functions to quickly prepare the initial database state for testing purposes (e.g. create N healthy workspaces and templates), operates on higher level than [dbgen](https://github.com/coder/coder/tree/main/coderd/database/dbgen)
  * [dbgen](https://github.com/coder/coder/tree/main/coderd/database/dbgen): helper functions to insert raw records to the database store, used for testing purposes
  * [dbmock](https://github.com/coder/coder/tree/main/coderd/database/dbmock): a store wrapper for database queries, useful to verify if the function has been called, used for testing purposes
  * [dbpurge](https://github.com/coder/coder/tree/main/coderd/database/dbpurge): simple wrapper for periodic database cleanup operations
  * [migrations](https://github.com/coder/coder/tree/main/coderd/database/migrations): an ordered list of up/down database migrations, use `./create_migration.sh my_migration_name` to modify the database schema
  * [pubsub](https://github.com/coder/coder/tree/main/coderd/database/pubsub): PubSub implementation using PostgreSQL and in-memory drop-in replacement
  * [queries](https://github.com/coder/coder/tree/main/coderd/database/queries): contains SQL files with queries, `sqlc` compiles them to [Go functions](https://github.com/coder/coder/blob/docs-backend-contrib-guide/coderd/database/queries.sql.go)
  * [sqlc.yaml](https://github.com/coder/coder/tree/main/coderd/database/sqlc.yaml): defines mappings between SQL types and custom Go structures
* [codersdk](https://github.com/coder/coder/tree/main/codersdk): user-facing API entities used by CLI and site to communicate with `coderd` endpoints
* [dogfood](https://github.com/coder/coder/tree/main/dogfood): Terraform definition of the dogfood cluster deployment
* [enterprise](https://github.com/coder/coder/tree/main/enterprise): enterprise-only features, notice similar file structure to repository root (`audit`, `cli`, `cmd`, `coderd`, etc.)
  * [coderd](https://github.com/coder/coder/tree/main/enterprise/coderd)
    * [prebuilds](https://github.com/coder/coder/tree/main/enterprise/coderd/prebuilds): core logic of prebuilt workspaces - reconciliation loop
* [provisioner](https://github.com/coder/coder/tree/main/provisioner): supported implementation of provisioners, Terraform and "echo" (for testing purposes)
* [provisionerd](https://github.com/coder/coder/tree/main/provisionerd): core logic of provisioner runner to interact provisionerd server, depending on a job acquired it calls template import, dry run or a workspace build
* [pty](https://github.com/coder/coder/tree/main/pty): terminal emulation for agent shell
* [support](https://github.com/coder/coder/tree/main/support): compile a support bundle with diagnostics
* [tailnet](https://github.com/coder/coder/tree/main/tailnet): core logic of Tailnet controller to maintain DERP maps, coordinate connections with agents and peers
* [vpn](https://github.com/coder/coder/tree/main/vpn): Coder Desktop (VPN) and tunneling components

## Testing

The Coder backend includes a rich suite of unit and end-to-end tests. A variety of helper utilities are used throughout the codebase to make testing easier, more consistent, and closer to real behavior.

### [clitest](https://github.com/coder/coder/tree/main/cli/clitest)

* Spawns an in-memory `serpent.Command` instance for unit testing
* Configures an authorized `codersdk` client
* Once a `serpent.Invocation` is created, tests can execute commands as if invoked by a real user

### [ptytest](https://github.com/coder/coder/tree/main/pty/ptytest)

* `ptytest` attaches to a `serpent.Invocation` and simulates TTY input/output
* `pty` provides matchers and "write" operations for interacting with pseudo-terminals

### [coderdtest](https://github.com/coder/coder/tree/main/coderd/coderdtest)

* Provides shortcuts to spin up an in-memory `coderd` instance
* Can start an embedded provisioner daemon
* Supports multi-user testing via `CreateFirstUser` and `CreateAnotherUser`
* Includes "busy wait" helpers like `AwaitTemplateVersionJobCompleted`
* [oidctest](https://github.com/coder/coder/tree/main/coderd/coderdtest/oidctest) can start a fake OIDC provider

### [testutil](https://github.com/coder/coder/tree/main/testutil)

* General-purpose testing utilities, including:
  * [chan.go](https://github.com/coder/coder/blob/main/testutil/chan.go): helpers for sending/receiving objects from channels (`TrySend`, `RequireReceive`, etc.)
  * [duration.go](https://github.com/coder/coder/blob/main/testutil/duration.go): set timeouts for test execution
  * [eventually.go](https://github.com/coder/coder/blob/main/testutil/eventually.go): repeatedly poll for a condition using a ticker
  * [port.go](https://github.com/coder/coder/blob/main/testutil/port.go): select a free random port
  * [prometheus.go](https://github.com/coder/coder/blob/main/testutil/prometheus.go): validate Prometheus metrics with expected values
  * [pty.go](https://github.com/coder/coder/blob/main/testutil/pty.go): read output from a terminal until a condition is met
  * [wait_buffer.go](https://github.com/coder/coder/blob/main/testutil/wait_buffer.go): thread-safe `io.Writer` that blocks until accumulated output contains a signal (`WaitFor`, `WaitForNth`, `WaitForCond`)

### [dbtestutil](https://github.com/coder/coder/tree/main/coderd/database/dbtestutil)

* Allows choosing between real and in-memory database backends for tests
* `WillUsePostgres` is useful for skipping tests in CI environments that don't run Postgres

### [quartz](https://github.com/coder/quartz/tree/main)

* Provides a mockable clock or ticker interface
* Allows manual time advancement
* Useful for testing time-sensitive or timeout-related logic

## Quiz

Try to find answers to these questions before jumping into implementation work — having a solid understanding of how Coder works will save you time and help you contribute effectively.

1. When you create a template, what does that do exactly?
2. When you create a workspace, what exactly happens?
3. How does the agent get the required information to run?
4. How are provisioner jobs run?

## Recipes

### Adding database migrations and fixtures

#### Database migrations

Database migrations are managed with
[`migrate`](https://github.com/golang-migrate/migrate).

To add new migrations, use the following command:

```shell
./coderd/database/migrations/create_migration.sh my name
/home/coder/src/coder/coderd/database/migrations/000070_my_name.up.sql
/home/coder/src/coder/coderd/database/migrations/000070_my_name.down.sql
```

Then write queries into the generated `.up.sql` and `.down.sql` files and commit
them into the repository. The down script should make a best-effort to retain as
much data as possible.

Run `make gen` to generate models.

#### Database fixtures (for testing migrations)

There are two types of fixtures that are used to test that migrations don't
break existing Coder deployments:

* Partial fixtures
  [`migrations/testdata/fixtures`](../../../coderd/database/migrations/testdata/fixtures)
* Full database dumps
  [`migrations/testdata/full_dumps`](../../../coderd/database/migrations/testdata/full_dumps)

Both types behave like database migrations (they also
[`migrate`](https://github.com/golang-migrate/migrate)). Their behavior mirrors
Coder migrations such that when migration number `000022` is applied, fixture
`000022` is applied afterwards.

Partial fixtures are used to conveniently add data to newly created tables so
that we can ensure that this data is migrated without issue.

Full database dumps are for testing the migration of fully-fledged Coder
deployments. These are usually done for a specific version of Coder and are
often fixed in time. A full database dump may be necessary when testing the
migration of multiple features or complex configurations.

To add a new partial fixture, run the following command:

```shell
./coderd/database/migrations/create_fixture.sh my fixture
/home/coder/src/coder/coderd/database/migrations/testdata/fixtures/000070_my_fixture.up.sql
```

Then add some queries to insert data and commit the file to the repo. See
[`000024_example.up.sql`](../../../coderd/database/migrations/testdata/fixtures/000024_example.up.sql)
for an example.

To create a full dump, run a fully fledged Coder deployment and use it to
generate data in the database. Then shut down the deployment and take a snapshot
of the database.

```shell
mkdir -p coderd/database/migrations/testdata/full_dumps/v0.12.2 && cd $_
pg_dump "postgres://coder@localhost:..." -a --inserts >000069_dump_v0.12.2.up.sql
```

Make sure sensitive data in the dump is desensitized, for instance names,
emails, OAuth tokens and other secrets. Then commit the dump to the project.

To find out what the latest migration for a version of Coder is, use the
following command:

```shell
git ls-files v0.12.2 -- coderd/database/migrations/*.up.sql
```

This helps in naming the dump (e.g. `000069` above).

---

# Frontend

Source: https://coder.com/docs/about/contributing/frontend

# Frontend

Welcome to the guide for contributing to the Coder frontend. Whether you’re part
of the community or a Coder team member, this documentation will help you get
started.

If you have any questions, feel free to reach out on our
[Discord server](https://discord.com/invite/coder), and we’ll be happy to assist
you.

## Running the UI

You can run the UI and access the Coder dashboard in two ways:

1. Build the UI pointing to an external Coder server:
   `CODER_HOST=https://mycoder.com pnpm dev` inside of the `site` folder. This
   is helpful when you are building something in the UI and already have the
   data on your deployed server.
2. Build the entire Coder server + UI locally: `./scripts/develop.sh` in the
   root folder. This is useful for contributing to features that are not
   deployed yet or that involve both the frontend and backend.

In both cases, you can access the dashboard on `http://localhost:8080`. If using
`./scripts/develop.sh` you can log in with the default credentials.

> [!NOTE]
> **Default Credentials:** `admin@coder.com` and `SomeSecurePassword!`.

## Tech Stack Overview

All our dependencies are described in `site/package.json`, but the following are
the most important.

- [React](https://reactjs.org/) for the UI framework
- [Typescript](https://www.typescriptlang.org/) to keep our sanity
- [Vite](https://vitejs.dev/) to build the project
- [react-router](https://reactrouter.com/en/main) for routing
- [TanStack Query](https://tanstack.com/query/v4/docs/react/overview) for
  fetching data
- [Vitest](https://vitest.dev/) for integration testing
- [Playwright](https://playwright.dev/) for end-to-end (E2E) testing
- [Storybook](https://storybook.js.org/) and
  [Chromatic](https://www.chromatic.com/) for visual testing
- [pnpm](https://pnpm.io/) as the package manager

## Structure

All UI-related code is in the `site` folder. Key directories include:

- **e2e** - End-to-end (E2E) tests
- **src** - Source code
  - **@types** - Custom types for dependencies that don't have defined types
    (largely code that has no server-side equivalent)
  - **api** - API function calls and types
    - **queries** - react-query queries and mutations
  - **components** - Reusable UI components without Coder specific business
    logic
  - **hooks** - Custom React hooks
  - **modules** - Coder specific logic and components related to multiple parts of the UI
  - **pages** - Page-level components
  - **testHelpers** - Helper functions for integration testing
  - **theme** - theme configuration and color definitions
  - **util** - Helper functions that can be used across the application
- **static** - Static assets like images, fonts, icons, etc

Do not use barrel files. Imports should be directly from the file that defines
the value.

## Routing

We use [react-router](https://reactrouter.com/en/main) as our routing engine.

- Authenticated routes - Place routes requiring authentication inside the
  `<RequireAuth>` route. The `RequireAuth` component handles all the
  authentication logic for the routes.
- Dashboard routes - routes that live in the dashboard should be placed under
  the `<DashboardLayout>` route. The `DashboardLayout` adds a navbar and passes
  down common dashboard data.

## Pages

Page components are the top-level components of the app and reside in the
`src/pages` folder. Each page should have its own folder to group relevant
views, tests, and utility functions. The page component fetches necessary data
and passes to the view. We explain this decision a bit better in the next
section which talks about where to fetch data.

If code within a page becomes reusable across other parts of the app,
consider moving it to `src/utils`, `hooks`, `components`, or `modules`.

### Handling States

A page typically has three states: **loading**, **ready**/**success**, and
**error**. Ensure you manage these states when developing pages. Use visual
tests for these states with `*.stories.ts` files.

## Data Fetching

We use [TanStack Query v4](https://tanstack.com/query/v4/docs/react/quick-start)
to fetch data from the API. Queries and mutation should be placed in the
api/queries folder.

### Where to fetch data

In the past, our approach involved creating separate components for page and
view, where the page component served as a container responsible for fetching
data and passing it down to the view.

For instance, when developing a page to display users, we would have a
`UsersPage` component with a corresponding `UsersPageView`. The `UsersPage`
would handle API calls, while the `UsersPageView` managed the presentational
logic.

Over time, however, we encountered challenges with this approach, particularly
in terms of excessive props drilling. To address this, we opted to fetch data in
proximity to its usage. Taking the example of displaying users, in the past, if
we were creating a header component for that page, we would have needed to fetch
the data in the page component and pass it down through the hierarchy
(`UsersPage -> UsersPageView -> UsersHeader`). Now, with libraries such as
`react-query`, data fetching can be performed directly in the `UsersHeader`
component, allowing UI elements to declare and consume their data-fetching
dependencies directly, while preventing duplicate server requests
([more info](https://github.com/TanStack/query/discussions/608#discussioncomment-29735)).

To simplify visual testing of scenarios where components are responsible for
fetching data, you can easily set the queries' value using `parameters.queries`
within the component's story.

```tsx
export const WithQuota: Story = {
    parameters: {
        queries: [
            {
                key: getWorkspaceQuotaQueryKey(MockUserOwner.username),
                data: {
                    credits_consumed: 2,
                    budget: 40,
                },
            },
        ],
    },
};
```

### API

Our project uses [axios](https://github.com/axios/axios) as the HTTP client for
making API requests. The API functions are centralized in `site/src/api/api.ts`.
Auto-generated TypeScript types derived from our Go server are located in
`site/src/api/typesGenerated.ts`.

Typically, each API endpoint corresponds to its own `Request` and `Response`
types. However, some endpoints require additional parameters for successful
execution. Here's an illustrative example:"

```ts
export const getAgentListeningPorts = async (
    agentID: string,
): Promise<TypesGen.ListeningPortsResponse> => {
    const response = await axiosInstance.get(
        `/api/v2/workspaceagents/${agentID}/listening-ports`,
    );
    return response.data;
};
```

Sometimes, a frontend operation can have multiple API calls which can be wrapped
as a single function.

```ts
export const updateWorkspaceVersion = async (
    workspace: TypesGen.Workspace,
): Promise<TypesGen.WorkspaceBuild> => {
    const template = await getTemplate(workspace.template_id);
    return startWorkspace(workspace.id, template.active_version_id);
};
```

## Components and Modules

Components should be atomic, reusable and free of business logic. Modules are
similar to components except that they can be more complex and can contain
business logic specific to the product.

### MUI

The codebase is currently using MUI v5. Please see the
[official documentation](https://mui.com/material-ui/getting-started/). In
general, favor building a custom component via MUI instead of plain React/HTML,
as MUI's suite of components is thoroughly battle-tested and accessible right
out of the box.

### Structure

Each component and module gets its own folder. Module folders may group multiple
files in a hierarchical structure. Storybook stories and component tests using
Storybook interactions are required. By keeping these tidy, the codebase will
remain easy to navigate, healthy and maintainable for all contributors.

### Accessibility

We strive to keep our UI accessible.

In general, colors should come from the app theme, but if there is a need to add
a custom color, please ensure that the foreground and background have a minimum
contrast ratio of 4.5:1 to meet WCAG level AA compliance. WebAIM has
[a great tool for checking your colors directly](https://webaim.org/resources/contrastchecker/),
but tools like
[Dequeue's axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd)
can also do automated checks in certain situations.

When using any kind of input element, always make sure that there is a label
associated with that element (the label can be made invisible for aesthetic
reasons, but it should always be in the HTML markup). Labels are important for
screen-readers; a placeholder text value is not enough for all users.

When possible, make sure that all image/graphic elements have accompanying text
that describes the image. `<img />` elements should have an `alt` text value. In
other situations, it might make sense to place invisible, descriptive text
inside the component itself using Tailwind's `sr-only` class.

```tsx
<Button>
    <GearIcon />
    <span className="sr-only">Settings</span>
</Button>;
```

### Should I create a new component or module?

Components could technically be used in any codebase and still feel at home. A
module would only make sense in the Coder codebase.

- Component
  - Simple
  - Atomic, used in multiple places
  - Generic, would be useful as a component outside of the Coder product
  - Good Examples: `Badge`, `Form`, `Timeline`
- Module
  - Simple or Complex
  - Used in multiple places
  - Good Examples: `Provisioner`, `DashboardLayout`, `DeploymentBanner`

Our codebase has some legacy components that are being updated to follow these
new conventions, but all new components should follow these guidelines.

## Styling

We use [Emotion](https://emotion.sh/) to handle CSS styles.

## Forms

We use [Formik](https://formik.org/docs) for forms along with
[Yup](https://github.com/jquense/yup) for schema definition and validation.

## Testing

We use three types of testing in our app: **End-to-end (E2E)**, **Integration/Unit**
and **Visual Testing**.

### End-to-End (E2E) – Playwright

These are useful for testing complete flows like "Create a user", "Import
template", etc. We use [Playwright](https://playwright.dev/). These tests run against a full Coder instance, backed by a database, and allows you to make sure that features work properly all the way through the stack. "End to end", so to speak.

For scenarios where you need to be authenticated as a certain user, you can use
`login` helper. Passing it some user credentials will log out of any other user account, and will attempt to login using those credentials.

For ease of debugging, it's possible to run a Playwright test in headful mode
running a Playwright server on your local machine, and executing the test inside
your workspace.

You can either run `scripts/remote_playwright.sh` from `coder/coder` on your
local machine, or execute the following command if you don't have the repo
available:

```bash
bash <(curl -sSL https://raw.githubusercontent.com/coder/coder/main/scripts/remote_playwright.sh) [workspace]
```

The `scripts/remote_playwright.sh` script will start a Playwright server on your
local machine and forward the necessary ports to your workspace. At the end of
the script, you will land _inside_ your workspace with environment variables set
so you can simply execute the test (`pnpm run playwright:test`).

### Integration/Unit

We use unit and integration tests mostly for testing code that does _not_ pertain to React. Functions and classes that contain notable app logic, and which are well abstracted from React should have accompanying tests. If the logic is tightly coupled to a React component, a Storybook test or an E2E test is usually a better option.

### Visual Testing – Storybook

We use Storybook for testing all of our React code. For static components, you simply add a story that renders the components with the props that you would like to test, and Storybook will record snapshots of it to ensure that it isn't changed unintentionally. If you would like to test an interaction with the component, then you can add an interaction test by specifying a `play` function for the story. For stories with an interaction test, a snapshot will be recorded of the end state of the component. We use
[Chromatic](https://www.chromatic.com/) to manage and compare snapshots in CI.

To learn more about testing components that fetch API data, refer to the
[**Where to fetch data**](#where-to-fetch-data) section.

### What should I test?

Choosing what to test is not always easy since there are a lot of flows and a
lot of things can happen but these are a few indicators that can help you with
that:

- Things that can block the user
- Reported bugs
- Regression issues

### Tests getting too slow

You may have observed that certain tests in our suite can be notably
time-consuming. Sometimes it is because the test itself is complex and sometimes
it is because of how the test is querying elements.

#### Using `ByRole` queries

One thing we figured out that was slowing down our tests was the use of `ByRole`
queries because of how it calculates the role attribute for every element on the
`screen`. You can read more about it on the links below:

- <https://stackoverflow.com/questions/69711888/react-testing-library-getbyrole-is-performing-extremely-slowly>
- <https://github.com/testing-library/dom-testing-library/issues/552#issuecomment-625172052>

Even with `ByRole` having performance issues we still want to use it but for
that, we have to scope the "querying" area by using the `within` command. So
instead of using `screen.getByRole("button")` directly we could do
`within(form).getByRole("button")`.

❌ Not ideal. If the screen has a hundred or thousand elements it can be VERY
slow.

```tsx
user.click(screen.getByRole("button"));
```

✅ Better. We can limit the number of elements we are querying.

```tsx
const form = screen.getByTestId("form");
user.click(within(form).getByRole("button"));
```

---

# Security

Source: https://coder.com/docs/about/contributing/SECURITY

# Security Policy

Coder welcomes feedback from security researchers and the general public to help improve our security.
If you believe you have discovered a vulnerability, privacy issue, exposed data, or other security issues
in any of our assets, we want to hear from you.

If you find a vulnerability, **DO NOT FILE AN ISSUE**.
Instead, send an email to
<security@coder.com>.

Refer to the [Security policy](https://coder.com/security/policy) for more information.

---

# AI Contribution Guidelines

Source: https://coder.com/docs/about/contributing/AI_CONTRIBUTING

# AI Contribution Guidelines

This document defines rules for contributions where an AI system is the primary author of the code (i.e., most of the pull request was generated by AI).
It applies to all Coder repositories and is a supplement to the [existing contributing guidelines](./CONTRIBUTING.md), not a replacement.

For minor AI-assisted edits, suggestions, or completions where the human contributor is clearly the primary author, these rules do not apply — standard contributing guidelines are sufficient.

## Disclosure

Contributors must **disclose AI involvement** in the pull request description whenever these guidelines apply.

## Human Ownership & Attribution

- All pull requests must be opened under **user accounts linked to a human**, and not an application ("bot account").
- Contributors are personally accountable for the content of their PRs, regardless of how it was generated.

## Verification & Evidence

All AI-assisted contributions require **manual verification**.
Contributions without verification evidence will be rejected.

- Test your changes yourself. Don’t assume AI is correct.
- Provide screenshots showing that the change works as intended.
  - For visual/UI changes: include before/after screenshots.
  - For CLI or backend changes: include terminal or api output.

## Why These Rules Exist

Traditionally, maintainers assumed that producing a pull request required more effort than reviewing it.
With AI-assisted tools, the balance has shifted: generating code is often faster than reviewing it.

Our guidelines exist to safeguard maintainers’ time, uphold contributor accountability, and preserve the overall quality of the project.

---

# Install

Source: https://coder.com/docs/install

# Installing Coder

A single CLI (`coder`) is used for both the Coder server and the client.

We support two release channels: mainline and stable - read the
[Releases](./releases/index.md) page to learn more about which best suits your team.

There are several ways to install Coder. Follow the steps on this page for a
minimal installation of Coder, or for a step-by-step guide on how to install and
configure your first Coder deployment, follow the
[quickstart guide](../tutorials/quickstart.md).

## Local/Individual Installs

This install guide is meant for **individual developers, small teams, and/or open source community members** setting up Coder locally or on a single server. It covers the light weight install for Linux, macOS, and Windows.

<div class="tabs">

## Linux/macOS

Our install script is the fastest way to install Coder on Linux/macOS:

```sh
curl -L https://coder.com/install.sh | sh
```

Refer to [GitHub releases](https://github.com/coder/coder/releases) for
alternate installation methods (e.g. standalone binaries, system packages).

## Windows

If you plan to use the built-in PostgreSQL database, ensure that the
[Visual C++ Runtime](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist#latest-microsoft-visual-c-redistributable-version)
is installed.

Use [GitHub releases](https://github.com/coder/coder/releases) to download the
Windows installer (`.msi`) or standalone binary (`.exe`).

![Windows setup wizard](../images/install/windows-installer.png)

Alternatively, you can use the
[`winget`](https://learn.microsoft.com/en-us/windows/package-manager/winget/#use-winget)
package manager to install Coder:

```powershell
winget install Coder.Coder
```

</div>

## Hosted/Enterprise Installs

This install guide is meant for **IT Administrators, DevOps, and Platform Teams** deploying Coder for an organization. It covers production-grade, multi-user installs on Kubernetes and other hosted platforms.

<div>

<children></children>

</div>

## Starting the Coder Server

To start the Coder server:

```sh
coder server
```

![Coder install](../images/screenshots/welcome-create-admin-user.png)

To log in to an existing Coder deployment:

```sh
coder login https://coder.example.com
```

---

# Coder CLI

Source: https://coder.com/docs/install/cli

# Installing Coder

A single CLI (`coder`) is used for both the Coder server and the client.

We support two release channels: mainline and stable - read the
[Releases](./releases/index.md) page to learn more about which best suits your team.

## Download the latest release from GitHub

<div class="tabs">

## Linux/macOS

Our install script is the fastest way to install Coder on Linux/macOS:

```sh
curl -L https://coder.com/install.sh | sh
```

Refer to [GitHub releases](https://github.com/coder/coder/releases) for
alternate installation methods (e.g. standalone binaries, system packages).

## Windows

If you plan to use the built-in PostgreSQL database, ensure that the
[Visual C++ Runtime](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist#latest-microsoft-visual-c-redistributable-version)
is installed.

Use [GitHub releases](https://github.com/coder/coder/releases) to download the
Windows installer (`.msi`) or standalone binary (`.exe`).

![Windows setup wizard](../images/install/windows-installer.png)

Alternatively, you can use the
[`winget`](https://learn.microsoft.com/en-us/windows/package-manager/winget/#use-winget)
package manager to install Coder:

```powershell
winget install Coder.Coder
```

</div>

To start the Coder server:

```sh
coder server
```

![Coder install](../images/screenshots/welcome-create-admin-user.png)

To log in to an existing Coder deployment:

```sh
coder login https://coder.example.com
```

## Download the CLI from your deployment

> [!NOTE]
> Available in Coder 2.19 and newer on macOS and Linux clients only.

Every Coder server hosts CLI binaries for all supported platforms. You can run a
script to download the appropriate CLI for your machine from your Coder
deployment.

![Install Coder binary from your deployment](../images/install/install_from_deployment.png)

This script works within air-gapped deployments and ensures that the version of
the CLI you have installed on your machine matches the version of the server.

This script can be useful when authoring a template for installing the CLI.

### Next up

- [Create your first template](../tutorials/template-from-scratch.md)
- [Control plane configuration](../admin/setup/index.md)

---

# Docker

Source: https://coder.com/docs/install/docker

# Install Coder via Docker

You can install and run Coder using the official Docker images published on
[GitHub Container Registry](https://github.com/coder/coder/pkgs/container/coder).

## Requirements

- Docker. See the
  [official installation documentation](https://docs.docker.com/install/).

- A Linux machine. For macOS devices, start Coder using the
  [standalone binary](./cli.md).

- 2 CPU cores and 4 GB memory free on your machine.

<div class="tabs">

## Install Coder via `docker compose`

Coder publishes a
[docker compose example](https://github.com/coder/coder/blob/main/compose.yaml)
which includes a PostgreSQL container and volume.

1. Make sure you have [Docker Compose](https://docs.docker.com/compose/install/)
   installed.

1. Download the
   [`docker-compose.yaml`](https://github.com/coder/coder/blob/main/compose.yaml)
   file.

1. Update `group_add:` in `docker-compose.yaml` with the `gid` of `docker`
   group. You can get the `docker` group `gid` by running the below command:

   ```shell
   getent group docker | cut -d: -f3
   ```

1. Start Coder with `docker compose up`

1. Visit the web UI via the configured url.

1. Follow the on-screen instructions log in and create your first template and
   workspace

Coder configuration is defined via environment variables. Learn more about
Coder's [configuration options](../admin/setup/index.md).

## Install Coder via `docker run`

### Built-in database (quick)

For proof-of-concept deployments, you can run a complete Coder instance with the
following command.

```shell
export CODER_DATA=$HOME/.config/coderv2-docker
export DOCKER_GROUP=$(getent group docker | cut -d: -f3)
mkdir -p $CODER_DATA
docker run --rm -it \
  -v $CODER_DATA:/home/coder/.config \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --group-add $DOCKER_GROUP \
  ghcr.io/coder/coder:latest
```

### External database (recommended)

For production deployments, we recommend using an external PostgreSQL database
(version 13 or higher). Set `CODER_ACCESS_URL` to the external URL that users
and workspaces will use to connect to Coder.

```shell
export DOCKER_GROUP=$(getent group docker | cut -d: -f3)
docker run --rm -it \
  -e CODER_ACCESS_URL="https://coder.example.com" \
  -e CODER_PG_CONNECTION_URL="postgresql://username:password@database/coder" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --group-add $DOCKER_GROUP \
  ghcr.io/coder/coder:latest
```

</div>

## Install the preview release

> [!TIP]
> We do not recommend using preview releases in production environments.

You can install and test a
[preview release of Coder](https://github.com/coder/coder/pkgs/container/coder-preview)
by using the `coder-preview:latest` image tag.
This image is automatically updated with the latest changes from the `main` branch.

Replace `ghcr.io/coder/coder:latest` in the `docker run` command in the
[steps above](#install-coder-via-docker-run) with `ghcr.io/coder/coder-preview:latest`.

## Troubleshooting

### Cannot connect to the Docker daemon

If you see an error like:

```text
Error: Error pinging Docker server: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

Docker is not installed or not running on the host. Install Docker and start the
daemon before creating a workspace from a Docker-based template. Refer to the
[quickstart troubleshooting](../tutorials/quickstart.md#cannot-connect-to-the-docker-daemon)
for platform-specific steps.

### Docker-based workspace is stuck in "Connecting..."

Ensure you have an externally-reachable `CODER_ACCESS_URL` set. See
[troubleshooting templates](../admin/templates/troubleshooting.md) for more
steps.

### Permission denied while trying to connect to the Docker daemon socket

See Docker's official documentation to
[Manage Docker as a non-root user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)

### I cannot add Docker templates

Coder runs as a non-root user, we use `--group-add` to ensure Coder has
permissions to manage Docker via `docker.sock`. If the host systems
`/var/run/docker.sock` is not group writable or does not belong to the `docker`
group, the above may not work as-is.

### I cannot add cloud-based templates

In order to use cloud-based templates (e.g. Kubernetes, AWS), you must have an
external URL that users and workspaces will use to connect to Coder. For
proof-of-concept deployments, you can use
[Coder's tunnel](../admin/setup/index.md#tunnel). For production deployments, we
recommend setting an [access URL](../admin/setup/index.md#access-url)

## Next steps

- [Create your first template](../tutorials/template-from-scratch.md)
- [Control plane configuration](../admin/setup/index.md#configure-control-plane-access)

---

# Kubernetes

Source: https://coder.com/docs/install/kubernetes

# Install Coder on Kubernetes

You can install Coder on Kubernetes (K8s) using Helm. We run on most Kubernetes
distributions, including [OpenShift](./openshift.md).

## Requirements

- Kubernetes cluster running K8s 1.19+
- [Helm](https://helm.sh/docs/intro/install/) 3.5+ installed on your local
  machine

## 1. Create a namespace

Create a namespace for the Coder control plane. In this tutorial, we'll call it
`coder`.

```sh
kubectl create namespace coder
```

## 2. Create a PostgreSQL instance

Coder does not manage a database server for you. This is required for storing
data about your Coder deployment and resources.

### Managed PostgreSQL (recommended)

If you're in a public cloud such as
[Google Cloud](https://cloud.google.com/sql/docs/postgres/),
[AWS](https://aws.amazon.com/rds/postgresql/),
[Azure](https://docs.microsoft.com/en-us/azure/postgresql/), or
[DigitalOcean](https://www.digitalocean.com/products/managed-databases-postgresql),
you can use the managed PostgreSQL offerings they provide. Make sure that the
PostgreSQL service is running and accessible from your cluster. It should be in
the same network, same project, etc.

### In-Cluster PostgreSQL (for proof of concepts)

You can install Postgres manually on your cluster using the
[Bitnami PostgreSQL Helm chart](https://github.com/bitnami/charts/tree/master/bitnami/postgresql#readme).
There are some [helpful guides](https://phoenixnap.com/kb/postgresql-kubernetes)
on the internet that explain sensible configurations for this chart. Example:

```console
# Install PostgreSQL
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install postgresql bitnami/postgresql \
    --namespace coder \
    --set image.repository=bitnamilegacy/postgresql \
    --set auth.username=coder \
    --set auth.password=coder \
    --set auth.database=coder \
    --set primary.persistence.size=10Gi
```

The cluster-internal DB URL for the above database is:

```shell
postgres://coder:coder@postgresql.coder.svc.cluster.local:5432/coder?sslmode=disable
```

You can optionally use the
[Postgres operator](https://github.com/zalando/postgres-operator) to manage
PostgreSQL deployments on your Kubernetes cluster.

## 3. Create the PostgreSQL secret

Create a secret with the PostgreSQL database URL string. In the case of the
self-managed PostgreSQL, the address will be:

```sh
kubectl create secret generic coder-db-url -n coder \
  --from-literal=url="postgres://coder:coder@postgresql.coder.svc.cluster.local:5432/coder?sslmode=disable"
```

## 4. Install Coder with Helm

```shell
helm repo add coder-v2 https://helm.coder.com/v2
```

Create a `values.yaml` with the configuration settings you'd like for your
deployment. For example:

```yaml
coder:
  # You can specify any environment variables you'd like to pass to Coder
  # here. Coder consumes environment variables listed in
  # `coder server --help`, and these environment variables are also passed
  # to the workspace provisioner (so you can consume them in your Terraform
  # templates for auth keys etc.).
  #
  # Please keep in mind that you should not set `CODER_HTTP_ADDRESS`,
  # `CODER_TLS_ENABLE`, `CODER_TLS_CERT_FILE` or `CODER_TLS_KEY_FILE` as
  # they are already set by the Helm chart and will cause conflicts.
  env:
    - name: CODER_PG_CONNECTION_URL
      valueFrom:
        secretKeyRef:
          # You'll need to create a secret called coder-db-url with your
          # Postgres connection URL like:
          # postgres://coder:password@postgres:5432/coder?sslmode=disable
          name: coder-db-url
          key: url
    # For production deployments, we recommend configuring your own GitHub
    # OAuth2 provider and disabling the default one.
    - name: CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE
      value: "false"

    # (Optional) For production deployments the access URL should be set.
    # If you're just trying Coder, access the dashboard via the service IP.
    # - name: CODER_ACCESS_URL
    #   value: "https://coder.example.com"

  #tls:
  #  secretNames:
  #    - my-tls-secret-name
```

You can view our
[Helm README](https://github.com/coder/coder/blob/main/helm/coder#readme) for
details on the values that are available, or you can view the
[values.yaml](https://github.com/coder/coder/blob/main/helm/coder/values.yaml)
file directly.

We support two release channels: mainline and stable - read the
[Releases](./releases/index.md) page to learn more about which best suits your team.

- **Mainline** Coder release:

  - **Chart Registry**
    <!-- autoversion(mainline): "--version [version]" -->

    ```shell
    helm install coder coder-v2/coder \
        --namespace coder \
        --values values.yaml \
        --version 2.30.0
    ```

  - **OCI Registry**

    <!-- autoversion(mainline): "--version [version]" -->

    ```shell
    helm install coder oci://ghcr.io/coder/chart/coder \
        --namespace coder \
        --values values.yaml \
        --version 2.30.0
    ```

- **Stable** Coder release:

  - **Chart Registry**

    <!-- autoversion(stable): "--version [version]" -->

    ```shell
    helm install coder coder-v2/coder \
        --namespace coder \
        --values values.yaml \
        --version 2.29.5
    ```

  - **OCI Registry**

    <!-- autoversion(stable): "--version [version]" -->

    ```shell
    helm install coder oci://ghcr.io/coder/chart/coder \
        --namespace coder \
        --values values.yaml \
        --version 2.29.5
    ```

You can watch Coder start up by running `kubectl get pods -n coder`. Once Coder
has started, the `coder-*` pods should enter the `Running` state.

## 5. Log in to Coder 🎉

Use `kubectl get svc -n coder` to get the IP address of the LoadBalancer. Visit
this in the browser to set up your first account.

If you do not have a domain, you should set `CODER_ACCESS_URL` to this URL in
the Helm chart and upgrade Coder (see below). This allows workspaces to connect
to the proper Coder URL.

## Upgrading Coder via Helm

To upgrade Coder in the future or change values, you can run the following
command:

```shell
helm repo update
helm upgrade coder coder-v2/coder \
  --namespace coder \
  -f values.yaml
```

## Coder Observability Chart

Use the [Observability Helm chart](https://github.com/coder/observability) for a
pre-built set of dashboards to monitor your control plane over time. It includes
Grafana, Prometheus, Loki, and Alert Manager out-of-the-box, and can be deployed
on your existing Grafana instance.

We recommend that all administrators deploying on Kubernetes set the
observability bundle up with the control plane from the start. For installation
instructions, visit the
[observability repository](https://github.com/coder/observability?tab=readme-ov-file#installation).

## Kubernetes Security Reference

Below are common requirements we see from our enterprise customers when
deploying an application in Kubernetes. This is intended to serve as a
reference, and not all security requirements may apply to your business.

1. **All container images must be sourced from an internal container registry.**

   - Control plane - To pull the control plane image from the appropriate
     registry,
     [update this Helm chart value](https://github.com/coder/coder/blob/f57ce97b5aadd825ddb9a9a129bb823a3725252b/helm/coder/values.yaml#L43-L50).
   - Workspaces - To pull the workspace image from your registry,
     [update the Terraform template code here](https://github.com/coder/coder/blob/f57ce97b5aadd825ddb9a9a129bb823a3725252b/examples/templates/kubernetes/main.tf#L271).
     This assumes your cluster nodes are authenticated to pull from the internal
     registry.

2. **All containers must run as non-root user**

   - Control plane - Our control plane pod
     [runs as non-root by default](https://github.com/coder/coder/blob/f57ce97b5aadd825ddb9a9a129bb823a3725252b/helm/coder/values.yaml#L124-L127).
   - Workspaces - Workspace pod UID is
     [set in the Terraform template here](https://github.com/coder/coder/blob/f57ce97b5aadd825ddb9a9a129bb823a3725252b/examples/templates/kubernetes/main.tf#L274-L276),
     and are not required to run as `root`.

3. **Containers cannot run privileged**

   - Coder's control plane does not run as privileged.
     [We disable](https://github.com/coder/coder/blob/f57ce97b5aadd825ddb9a9a129bb823a3725252b/helm/coder/values.yaml#L141)
     `allowPrivilegeEscalation`
     [by default](https://github.com/coder/coder/blob/f57ce97b5aadd825ddb9a9a129bb823a3725252b/helm/coder/values.yaml#L141).
   - Workspace pods do not require any elevated privileges, with the exception
     of our `envbox` workspace template (used for docker-in-docker workspaces,
     not required).

4. **Containers cannot mount host filesystems**

   - Both the control plane and workspace containers do not require any host
     filesystem mounts.

5. **Containers cannot attach to host network**

   - Both the control plane and workspaces use the Kubernetes networking layer
     by default, and do not require host network access.

6. **All Kubernetes objects must define resource requests/limits**

   - Both the control plane and workspaces set resource request/limits by
     default.

## Load balancing considerations

### AWS

If you are deploying Coder on AWS EKS and service is set to `LoadBalancer`, AWS
will default to the Classic load balancer. The load balancer external IP will be
stuck in a pending status unless sessionAffinity is set to None.

```yaml
coder:
  service:
    type: LoadBalancer
    sessionAffinity: None
```

AWS recommends a Network load balancer in lieu of the Classic load balancer. Use
the following `values.yaml` settings to request a Network load balancer:

```yaml
coder:
  service:
    externalTrafficPolicy: Local
    sessionAffinity: None
    annotations: { service.beta.kubernetes.io/aws-load-balancer-type: "nlb" }
```

By default, Coder will set the `externalTrafficPolicy` to `Cluster` which will
mask client IP addresses in the Audit log. To preserve the source IP, you can
either set this value to `Local`, or pass through the client IP via the
X-Forwarded-For header. To configure the latter, set the following environment
variables:

```yaml
coder:
  env:
    - name: CODER_PROXY_TRUSTED_HEADERS
      value: X-Forwarded-For
    - name: CODER_PROXY_TRUSTED_ORIGINS
      value: 10.0.0.1/8 # this will be the CIDR range of your Load Balancer IP address
```

### Azure

Certain enterprise environments require the
[Azure Application Gateway](https://learn.microsoft.com/en-us/azure/application-gateway/ingress-controller-overview).
The Application Gateway supports:

- Websocket traffic (required for workspace connections)
- TLS termination

Follow our doc on
[how to deploy Coder on Azure with an Application Gateway](./kubernetes/kubernetes-azure-app-gateway.md)
for an example.

## Troubleshooting

You can view Coder's logs by getting the pod name from `kubectl get pods` and
then running `kubectl logs <pod name>`. You can also view these logs in your
Cloud's log management system if you are using managed Kubernetes.

### Kubernetes-based workspace is stuck in "Connecting..."

Ensure you have an externally-reachable `CODER_ACCESS_URL` set in your helm
chart. If you do not have a domain set up, this should be the IP address of
Coder's LoadBalancer (`kubectl get svc -n coder`).

See [troubleshooting templates](../admin/templates/troubleshooting.md) for more
steps.

## Next steps

- [Create your first template](../tutorials/template-from-scratch.md)
- [Control plane configuration](../admin/setup/index.md)

---

# Deploy Coder on Azure with an Application Gateway

Source: https://coder.com/docs/install/kubernetes/kubernetes-azure-app-gateway

# Deploy Coder on Azure with an Application Gateway

In certain enterprise environments, the [Azure Application Gateway](https://learn.microsoft.com/en-us/azure/application-gateway/ingress-controller-overview) is required.

These steps serve as a proof-of-concept example so that you can get Coder running with Kubernetes on Azure. Your deployment might require a separate Postgres server or signed certificates.

The Application Gateway supports:

- Websocket traffic (required for workspace connections)
- TLS termination

Refer to Microsoft's documentation on how to [enable application gateway ingress controller add-on for an existing AKS cluster with an existing application gateway](https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-existing).
The steps here follow the Microsoft tutorial for a Coder deployment.

## Deploy Coder on Azure with an Application Gateway

1. Create Azure resource group:

   ```sql
   az group create --name myResourceGroup --location eastus
   ```

1. Create AKS cluster:

   ```sql
   az aks create --name myCluster --resource-group myResourceGroup --network-plugin azure --enable-managed-identity --generate-ssh-keys
   ```

1. Create public IP:

   ```sql
   az network public-ip create --name myPublicIp --resource-group myResourceGroup --allocation-method Static --sku Standard
   ```

1. Create VNet and subnet:

   ```sql
   az network vnet create --name myVnet --resource-group myResourceGroup --address-prefix 10.0.0.0/16 --subnet-name mySubnet --subnet-prefix 10.0.0.0/24
   ```

1. Create Azure application gateway, attach VNet, subnet and public IP:

   ```sql
   az network application-gateway create --name myApplicationGateway --resource-group myResourceGroup --sku Standard_v2 --public-ip-address myPublicIp --vnet-name myVnet --subnet mySubnet --priority 100
   ```

1. Get app gateway ID:

   ```sql
   appgwId=$(az network application-gateway show --name myApplicationGateway --resource-group myResourceGroup -o tsv --query "id")
   ```

1. Enable app gateway ingress to AKS cluster:

   ```sql
   az aks enable-addons --name myCluster --resource-group myResourceGroup --addon ingress-appgw --appgw-id $appgwId
   ```

1. Get AKS node resource group:

   ```sql
   nodeResourceGroup=$(az aks show --name myCluster --resource-group myResourceGroup -o tsv --query "nodeResourceGroup")
   ```

1. Get AKS VNet name:

   ```sql
   aksVnetName=$(az network vnet list --resource-group $nodeResourceGroup -o tsv --query "[0].name")
   ```

1. Get AKS VNet ID:

   ```sql
   aksVnetId=$(az network vnet show --name $aksVnetName --resource-group $nodeResourceGroup -o tsv --query "id")
   ```

1. Peer VNet to AKS VNet:

   ```sql
   az network vnet peering create --name AppGWtoAKSVnetPeering --resource-group myResourceGroup --vnet-name myVnet --remote-vnet $aksVnetId --allow-vnet-access
   ```

1. Get app gateway VNet ID:

   ```sql
   appGWVnetId=$(az network vnet show --name myVnet --resource-group myResourceGroup -o tsv --query "id")
   ```

1. Peer AKS VNet to app gateway VNet:

   ```sql
   az network vnet peering create --name AKStoAppGWVnetPeering --resource-group $nodeResourceGroup --vnet-name $aksVnetName --remote-vnet $appGWVnetId --allow-vnet-access
   ```

1. Get AKS credentials:

   ```sql
   az aks get-credentials --name myCluster --resource-group myResourceGroup
   ```

1. Create Coder namespace:

   ```shell
   kubectl create ns coder
   ```

1. Deploy non-production PostgreSQL instance to AKS cluster:

   ```shell
   helm repo add bitnami https://charts.bitnami.com/bitnami
   helm install coder-db bitnami/postgresql \
   --set image.repository=bitnamilegacy/postgresql \
   --namespace coder \
   --set auth.username=coder \
   --set auth.password=coder \
   --set auth.database=coder \
   --set persistence.size=10Gi
   ```

1. Create the PostgreSQL secret:

   ```shell
   kubectl create secret generic coder-db-url -n coder --from-literal=url="postgres://coder:coder@coder-db-postgresql.coder.svc.cluster.local:5432/coder?sslmode=disable"
   ```

1. Deploy Coder to AKS cluster:

   ```shell
   helm repo add coder-v2 https://helm.coder.com/v2
   helm install coder coder-v2/coder \
       --namespace coder \
    --values values.yaml \
    --version 2.25.2
   ```

1. Clean up Azure resources:

   ```sql
   az group delete --name myResourceGroup
   az group delete --name MC_myResourceGroup_myCluster_eastus
   ```

1. Deploy the gateway - this needs clarification

1. After you deploy the gateway, add the following entries to Helm's `values.yaml` file before you deploy Coder:

   ```yaml
     service:
       enable: true
       type: ClusterIP
       sessionAffinity: None
       externalTrafficPolicy: Cluster
       loadBalancerIP: ""
       annotations: {}
       httpNodePort: ""
       httpsNodePort: ""

     ingress:
       enable: true
       className: "azure-application-gateway"
       host: ""
       wildcardHost: ""
       annotations: {}
       tls:
         enable: false
         secretName: ""
         wildcardSecretName: ""
   ```

---

# Rancher

Source: https://coder.com/docs/install/rancher

# Deploy Coder on Rancher

You can deploy Coder on Rancher as a
[Workload](https://ranchermanager.docs.rancher.com/getting-started/quick-start-guides/deploy-workloads/workload-ingress).

## Requirements

- [SUSE Rancher Manager](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster) running Kubernetes (K8s) 1.19+ with [SUSE Rancher Prime distribution](https://documentation.suse.com/cloudnative/rancher-manager/latest/en/integrations/kubernetes-distributions.html) (Rancher Manager 2.10+)
- Helm 3.5+ installed
- Workload Kubernetes cluster for Coder

## Overview

Installing Coder on Rancher involves four key steps:

1. Create a namespace for Coder
1. Set up PostgreSQL
1. Create a database connection secret
1. Install the Coder application via Rancher UI

## Create a namespace

Create a namespace for the Coder control plane. In this tutorial, we call it `coder`:

```shell
kubectl create namespace coder
```

## Set up PostgreSQL

Coder requires a PostgreSQL database to store deployment data.
We recommend that you use a managed PostgreSQL service, but you can use an in-cluster PostgreSQL service for non-production deployments:

<div class="tabs">

### Managed PostgreSQL (Recommended)

For production deployments, we recommend using a managed PostgreSQL service:

- [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/)
- [AWS RDS for PostgreSQL](https://aws.amazon.com/rds/postgresql/)
- [Azure Database for PostgreSQL](https://docs.microsoft.com/en-us/azure/postgresql/)
- [DigitalOcean Managed PostgreSQL](https://www.digitalocean.com/products/managed-databases-postgresql)

Ensure that your PostgreSQL service:

- Is running and accessible from your cluster
- Is in the same network/project as your cluster
- Has proper credentials and a database created for Coder

### In-Cluster PostgreSQL (Development/PoC)

For proof-of-concept deployments, you can use Bitnami Helm chart to install PostgreSQL in your Kubernetes cluster:

```console
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install coder-db bitnami/postgresql \
    --set image.repository=bitnamilegacy/postgresql \
    --namespace coder \
    --set auth.username=coder \
    --set auth.password=coder \
    --set auth.database=coder \
    --set persistence.size=10Gi
```

After installation, the cluster-internal database URL will be:

```text
postgres://coder:coder@coder-db-postgresql.coder.svc.cluster.local:5432/coder?sslmode=disable
```

For more advanced PostgreSQL management, consider using the
[Postgres operator](https://github.com/zalando/postgres-operator).

</div>

## Create the database connection secret

Create a Kubernetes secret with your PostgreSQL connection URL:

```shell
kubectl create secret generic coder-db-url -n coder \
  --from-literal=url="postgres://coder:coder@coder-db-postgresql.coder.svc.cluster.local:5432/coder?sslmode=disable"
```

> [!Important]
> If you're using a managed PostgreSQL service, replace the connection URL with your specific database credentials.

## Install Coder through the Rancher UI

![Coder installed on Rancher](../images/install/coder-rancher.png)

1. In the Rancher Manager console, select your target Kubernetes cluster for Coder.

1. Navigate to **Apps** > **Charts**

1. From the dropdown menu, select **Partners** and search for `Coder`

1. Select **Coder**, then **Install**

1. Select the `coder` namespace you created earlier and check **Customize Helm options before install**.

   Select **Next**

1. On the configuration screen, select **Edit YAML** and enter your Coder configuration settings:

   <details>
   <summary>Example values.yaml configuration</summary>

   ```yaml
   coder:
     # Environment variables for Coder
     env:
       - name: CODER_PG_CONNECTION_URL
         valueFrom:
           secretKeyRef:
             name: coder-db-url
             key: url

       # For production, uncomment and set your access URL
       # - name: CODER_ACCESS_URL
       #   value: "https://coder.example.com"

     # For TLS configuration (uncomment if needed)
     #tls:
     #  secretNames:
     #    - my-tls-secret-name
   ```

   For available configuration options, refer to the [Helm chart documentation](https://github.com/coder/coder/blob/main/helm#readme)
   or [values.yaml file](https://github.com/coder/coder/blob/main/helm/coder/values.yaml).

   </details>

1. Select a Coder version:

   - **Mainline**: `2.30.0`
   - **Stable**: `2.29.5`

   Learn more about release channels in the [Releases documentation](./releases/index.md).

1. Select **Next** when your configuration is complete.

1. On the **Supply additional deployment options** screen:

   1. Accept the default settings
   1. Select **Install**

1. A Helm install output shell will be displayed and indicates the installation status.

## Manage your Rancher Coder deployment

To update or manage your Coder deployment later:

1. Navigate to **Apps** > **Installed Apps** in the Rancher UI.
1. Find and select Coder.
1. Use the options in the **⋮** menu for upgrade, rollback, or other operations.

## Next steps

- [Create your first template](../tutorials/template-from-scratch.md)
- [Control plane configuration](../admin/setup/index.md)

---

# OpenShift

Source: https://coder.com/docs/install/openshift

# OpenShift

## Requirements

- OpenShift cluster running K8s 1.19+ (OpenShift 4.7+)
- Helm 3.5+ installed
- OpenShift CLI (`oc`) installed
- [Coder CLI](./cli.md) installed

## Install Coder with OpenShift

### 1. Authenticate to OpenShift and create a Coder project

Run the following command to login to your OpenShift cluster:

```shell
oc login --token=w4r...04s --server=<cluster-url>
```

Next, you will run the below command to create a project for Coder:

```shell
oc new-project coder
```

### 2. Configure SecurityContext values

Depending upon your configured Security Context Constraints (SCC), you'll need
to modify some or all of the following `securityContext` values from the default
values:

The below values are modified from Coder defaults and allow the Coder deployment
to run under the SCC `restricted-v2`.

> [!NOTE]
> `readOnlyRootFilesystem: true` is not technically required under
> `restricted-v2`, but is often mandated in OpenShift environments.

```yaml
coder:
  securityContext:
    runAsNonRoot: true # Unchanged from default
    runAsUser: <project-specific UID> # Default: 1000, replace this with the correct UID for your project.
    runAsGroup: <project-specific GID> # Default: 1000, replace this with the correct GID for your project.
    readOnlyRootFilesystem: true # Default: false, this is often required in OpenShift environments.
    seccompProfile: RuntimeDefault # Unchanged from default
```

- For `runAsUser` / `runAsGroup`, you can retrieve the correct values for
  project UID and project GID with the following command:

    ```console
    oc get project coder -o json | jq -r '.metadata.annotations'
    {
        "openshift.io/sa.scc.supplemental-groups": "1000680000/10000",
        "openshift.io/sa.scc.uid-range": "1000680000/10000"
    }
    ```

  Alternatively, you can set these values to `null` to allow OpenShift to
  automatically select the correct value for the project.

- For `readOnlyRootFilesystem`, consult the SCC under which Coder needs to run.
  In the below example, the `restricted-v2` SCC does not require a read-only
  root filesystem, while `restricted-custom` does:

  ```console
  oc get scc -o wide
  NAME               PRIV    CAPS                   SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY     READONLYROOTFS   VOLUMES
  restricted-custom   false   ["NET_BIND_SERVICE"]   MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   true             ["configMap","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
  restricted-v2       false   ["NET_BIND_SERVICE"]   MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            ["configMap","downwardAPI","emptyDir","ephemeral","persistentVolumeClaim","projected","secret"]
  ```

  If you are unsure, we recommend setting `readOnlyRootFilesystem` to `true` in
  an OpenShift environment.

- For `seccompProfile`: in some environments, you may need to set this to `null`
  to allow OpenShift to pick its preferred value.

### 3. Configure the Coder service, connection URLs, and cache values

To establish a connection to PostgreSQL, set the `CODER_PG_CONNECTION_URL`
value. [See our Helm documentation](./kubernetes.md) on configuring the
PostgreSQL connection URL as a secret. Additionally, if accessing Coder over a
hostname, set the `CODER_ACCESS_URL` value.

By default, Coder creates the cache directory in `/home/coder/.cache`. Given the
OpenShift-provided UID and `readOnlyRootFS` security context constraint, the
Coder container does not have permission to write to this directory.

To fix this, you can mount a temporary volume in the pod and set the
`CODER_CACHE_DIRECTORY` environment variable to that location. In the below
example, we mount this under `/tmp` and set the cache location to `/tmp/coder`.
This enables Coder to run with `readOnlyRootFilesystem: true`.

> [!NOTE]
> Depending on the number of templates and provisioners you use, you may
> need to increase the size of the volume, as the `coder` pod will be
> automatically restarted when this volume fills up.

Additionally, create the Coder service as a `ClusterIP`. In the next step, you
will create an OpenShift route that points to the service HTTP target port.

```yaml
coder:
  service:
    type: ClusterIP
  env:
    - name: CODER_CACHE_DIRECTORY
      value: /tmp/coder
    - name: CODER_PG_CONNECTION_URL
      valueFrom:
        secretKeyRef:
          key: url
          name: coder-db-url
    - name: CODER_ACCESS_URL
      value: "https://coder-example.apps.openshiftapps.com"
  securityContext:
    runAsNonRoot: true
    runAsUser: <project-specific UID>
    runAsGroup: <project-specific GID>
    readOnlyRootFilesystem: true
  volumes:
    - name: "cache"
      emptyDir:
        sizeLimit: 1Gi
  volumeMounts:
    - name: "cache"
      mountPath: "/tmp"
      readOnly: false
```

> [!NOTE]
> OpenShift provides a Developer Catalog offering you can use to install
> PostgreSQL into your cluster.

### 4. Create the OpenShift route

Below is the YAML spec for creating an OpenShift route that sends traffic to the
HTTP port of the Coder service:

```yaml
kind: Route
apiVersion: route.openshift.io/v1
metadata:
  namespace: coder
spec:
  host: https://coder-example.apps.openshiftapps.com
  to:
    kind: Service
    name: coder
  tls:
    # if set to edge, OpenShift will terminate TLS prior to the traffic reaching
    # the service.
    termination: edge
    # if set to Redirect, insecure client connections are redirected to the secure
    # port
    insecureEdgeTerminationPolicy: Redirect
  port:
    targetPort: http
```

Once complete, you can create this route in OpenShift via:

```console
oc apply -f route.yaml
```

### 5. Install Coder

You can now install Coder using the values you've set from the above steps. To
do so, run the series of `helm` commands below:

```shell
helm repo add coder-v2 https://helm.coder.com/v2
helm repo update
helm install coder coder-v2/coder \
  --namespace coder \
  --values values.yaml
```

> [!NOTE]
> If the Helm installation fails with a Kubernetes RBAC error, check the
> permissions of your OpenShift user using the `oc auth can-i` command.
>
> The below permissions are the minimum required:
>
> ```console
> oc auth can-i --list
> Resources                                          Non-Resource URLs   Resource Names    Verbs
> selfsubjectaccessreviews.authorization.k8s.io      []                  []                [create]
> selfsubjectrulesreviews.authorization.k8s.io       []                  []                [create]
> *                                                  []                  []                [get list watch create update patch delete deletecollection]
> *.apps                                             []                  []                [get list watch create update patch delete deletecollection]
> *.rbac.authorization.k8s.io                        []                  []                [get list watch create update patch delete deletecollection]
>                                                    [/.well-known/*]    []                [get]
>                                                    [/.well-known]      []                [get]
>                                                    [/api/*]            []                [get]
>                                                    [/api]              []                [get]
>                                                    [/apis/*]           []                [get]
>                                                    [/apis]             []                [get]
>                                                    [/healthz]          []                [get]
>                                                    [/healthz]          []                [get]
>                                                    [/livez]            []                [get]
>                                                    [/livez]            []                [get]
>                                                    [/openapi/*]        []                [get]
>                                                    [/openapi]          []                [get]
>                                                    [/readyz]           []                [get]
>                                                    [/readyz]           []                [get]
>                                                    [/version/]         []                [get]
>                                                    [/version/]         []                [get]
>                                                    [/version]          []                [get]
>                                                    [/version]          []                [get]
> securitycontextconstraints.security.openshift.io   []                  [restricted-v2]   [use]
> ```

### 6. Create an OpenShift-compatible image

While the deployment is spinning up, we will need to create some images that are
compatible with OpenShift. These images can then be run without modifying the
Security Context Constraints (SCCs) in OpenShift.

1. Determine the UID range for the project:

   ```console
   oc get project coder -o json | jq -r '.metadata.annotations'
   {
     "openshift.io/description": "",
     "openshift.io/display-name": "coder",
     "openshift.io/requester": "kube:admin",
     "openshift.io/sa.scc.mcs": "s0:c26,c15",
     "openshift.io/sa.scc.supplemental-groups": "1000680000/10000",
     "openshift.io/sa.scc.uid-range": "1000680000/10000"
   }
   ```

   Note the `uid-range` and `supplemental-groups`. In this case, the project
   `coder` has been allocated 10,000 UIDs and GIDs, both starting at
   `1000680000`.

   In this example, we will pick both UID and GID `1000680000`.

1. Create a `BuildConfig` referencing the source image you want to customize.
   This will automatically kick off a `Build` that will remain pending until
   step 3.

   > For more information, please consult the
   > [OpenShift Documentation](https://docs.openshift.com/container-platform/4.12/cicd/builds/understanding-buildconfigs.html).

   ```shell
   oc create -f - <<EOF
   kind: BuildConfig
   apiVersion: build.openshift.io/v1
   metadata:
     name: enterprise-base
     namespace: coder
   spec:
     output:
       to:
         kind: ImageStreamTag
         name: 'enterprise-base:latest'
     strategy:
       type: Docker
       dockerStrategy:
         imageOptimizationPolicy: SkipLayers
     source:
       type: Dockerfile
       dockerfile: |
         # Specify the source image.
         FROM docker.io/codercom/enterprise-base:ubuntu

         # Switch to root
         USER root

         # As root:
         # 1) Remove the original coder user with UID 1000
         # 2) Add a coder group with an allowed UID
         # 3) Add a coder user as a member of the above group
         # 4) Fix ownership on the user's home directory
         RUN userdel coder && \
             groupadd coder -g 1000680000 && \
             useradd -l -u 1000680000 coder -g 1000680000 && \
             chown -R coder:coder /home/coder

         # Go back to the user 'coder'
         USER coder
     triggers:
       - type: ConfigChange
     runPolicy: Serial
   EOF
   ```

1. Create an `ImageStream` as a target for the previous step:

   ```shell
   oc create imagestream enterprise-base
   ```

   The `Build` created in the previous step should now begin. Once completed,
   you should see output similar to the following:

   ```console
   oc get imagestreamtag
   NAME                     IMAGE REFERENCE                                                                                                                                    UPDATED
   enterprise-base:latest   image-registry.openshift-image-registry.svc:5000/coder/enterprise-base@sha256:1dbbe4ee11be9218e1e4741264135a4f57501fe592d94d20db6bfe11692accd1   55 minutes ago
   ```

### 7. Create an OpenShift-compatible template

Start from the default "Kubernetes" template:

```shell
echo kubernetes | coderv2 templates init ./openshift-k8s
cd ./openshift-k8s
```

Edit `main.tf` and update the following fields of the Kubernetes pod resource:

- `spec.security_context`: remove this field.
- `spec.container.image`: update this field to the newly built image hosted on
  the OpenShift image registry from the previous step.
- `spec.container.security_context`: remove this field.

Finally, create the template:

```shell
coder template push kubernetes -d .
```

This template should be ready to use straight away.

## Next steps

- [Create your first template](../tutorials/template-from-scratch.md)
- [Control plane configuration](../admin/setup/index.md)

---

# Cloud Providers

Source: https://coder.com/docs/install/cloud

# Cloud Platforms

We provide install guides and example templates for deploying Coder to your
cloud of choice.

<div class="tabs">

## AWS

We publish Coder Community Edition on the AWS Marketplace. Follow the tutorial here:

- [Install Coder Community Edition from AWS Marketplace](./aws-marketplace.md)

Alternatively, install the [CLI binary](../cli.md) on any Linux machine or
follow our [Kubernetes](../kubernetes.md) documentation to install Coder on an
existing Kubernetes cluster.

For EKS-specific installation guidance, see the [AWS section in Kubernetes installation docs](../kubernetes.md#aws).

## GCP

We publish a GCP Marketplace listing with Coder pre-installed. Follow the
tutorial here:

- [Install Coder on GCP Compute Engine](./compute-engine.md)

Alternatively, install the [CLI binary](../cli.md) on any Linux machine or
follow our [Kubernetes](../kubernetes.md) documentation to install Coder on an
existing GKE cluster.

## Azure

Use the following guide to run Coder on an Azure VM:

- [Install Coder on an Azure VM](./azure-vm.md)

Alternatively, install the [CLI binary](../cli.md) on any Linux machine or
follow our [Kubernetes](../kubernetes.md) documentation to install Coder on an
existing GKE cluster.

## Other

Is your cloud missing? Check [unofficial](../other/index.md) install methods or
install the [standalone binary](../cli.md).

</div>

---

# AWS Marketplace

Source: https://coder.com/docs/install/cloud/aws-marketplace

# Amazon Web Services

This guide is designed to get you up and running with a Coder proof-of-concept
on AWS EKS using a [Coder-provided CloudFormation Template](https://codermktplc-assets.s3.us-east-1.amazonaws.com/community-edition/eks-cluster.yaml).  The deployed AWS Coder Reference Architecture is below:
![Coder on AWS EKS](../../images/platforms/aws/aws-coder-refarch-v1.png)

If you are familiar with EC2 however, you can use our
[install script](../cli.md) to run Coder on any popular Linux distribution.

## Requirements

This guide assumes your AWS account has `AdministratorAccess` permissions given the number and types of AWS Services deployed.  After deployment of Coder into a AWS POC or Sandbox account, it is recommended that the permissions be scaled back to only what your deployment requires.

## Launch Coder Community Edition from the from AWS Marketplace

We publish an Ubuntu 22.04 Container Image with Coder pre-installed and a supporting AWS Marketplace Launch guide. Search for `Coder Community Edition` in the AWS Marketplace or
[launch directly from the Coder listing](https://aws.amazon.com/marketplace/pp/prodview-34vmflqoi3zo4).

![Coder on AWS Marketplace](../../images/platforms/aws/marketplace-ce.png)

Use `View purchase options` to create a zero-cost subscription to Coder Community Edition and then use `Launch your software` to deploy to your current AWS Account.

![AWS Marketplace Subscription](../../images/platforms/aws/marketplace-sub.png)

Select `EKS` for the Launch setup, choose the desired/lastest version to deploy, and then review the **Launch** instructions for more detail explanation of what will be deployed.  When you are ready to proceed, click the `CloudFormation Template` link under **Deployment templates**.

![AWS Marketplace Launch](../../images/platforms/aws/marketplace-launch.png)

You will then be taken to the AWS Management Console, CloudFormation `Create stack` in the currently selected AWS Region.  Select `Next` to view the Coder Community Edition CloudFormation Stack parameters.

![AWS Marketplace Stack](../../images/platforms/aws/marketplace-stack.png)

The default parameters will support POCs and small team deployments of Coder using `t3.large` (2 cores and 8 GB memory) Nodes.  While the deployment uses EKS Auto-mode and will scale using Karpenter, keep in mind this platforms is intended for proof-of-concept
deployments. You should adjust your infrastructure when preparing for
production use. See: [Scaling Coder](../../admin/infrastructure/index.md)

![AWS Marketplace Parameters](../../images/platforms/aws/marketplace-parm.png)

Select `Next` and follow the prompts to submit the CloudFormation Stack.  Deployment of the Stack can take 10-20 minutes, and will create EKS related sub-stacks and a CodeBuild pipeline that automates the initial Helm deployment of Coder and final AWS network services integration.  Once the Stack successfully creates, access the `Outputs` as shown below:

![AWS Marketplace Outputs](../../images/platforms/aws/marketplace-output.png)

Look for the `CoderURL` output link, and use to navigate to your newly deployed instance of Coder Community Edition.

That's all! Use the UI to create your first user, template, and workspace. We recommend starting with a Kubernetes template since Coder Community Edition is deployed to EKS.

### Next steps

- [IDEs with Coder](../../user-guides/workspace-access/index.md)
- [Writing custom templates for Coder](../../admin/templates/index.md)
- [Configure the Coder server](../../admin/setup/index.md)
- [Use your own domain + TLS](../../admin/setup/index.md#tls--reverse-proxy)

---

# GCP Compute Engine

Source: https://coder.com/docs/install/cloud/compute-engine

# Google Cloud Platform

In this guide, you will learn how to deploy the Coder control plane instance and
your first template.

## Requirements

This guide assumes you have `roles/compute.instanceAdmin.v1` access to your
Google Cloud Platform project.

## Launch a Coder instance from the Google Cloud Marketplace

We publish an Ubuntu 22.04 VM image with Coder and Docker pre-installed.

Two SKU's are available via the Google Cloud Marketplace:

1. [License purchase via Google Cloud Marketplace](https://console.cloud.google.com/marketplace/product/coder-enterprise-market-public/coder-gcmp?inv=1&invt=Ab45rg&project=secret-beacon-468405-p5)
2. [A solution to deploy VM's on GCP (Bring Your Own License)](https://console.cloud.google.com/marketplace/product/workspan-public-422119/coder?inv=1&invt=Ab45rg&project=secret-beacon-468405-p5)

![Coder on GCP Marketplace](../../images/platforms/gcp/marketplace.png)

Be sure to keep the default firewall options checked so you can connect over
HTTP, HTTPS, and SSH.

We recommend keeping the default instance type (`e2-standard-4`, 4 cores and 16
GB memory) if you plan on provisioning Docker containers as workspaces on this
VM instance. Keep in mind this platforms is intended for proof-of-concept
deployments and you should adjust your infrastructure when preparing for
production use. See: [Scaling Coder](../../admin/infrastructure/index.md)

<video autoplay playsinline loop>
  <source src="https://github.com/coder/coder/blob/main/docs/images/platforms/gcp/launch.mp4?raw=true" type="video/mp4">
Your browser does not support the video tag.
</video>

Be sure to add a keypair so that you can connect over SSH to further
[configure Coder](../../admin/setup/index.md).

After launching the instance, wait 30 seconds and navigate to the public IPv4
address. You should be redirected to a public tunnel URL.

![Coder on GCP Marketplace start](../../images/platforms/gcp/start.png)

That's all! Use the UI to create your first user, template, and workspace. We
recommend starting with a Docker template since the instance has Docker
pre-installed.

![Coder Workspace and IDE in GCP VM](../../images/platforms/aws/workspace.png)

## Configuring Coder server

Coder is primarily configured by server-side flags and environment variables.
Given you created or added key-pairs when launching the instance, you can
[configure your Coder deployment](../../admin/setup/index.md) by logging in via
SSH or using the console:

```shell
ssh ubuntu@<gcp-public-IPv4>
sudo vim /etc/coder.d/coder.env # edit config
sudo systemctl daemon-reload
sudo systemctl restart coder # restart Coder
```

## Give developers VM workspaces (optional)

Instead of running containers on the Coder instance, you can offer developers
full VM instances with the
[gcp-linux](https://github.com/coder/coder/tree/main/examples/templates/gcp-linux)
template.

Before you can use this template, you must authorize Coder to create VM
instances in your GCP project. Follow the instructions in the
[gcp-linux template README](https://github.com/coder/coder/tree/main/examples/templates/gcp-linux#authentication)
to set up authentication.

### Next Steps

- [Use your IDE with Coder](../../user-guides/workspace-access/index.md)
- [Writing custom templates for Coder](../../admin/templates/index.md)
- [Configure the Coder server](../../admin/setup/index.md)
- [Use your own domain + TLS](../../admin/setup/index.md#tls--reverse-proxy)

---

# Azure VM

Source: https://coder.com/docs/install/cloud/azure-vm

# Microsoft Azure

This guide shows you how to set up the Coder server on Azure which will
provision Azure-hosted Linux workspaces.

## Requirements

This guide assumes you have full administrator privileges on Azure.

## Create An Azure VM

From the Azure Portal, navigate to the Virtual Machines Dashboard. Click Create,
and select creating a new Azure Virtual machine .

<img src="../../images/platforms/azure/azure1.jpg" alt="Azure VM creation page">

This will bring you to the `Create a virtual machine` page. Select the
subscription group of your choice, or create one if necessary.

Next, name the VM something relevant to this project using the naming convention
of your choice. Change the region to something more appropriate for your current
location. For this tutorial, we will use the base selection of the Ubuntu Gen2
Image and keep the rest of the base settings for this image the same.

<img src="../../images/platforms/azure/azure2.png" alt="Azure VM instance details">

<img src="../../images/platforms/azure/azure3.png" alt="Azure VM size selection">

Up next, under `Inbound port rules` modify the Select `inbound ports` to also
take in `HTTPS` and `HTTP`.

<img src="../../images/platforms/azure/azure4.png" alt="Azure VM inbound port rules">

The set up for the image is complete at this stage. Click `Review and Create` -
review the information and click `Create`. A popup will appear asking you to
download the key pair for the server. Click
`Download private key and create resource` and place it into a folder of your
choice on your local system.

<img src="../../images/platforms/azure/azure5.png" alt="Azure VM key pair generation">

Click `Return to create a virtual machine`. Your VM will start up!

<img src="../../images/platforms/azure/azure6.png" alt="Azure VM deployment complete">

Click `Go to resource` in the virtual machine and copy the public IP address.
You will need it to SSH into the virtual machine via your local machine.

Follow
[these instructions](https://learn.microsoft.com/en-us/azure/virtual-machines/linux-vm-connect?tabs=Linux)
to SSH into the virtual machine. Once on the VM, you can run and install Coder
using your method of choice. For the fastest install, we recommend running Coder
as a system service.

## Install Coder

For this instance, we will run Coder as a system service, however you can run
Coder a multitude of different ways. You can learn more about those
[here](https://coder.com/docs/coder-oss/latest/install).

In the Azure VM instance, run the following command to install Coder

```shell
curl -fsSL https://coder.com/install.sh | sh
```

## Run Coder

Run the following command to start Coder as a system level service:

```shell
sudo systemctl enable --now coder
```

The following command will get you information about the Coder launch service

```shell
journalctl -u coder.service -b
```

This will return a series of logs related to running Coder as a system service.
Embedded in the logs is the Coder Access URL.

Copy the URL and run the following command to create the first user, either on
your local machine or in the instance terminal.

```shell
coder login <url***.try.coder.app>
```

Fill out the prompts. Be sure to save use email and password as these are your
admin username and password.

You can now access Coder on your local machine with the relevant
`***.try.coder.app` URL and logging in with the username and password.

## Creating and Uploading Your First Template

First, run `coder template init` to create your first template. You’ll be given
a list of possible templates to use. This tutorial will show you how to set up
your Coder instance to create a Linux based machine on Azure.

<img src="../../images/platforms/azure/azure9.png" alt="Coder CLI template init">

Press `enter` to select `Develop in Linux on Azure` template. This will return
the following:

<img src="../../images/platforms/azure/azure10.png" alt="Coder CLI template init">

To get started using the Azure template, install the Azure CLI by following the
instructions
[here](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-linux?pivots=apt).
Run `az login` and follow the instructions to configure the Azure command line.

Coder is running as a system service, which creates the system user `coder` for
handling processes. The Coder user will require access to the Azure credentials
to initialize the template.

Run the following commands to copy the Azure credentials and give the `coder`
user access to them:

```shell
sudo cp -r ~/.azure /home/coder/.azure
sudo chown -R coder:coder /home/coder/.azure/
```

Navigate to the `./azure-linux` folder where you created your template and run
the following command to put the template on your Coder instance.

```shell
coder templates push
```

Congrats! You can now navigate to your Coder dashboard and use this Linux on
Azure template to create a new workspace!

---

# Air-gapped Deployments

Source: https://coder.com/docs/install/airgap

# Air-gapped Deployments

All Coder features are supported in air-gapped / behind firewalls / disconnected / offline.
This is a general comparison. Keep reading for a full tutorial running Coder
air-gapped with Kubernetes or Docker.

|                           | Public deployments                                                                                                                                                                                                                                                 | Air-gapped deployments                                                                                                                                                                                                                                                                               |
|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Terraform binary          | By default, Coder downloads Terraform binary from [releases.hashicorp.com](https://releases.hashicorp.com)                                                                                                                                                         | Terraform binary must be included in `PATH` for the VM or container image. [Supported versions](https://github.com/coder/coder/blob/main/provisioner/terraform/install.go#L23-L24)                                                                                                                   |
| Terraform registry        | Coder templates will attempt to download providers from [registry.terraform.io](https://registry.terraform.io) or [custom source addresses](https://developer.hashicorp.com/terraform/language/providers/requirements#source-addresses) specified in each template | [Custom source addresses](https://developer.hashicorp.com/terraform/language/providers/requirements#source-addresses) can be specified in each Coder template, or a custom registry/mirror can be used. More details below                                                                           |
| STUN                      | By default, Coder uses Google's public STUN server for direct workspace connections                                                                                                                                                                                | STUN can be safely [disabled](../reference/cli/server.md#--derp-server-stun-addresses) users can still connect via [relayed connections](../admin/networking/index.md#-geo-distribution). Alternatively, you can set a [custom DERP server](../reference/cli/server.md#--derp-server-stun-addresses) |
| DERP                      | By default, Coder's built-in DERP relay can be used, or [Tailscale's public relays](../admin/networking/index.md#relayed-connections).                                                                                                                             | By default, Coder's built-in DERP relay can be used, or [custom relays](../admin/networking/index.md#custom-relays).                                                                                                                                                                                 |
| PostgreSQL                | If no [PostgreSQL connection URL](../reference/cli/server.md#--postgres-url) is specified, Coder will download Postgres from [repo1.maven.org](https://repo1.maven.org)                                                                                            | An external database is required, you must specify a [PostgreSQL connection URL](../reference/cli/server.md#--postgres-url)                                                                                                                                                                          |
| Telemetry                 | Telemetry is on by default, and [can be disabled](../reference/cli/server.md#--telemetry)                                                                                                                                                                          | Telemetry [can be disabled](../reference/cli/server.md#--telemetry)                                                                                                                                                                                                                                  |
| Update check              | By default, Coder checks for updates from [GitHub releases](https://github.com/coder/coder/releases)                                                                                                                                                               | Update checks [can be disabled](../reference/cli/server.md#--update-check)                                                                                                                                                                                                                           |
| License validation        | License keys are validated locally using cryptographic signatures. No outbound connection to Coder is required                                                                                                                                                     | No changes needed. See [offline license validation](../admin/licensing/index.md#offline-license-validation)                                                                                                                                                                                          |
| AI Governance Usage Count | By default, deployments with the [AI Governance Add On](../ai-coder/ai-governance.md) report usage data                                                                                                                                                            | [Contact us](https://coder.com/contact) to request a license with usage reporting off.                                                                                                                                                                                                               |

## Air-gapped container images

The following instructions walk you through how to build a custom Coder server
image for Docker or Kubernetes

First, build and push a container image extending our official image with the
following:

- CLI config (.tfrc) for Terraform referring to
  [external mirror](https://www.terraform.io/cli/config/config-file#explicit-installation-method-configuration)
- [Terraform Providers](https://registry.terraform.io) for templates
  - These could also be specified via a volume mount (Docker) or
    [network mirror](https://www.terraform.io/internals/provider-network-mirror-protocol).
    See below for details.

> [!NOTE]
> Coder includes the latest
> [supported version](https://github.com/coder/coder/blob/main/provisioner/terraform/install.go#L23-L24)
> of Terraform in the official Docker images. If you need to bundle a different
> version of terraform, you can do so by customizing the image.

Here's an example Dockerfile:

```Dockerfile
FROM ghcr.io/coder/coder:latest

USER root

RUN apk add curl unzip

# Create directory for the Terraform CLI (and assets)
RUN mkdir -p /opt/terraform

# Terraform is already included in the official Coder image.
# See https://github.com/coder/coder/blob/main/scripts/Dockerfile.base#L15
# If you need to install a different version of Terraform, you can do so here.
# The below step is optional if you wish to keep the existing version.
# See https://github.com/coder/coder/blob/main/provisioner/terraform/install.go#L23-L24
# for supported Terraform versions.
ARG TERRAFORM_VERSION=1.11.0
RUN apk update && \
    curl -LOs https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \
    && unzip -o terraform_${TERRAFORM_VERSION}_linux_amd64.zip \
    && mv terraform /opt/terraform \
    && rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip
ENV PATH=/opt/terraform:${PATH}

# Additionally, a Terraform mirror needs to be configured
# to download the Terraform providers used in Coder templates.
# There are two options:

# Option 1) Use a filesystem mirror.
#  We can seed this at build-time or by mounting a volume to
#  /opt/terraform/plugins in the container.
#  https://developer.hashicorp.com/terraform/cli/config/config-file#filesystem_mirror
#  Be sure to add all the providers you use in your templates to /opt/terraform/plugins

RUN mkdir -p /home/coder/.terraform.d/plugins/registry.terraform.io
ADD filesystem-mirror-example.tfrc /home/coder/.terraformrc

# Optionally, we can "seed" the filesystem mirror with common providers.
# Comment out lines 40-49 if you plan on only using a volume or network mirror:
WORKDIR /home/coder/.terraform.d/plugins/registry.terraform.io
ARG CODER_PROVIDER_VERSION=2.2.0
RUN echo "Adding coder/coder v${CODER_PROVIDER_VERSION}" \
    && mkdir -p coder/coder && cd coder/coder \
    && curl -LOs https://github.com/coder/terraform-provider-coder/releases/download/v${CODER_PROVIDER_VERSION}/terraform-provider-coder_${CODER_PROVIDER_VERSION}_linux_amd64.zip
ARG DOCKER_PROVIDER_VERSION=3.0.2
RUN echo "Adding kreuzwerker/docker v${DOCKER_PROVIDER_VERSION}" \
    && mkdir -p kreuzwerker/docker && cd kreuzwerker/docker \
    && curl -LOs https://github.com/kreuzwerker/terraform-provider-docker/releases/download/v${DOCKER_PROVIDER_VERSION}/terraform-provider-docker_${DOCKER_PROVIDER_VERSION}_linux_amd64.zip
ARG KUBERNETES_PROVIDER_VERSION=2.36.0
RUN echo "Adding kubernetes/kubernetes v${KUBERNETES_PROVIDER_VERSION}" \
    && mkdir -p hashicorp/kubernetes && cd hashicorp/kubernetes \
    && curl -LOs https://releases.hashicorp.com/terraform-provider-kubernetes/${KUBERNETES_PROVIDER_VERSION}/terraform-provider-kubernetes_${KUBERNETES_PROVIDER_VERSION}_linux_amd64.zip
ARG AWS_PROVIDER_VERSION=5.89.0
RUN echo "Adding aws/aws v${AWS_PROVIDER_VERSION}" \
    && mkdir -p aws/aws && cd aws/aws \
    && curl -LOs https://releases.hashicorp.com/terraform-provider-aws/${AWS_PROVIDER_VERSION}/terraform-provider-aws_${AWS_PROVIDER_VERSION}_linux_amd64.zip

RUN chown -R coder:coder /home/coder/.terraform*
WORKDIR /home/coder

# Option 2) Use a network mirror.
#  https://developer.hashicorp.com/terraform/cli/config/config-file#network_mirror
#  Be sure uncomment line 60 and edit network-mirror-example.tfrc to
#  specify the HTTPS base URL of your mirror.

# ADD network-mirror-example.tfrc /home/coder/.terraformrc

USER coder

# Use the .terraformrc file to inform Terraform of the locally installed providers.
ENV TF_CLI_CONFIG_FILE=/home/coder/.terraformrc
```

> [!NOTE]
> If you are bundling Terraform providers into your Coder image, be sure the
> provider version matches any templates or
> [example templates](https://github.com/coder/coder/tree/main/examples/templates)
> you intend to use.

```tf
# filesystem-mirror-example.tfrc
provider_installation {
  filesystem_mirror {
    path = "/home/coder/.terraform.d/plugins"
  }
}
```

```tf
# network-mirror-example.tfrc
provider_installation {
  network_mirror {
    url = "https://terraform.example.com/providers/"
  }
}
```

<div class="tabs">

### Docker

Follow our [docker-compose](./docker.md#install-coder-via-docker-compose)
documentation and modify the docker-compose file to specify your custom Coder
image. Additionally, you can add a volume mount to add providers to the
filesystem mirror without re-building the image.

First, create an empty plugins directory:

```shell
mkdir $HOME/plugins
```

Next, add a volume mount to compose.yaml:

```shell
vim compose.yaml
```

```yaml
# compose.yaml
services:
  coder:
    image: registry.example.com/coder:latest
    volumes:
      - ./plugins:/opt/terraform/plugins
    # ...
  environment:
    CODER_TELEMETRY_ENABLE: "false" # Disable telemetry
    CODER_BLOCK_DIRECT: "true" # force SSH traffic through control plane's DERP proxy
    CODER_DERP_SERVER_STUN_ADDRESSES: "disable" # Only use relayed connections
    CODER_UPDATE_CHECK: "false" # Disable automatic update checks
  database:
    image: registry.example.com/postgres:17
    # ...
```

The
[terraform providers mirror](https://www.terraform.io/cli/commands/providers/mirror)
command can be used to download the required plugins for a Coder template.
This can be uploaded into the `plugins` directory on your offline server.

### Kubernetes

We publish the Helm chart for download on
[GitHub Releases](https://github.com/coder/coder/releases/latest). Follow our
[Kubernetes](./kubernetes.md) documentation and modify the Helm values to
specify your custom Coder image.

```yaml
# values.yaml
coder:
  image:
    repo: "registry.example.com/coder"
    tag: "latest"
  env:
    # Disable telemetry
    - name: "CODER_TELEMETRY_ENABLE"
      value: "false"
    # Disable automatic update checks
    - name: "CODER_UPDATE_CHECK"
      value: "false"
    # force SSH traffic through control plane's DERP proxy
    - name: CODER_BLOCK_DIRECT
      value: "true"
    # Only use relayed connections
    - name: "CODER_DERP_SERVER_STUN_ADDRESSES"
      value: "disable"
    # You must set up an external PostgreSQL database
    - name: "CODER_PG_CONNECTION_URL"
      value: ""
# ...
```

</div>

## Air-gapped docs

Coder also provides air-gapped documentation in case you want to host it on your
own server. The docs are exported as static files that you can host on any web
server, as demonstrated in the example below:

1. Go to the release page. In this case, we want to use the
   [latest version](https://github.com/coder/coder/releases/latest).
2. Download the documentation files from the "Assets" section. It is named as
   `coder_docs_<version>.tgz`.
3. Extract the file and move its contents to your server folder.
4. If you are using NodeJS, you can execute the following command:
   `cd docs && npx http-server .`
5. Set the [CODER_DOCS_URL](../reference/cli/server.md#--docs-url) environment
   variable to use the URL of your hosted docs. This way, the Coder UI will
   reference the documentation from your specified URL.

With these steps, you'll have the Coder documentation hosted on your server and
accessible for your team to use.

## Coder Modules

To use Coder modules in offline installations, you can either:

- [Mirror the Coder Registry with JFrog Artifactory](./registry-mirror-artifactory.md) (recommended)
- [Manually publish modules to Artifactory or use a private git repository](../admin/templates/extending-templates/modules.md#offline-installations)

## Firewall exceptions

In restricted internet networks, Coder may require connection to internet.
Ensure that the following web addresses are accessible from the machine where
Coder is installed.

- code-server.dev (install via AUR)
- open-vsx.org (optional if someone would use code-server)
- registry.terraform.io (to create and push template)
- v2-licensor.coder.com (developing Coder in Coder)

## JetBrains IDEs

Gateway, JetBrains' remote development product that works with Coder,
[has documented offline deployment steps.](../admin/templates/extending-templates/jetbrains-airgapped.md)

## Microsoft VS Code Remote - SSH

Installation of the
[Visual Studio Code Remote - SSH extension](https://code.visualstudio.com/docs/remote/ssh)
(for connecting a local VS Code to a remote Coder workspace) requires that your
local machine has outbound HTTPS (port 443) connectivity to:

- update.code.visualstudio.com
- vscode.blob.core.windows.net
- \*.vo.msecnd.net

## Next steps

- [Create your first template](../tutorials/template-from-scratch.md)
- [Control plane configuration](../admin/setup/index.md)

---

# Unofficial Install Methods

Source: https://coder.com/docs/install/other

# Alternate install methods

Coder has a number of alternate unofficial installation methods. Contributions are
welcome!

| Platform Name                                                                     | Status     | Documentation                                                                                |
|-----------------------------------------------------------------------------------|------------|----------------------------------------------------------------------------------------------|
| Azure AKS                                                                         | Unofficial | [GitHub: coder-aks](https://github.com/ericpaulsen/coder-aks)                                |
| Terraform (GKE, AKS, LKE, DOKS, IBMCloud K8s, OVHCloud K8s, Scaleway K8s Kapsule) | Unofficial | [GitHub: coder-oss-terraform](https://github.com/ElliotG/coder-oss-tf)                       |
| Fly.io                                                                            | Unofficial | [Blog: Run Coder on Fly.io](https://coder.com/blog/remote-developer-environments-on-fly-io)  |
| Garden.io                                                                         | Unofficial | [GitHub: garden-coder-example](https://github.com/garden-io/garden-coder-example)            |
| Railway.com                                                                       | Unofficial | [Run Coder on Railway.com](https://railway.com/deploy/coder)                                 |
| Heroku                                                                            | Unofficial | [Docs: Deploy Coder on Heroku](https://github.com/coder/packages/blob/main/heroku/README.md) |
| Render                                                                            | Unofficial | [Docs: Deploy Coder on Render](https://github.com/coder/packages/blob/main/render/README.md) |
| Snapcraft                                                                         | Unofficial | [Get it from the Snap Store](https://snapcraft.io/coder)                                     |

---

# Upgrading

Source: https://coder.com/docs/install/upgrade

# Upgrade

This article describes how to upgrade your Coder server.

> [!CAUTION]
> Prior to upgrading a production Coder deployment, take a database snapshot since
> Coder does not support rollbacks.

For upgrade recommendations and troubleshooting, see
[Upgrading Best Practices](./upgrade-best-practices.md).

## Reinstall Coder to upgrade

To upgrade your Coder server, reinstall Coder using your original method
of [install](../install).

### Coder install script

1. If you installed Coder using the `install.sh` script, re-run the below command
   on the host:

   ```shell
   curl -L https://coder.com/install.sh | sh
   ```

1. If you're running Coder as a system service, you can restart it with `systemctl`:

   ```shell
   systemctl daemon-reload
   systemctl restart coder
   ```

### Other upgrade methods

<div class="tabs">

### docker-compose

If you installed using `docker-compose`, run the below command to upgrade the
Coder container:

```shell
docker-compose pull coder && docker-compose up -d coder
```

### Kubernetes

See
[Upgrading Coder via Helm](../install/kubernetes.md#upgrading-coder-via-helm).

### Coder AMI on AWS

1. Run the Coder installation script on the host:

   ```shell
   curl -L https://coder.com/install.sh | sh
   ```

   The script will unpack the new `coder` binary version over the one currently
   installed.

1. Restart the Coder system process with `systemctl`:

   ```shell
   systemctl daemon-reload
   systemctl restart coder
   ```

### Windows

Download the latest Windows installer or binary from
[GitHub releases](https://github.com/coder/coder/releases/latest), or upgrade
from Winget.

```pwsh
winget install Coder.Coder
```

</div>

---

# Upgrading Best Practices

Source: https://coder.com/docs/install/upgrade-best-practices

# Upgrading Best Practices

This guide provides best practices for upgrading Coder, along with
troubleshooting steps for common issues encountered during upgrades,
particularly with database migrations in high availability (HA) deployments.

## Before you upgrade

> [!TIP]
> To check your current Coder version, use `coder version` from the CLI, check
> the bottom-right of the Coder dashboard, or query the `/api/v2/buildinfo`
> endpoint. See the [version command](../reference/cli/version.md) for details.

- **Schedule upgrades during off-peak hours.** Upgrades can cause a noticeable
  disruption to the developer experience. Plan your maintenance window when
  the fewest developers are actively using their workspaces.
- **The larger the version jump, the more migrations will run.** If you are
  upgrading across multiple minor versions, expect longer migration times.
- **Large upgrades should complete in minutes** (typically 4-7 minutes). If your
  upgrade is taking significantly longer, there may be an issue requiring
  investigation.
- **Check for known issues affecting your upgrade path.** Some version upgrades
  have known issues that may require a larger maintenance window or additional
  steps. For example, upgrades from v2.26.0 to v2.27.8 may encounter issues with
  the `api_keys` table—upgrading to v2.26.6 first can help mitigate this.
  Contact [Coder support](../support/index.md) for guidance on your specific
  upgrade path.

## Pre-upgrade strategy for Kubernetes HA deployments

Standard Kubernetes rolling updates may fail when exclusive database locks are
required because old replicas keep connections open. For production deployments
running multiple replicas (HA), active connections from existing pods can
prevent the new pod from acquiring necessary locks.

### Recommended strategy for major upgrades

1. **Scale down before upgrading:** Before running `helm upgrade`, scale your
   Coder deployment down to eliminate database connection contention from
   existing pods.

   - **Scale to zero** for a clean cutover with no active database connections
     when the upgrade starts. This momentarily ensures no application access to
     the database, allowing migrations to acquire locks immediately:

     ```shell
     kubectl scale deployment coder --replicas=0
     ```

   - **Scale to one** if you prefer to minimize downtime. This keeps one pod
     running but eliminates contention from multiple replicas:

     ```shell
     kubectl scale deployment coder --replicas=1
     ```

1. **Perform upgrade:** Run your standard Helm upgrade command. When scaling to
   zero, this will bring up a fresh pod that can run migrations without
   competing for database locks.

1. **Scale back:** Once the upgrade is healthy, scale back to your desired
   replica count.

## Kubernetes liveness probes and long-running migrations

Liveness probes can cause pods to be killed during long-running database
migrations. Starting with Coder v2.30.0, liveness probes are *disabled by
default* in the Helm chart.

This change was made because:

- Liveness probes can kill pods during legitimate long-running migrations
- If a Coder pod becomes unresponsive (due to a deadlock, etc.), it's better to
  investigate the issue rather than have Kubernetes silently restart the pod

If you have enabled liveness probes in your deployment and observe pods
restarting with `CrashLoopBackOff` during an upgrade, the liveness probe may be
killing the pod prematurely.

### Diagnosing liveness probe issues

To confirm whether Kubernetes is killing pods due to liveness probe failures,
check the Kubernetes events and pod logs:

```shell
# Check events for the Coder deployment
kubectl get events --field-selector involvedObject.name=coder -n <namespace>

# Check pod logs for migration progress
kubectl logs -l app.kubernetes.io/name=coder -n <namespace> --previous
```

Look for events indicating `Liveness probe failed` or `Container coder failed
liveness probe, will be restarted`.

### Recommended approach

If you have liveness probes enabled and experience issues during upgrades,
disable them before upgrading:

```shell
kubectl edit deployment coder
```

Remove the `livenessProbe` section entirely, then proceed with the upgrade.

> [!NOTE]
> For versions prior to v2.30.0, liveness probes were enabled by default. You
> can disable them by editing the Deployment directly with `kubectl edit
> deployment coder` or by using a ConfigMap override. See the
> [Helm chart values](https://artifacthub.io/packages/helm/coder-v2/coder?modal=values&path=coder.livenessProbe)
> for configuration options available in v2.30.0+.

### Workaround steps

1. **Remove or adjust liveness probes:** Temporarily remove the `livenessProbe`
   from your Deployment configuration to prevent Kubernetes from restarting the
   pod during migrations.

1. **Isolate the migration:** Ensure all extra replica sets are shut down. If
   you have clear evidence of database locks from old pods, scale the deployment
   to 1 replica to prevent old pods from holding locks on the tables being
   upgraded.

1. **Clear database locks:** Monitor database activity. If the migration remains
   blocked by locks despite scaling down, you may need to manually terminate
   existing connections. See
   [Recovering from failed database migrations](#recovering-from-failed-database-migrations)
   below for instructions.

## Recovering from failed database migrations

If an upgrade gets stuck in a restart loop due to database locks:

1. **Scale to zero:** Scale the Coder deployment to 0 to stop all application
   activity.

   ```shell
   kubectl scale deployment coder --replicas=0
   ```

1. **Clear connections:** Terminate existing connections to the Coder database
   to release any lingering locks. This PostgreSQL command drops all active
   connections to the database:

   > [!CAUTION]
   > This command is intrusive and should be used as a last resort. Contact
   > [Coder support](../support/index.md) before running destructive database
   > commands in production. SQL commands may vary depending on your PostgreSQL
   > version and configuration.

   ```sql
   SELECT pg_terminate_backend(pid)
   FROM pg_stat_activity
   WHERE datname = 'coder'
   AND pid <> pg_backend_pid();
   ```

1. **Check schema migrations:** Verify the level of upgrade and check if `dirty`
   is true. If this has progressed, this now indicates your current Coder
   installation state.

   > [!NOTE]
   > The SQL commands below are for informational purposes. If you are unsure
   > about querying your database directly, contact
   > [Coder support](../support/index.md) for assistance.

   ```sql
   SELECT * FROM schema_migrations;
   ```

1. **Ensure image version:** Confirm the Deployment image is set to the
   appropriate version (old or new, depending on the database migration state
   found in step 3). Match your tag in the
   [migrations directory](https://github.com/coder/coder/tree/main/coderd/database/migrations)
   to the value in the `schema_migrations` output.

1. **Resume the upgrade:** Follow the
   [pre-upgrade strategy](#recommended-strategy-for-major-upgrades) to scale
   back up and continue the upgrade process.

## When to contact support

If you encounter any of the following issues, contact
[Coder support](../support/index.md):

- Locking issues that cannot be mitigated by the steps in this guide
- Migrations taking significantly longer than expected (more than 15 minutes)
  without evidence of lock contention—this may indicate database resource
  constraints requiring investigation
- Resource consumption issues (excessive memory, CPU, or OOM kills) during
  upgrades
- Any other upgrade problems not covered by this documentation

When contacting support, please collect and provide:

- `coderd` logs with details on the stages where the upgrade stalled
- PostgreSQL logs if available
- The Coder versions involved (source and target)
- Your deployment configuration (number of replicas, resource limits)

---

# Uninstall

Source: https://coder.com/docs/install/uninstall

<!-- markdownlint-disable MD024 -->
# Uninstall

This article walks you through how to uninstall your Coder server.

To uninstall your Coder server, delete the following directories.

## The Coder server binary and CLI

<div class="tabs">

## Linux

<div class="tabs">

## Debian, Ubuntu

```shell
sudo apt remove coder
```

## Fedora, CentOS, RHEL, SUSE

```shell
sudo yum remove coder
```

## Alpine

```shell
sudo apk del coder
```

</div>

If you installed Coder manually or used the install script on an unsupported
operating system, you can remove the binary directly:

```shell
sudo rm /usr/local/bin/coder
```

## macOS

```shell
brew uninstall coder
```

If you installed Coder manually, you can remove the binary directly:

```shell
sudo rm /usr/local/bin/coder
```

## Windows

```powershell
winget uninstall Coder.Coder
```

</div>

## Coder as a system service configuration

```shell
sudo rm /etc/coder.d/coder.env
```

## Coder settings, cache, and the optional built-in PostgreSQL database

There is a `postgres` directory within the `coderv2` directory that has the
database engine and database. If you want to reuse the database, consider not
performing the following step or copying the directory to another location.

<div class="tabs">

## Linux

```shell
rm -rf ~/.config/coderv2
rm -rf ~/.cache/coder
```

## macOS

```shell
rm -rf ~/Library/Application\ Support/coderv2
```

## Windows

```powershell
rmdir %AppData%\coderv2
```

</div>

---

# Releases

Source: https://coder.com/docs/install/releases

# Releases

Coder releases are cut directly from main in our
[GitHub](https://github.com/coder/coder) on the first Tuesday of each month.

We recommend enterprise customers test the compatibility of new releases with
their infrastructure on a staging environment before upgrading a production
deployment.

## Release channels

We support four primary release channels, as well as ad-hoc release candidates:

- **Mainline:** The bleeding edge version of Coder
- **Stable:** N-1 of the mainline release
- **Security Support:** N-2 of the mainline release
- **Extended Support Release:** Biannually released version of Coder
- **Release Candidates:** Ad-hoc builds to validate in-development features

We field our mainline releases publicly for one month before promoting them to stable. The security support version, so n-2 from mainline, receives patches
only for security issues or CVEs.

### Mainline releases

- Intended for customers with a staging environment
- Gives earliest access to new features
- May include minor bugs
- All bugfixes and security patches are supported

### Stable releases

- Safest upgrade/installation path
- May not include the latest features
- All bugfixes and security patches are supported

### Security Support

- In-product security vulnerabilities and CVEs are supported

For more information on feature rollout, see our
[feature stages documentation](../releases/feature-stages.md).

### Extended Support Release

- Designed for organizations that prioritize long-term stability
- Receives only critical bugfixes and security patches
- Ideal for regulated environments or large deployments with strict upgrade cycles

ESR releases will be updated with critical bugfixes and security patches that are available to paying customers. This extended support model provides predictable, long-term maintenance for organizations that require enhanced stability. Because ESR forgoes new features in favor of maintenance and stability, it is best suited for teams with strict upgrade constraints. The latest ESR version is [Coder 2.29](https://github.com/coder/coder/releases/tag/v2.29.0).

For more information, see the [Coder ESR announcement](https://coder.com/blog/esr) or our [ESR Upgrade Guide](./esr-2.24-2.29-upgrade.md).

### Release Candidates

- Ad-hoc builds that Coder releases to validate in-development features with select customers
- Not guaranteed to be stable or free of bugs
- Features introduced in an RC are not guaranteed to be included in a mainline or stable release
- Not intended for production use

Release candidates give Coder a way to push out builds for customers and other users to try out new, under-development functionality without cutting a new minor version. Unlike mainline and stable releases, RCs do not follow a fixed schedule and carry no guarantees around stability or long-term support. They exist purely as a feedback mechanism: Coder can ship targeted builds, gather real-world input, and iterate before committing changes to the standard release channels.

## Installing stable

When installing Coder, we generally advise specifying the desired version from
our GitHub [releases page](https://github.com/coder/coder/releases).

You can also use our `install.sh` script with the `stable` flag to install the
latest stable release:

```shell
curl -fsSL https://coder.com/install.sh | sh -s -- --stable
```

Best practices for installing Coder can be found on our [install](../index.md)
pages.

## Release schedule
<!-- Autogenerated release calendar from scripts/update-release-calendar.sh -->
<!-- RELEASE_CALENDAR_START -->
| Release name                                   | Release Date       | Status                   | Latest Release                                                   |
|------------------------------------------------|--------------------|--------------------------|------------------------------------------------------------------|
| [2.24](https://coder.com/changelog/coder-2-24) | July 01, 2025      | Extended Support Release | [v2.24.4](https://github.com/coder/coder/releases/tag/v2.24.4)   |
| [2.26](https://coder.com/changelog/coder-2-26) | September 03, 2025 | Not Supported            | [v2.26.6](https://github.com/coder/coder/releases/tag/v2.26.6)   |
| [2.27](https://coder.com/changelog/coder-2-27) | October 02, 2025   | Not Supported            | [v2.27.11](https://github.com/coder/coder/releases/tag/v2.27.11) |
| [2.28](https://coder.com/changelog/coder-2-28) | November 04, 2025  | Not Supported            | [v2.28.11](https://github.com/coder/coder/releases/tag/v2.28.11) |
| [2.29](https://coder.com/changelog/coder-2-29) | December 02, 2025  | Extended Support Release | [v2.29.10](https://github.com/coder/coder/releases/tag/v2.29.10) |
| [2.30](https://coder.com/changelog/coder-2-30) | February 03, 2026  | Security Support         | [v2.30.7](https://github.com/coder/coder/releases/tag/v2.30.7)   |
| [2.31](https://coder.com/changelog/coder-2-31) | February 23, 2026  | Stable                   | [v2.31.9](https://github.com/coder/coder/releases/tag/v2.31.9)   |
| [2.32](https://coder.com/changelog/coder-2-32) | April 14, 2026     | Mainline                 | [v2.32.0](https://github.com/coder/coder/releases/tag/v2.32.0)   |
| 2.33                                           |                    | Not Released             | N/A                                                              |
<!-- RELEASE_CALENDAR_END -->

> [!TIP]
> We publish a
> [`preview`](https://github.com/coder/coder/pkgs/container/coder-preview) image
> `ghcr.io/coder/coder-preview` on each commit to the `main` branch. This can be
> used to test under-development features and bug fixes that have not yet been
> released to [`mainline`](#mainline-releases) or [`stable`](#stable-releases).
>
> The `preview` image is not intended for production use.

### January Releases

Releases on the first Tuesday of January **are not guaranteed to occur** because most of our team is out for the December holiday period. That being said, an ad-hoc release might still occur. We advise not relying on a January release, or reaching out to Coder directly to determine if one will be occurring closer to the release date.

---

# Feature stages

Source: https://coder.com/docs/install/releases/feature-stages

# Feature stages

Some Coder features are released in feature stages before they are generally
available.

If you encounter an issue with any Coder feature, please submit a
[GitHub issue](https://github.com/coder/coder/issues) or join the
[Coder Discord](https://discord.gg/coder).

## Feature stages

| Feature stage                          | Stable | Production-ready | Support               | Description                                                                                                                   |
|----------------------------------------|--------|------------------|-----------------------|-------------------------------------------------------------------------------------------------------------------------------|
| [Early Access](#early-access-features) | No     | No               | GitHub issues         | For staging only. Not feature-complete or stable. Disabled by default.                                                        |
| [Beta](#beta)                          | No     | Not fully        | Docs, Discord, GitHub | Publicly available. In active development with minor bugs. Suitable for staging; optional for production. Not covered by SLA. |
| [GA](#general-availability-ga)         | Yes    | Yes              | License-based         | Stable and tested. Enabled by default. Fully documented. Support based on license.                                            |

## Early access features

- **Stable**: No
- **Production-ready**: No
- **Support**: GitHub issues

Early access features are neither feature-complete nor stable. We do not
recommend using early access features in production deployments.

Coder sometimes releases early access features that are available for use, but
are disabled by default. You shouldn't use early access features in production
because they might cause performance or stability issues. Early access features
can be mostly feature-complete, but require further internal testing and remain
in the early access stage for at least one month.

Coder may make significant changes or revert features to a feature flag at any
time.

If you plan to activate an early access feature, we suggest that you use a
staging deployment.

<details><summary>To enable early access features:</summary>

Use the [Coder CLI](../../install/cli.md) `--experiments` flag to enable early
access features:

- Enable all early access features:

  ```shell
  coder server --experiments=*
  ```

- Enable multiple early access features:

  ```shell
  coder server --experiments=feature1,feature2
  ```

You can also use the `CODER_EXPERIMENTS`
[environment variable](../../admin/setup/index.md).

You can opt-out of a feature after you've enabled it.

</details>

### Available early access features

<!-- Code generated by scripts/release/docs_update_feature_stages.sh. DO NOT EDIT. -->
<!-- BEGIN: available-experimental-features -->
Currently no experimental features are available in the latest mainline or stable release.
<!-- END: available-experimental-features -->

## Beta

- **Stable**: No
- **Production-ready**: Not fully
- **Support**: Documentation, [Discord](https://discord.gg/coder), and
  [GitHub issues](https://github.com/coder/coder/issues)

Beta features are open to the public and are tagged with a `Beta` label.

They’re in active development and subject to minor changes. They might contain
minor bugs, but are generally ready for use.

Beta features are often ready for general availability within two-three
releases. You should test beta features in staging environments. You can use
beta features in production, but should set expectations and inform users that
some features may be incomplete.

We keep documentation about beta features up-to-date with the latest
information, including planned features, limitations, and workarounds. If you
encounter an issue, please contact your
[Coder account team](https://coder.com/contact), reach out on
[Discord](https://discord.gg/coder), or create a
[GitHub issues](https://github.com/coder/coder/issues) if there isn't one
already. While we will do our best to provide support with beta features, most
issues will be escalated to the product team. Beta features are not covered
within service-level agreements (SLA).

Most beta features are enabled by default. Beta features are announced through
the [Coder Changelog](https://coder.com/changelog), and more information is
available in the documentation.

### Available beta features

<!-- Code generated by scripts/release/docs_update_feature_stages.sh. DO NOT EDIT. -->
<!-- BEGIN: available-beta-features -->
| Feature                                                                      | Description                                    | Available in     |
|------------------------------------------------------------------------------|------------------------------------------------|------------------|
| [MCP Server](../../ai-coder/mcp-server.md)                                   | Connect to agents Coder with a MCP server      | mainline, stable |
| [JetBrains Toolbox](../../user-guides/workspace-access/jetbrains/toolbox.md) | Access Coder workspaces from JetBrains Toolbox | mainline, stable |
| Agent Firewall                                                               | Understanding Agent Firewall in Coder Tasks    | stable           |
| [Workspace Sharing](../../user-guides/shared-workspaces.md)                  | Sharing workspaces                             | mainline, stable |
<!-- END: available-beta-features -->

## General Availability (GA)

- **Stable**: Yes
- **Production-ready**: Yes
- **Support**: Yes, [based on license](https://coder.com/pricing).

All features that are not explicitly tagged as `Early access` or `Beta` are
considered generally available (GA). They have been tested, are stable, and are
enabled by default.

If your Coder license includes an SLA, please consult it for an outline of
specific expectations.

For support, consult our knowledgeable and growing community on
[Discord](https://discord.gg/coder), or create a
[GitHub issue](https://github.com/coder/coder/issues) if one doesn't exist
already. Customers with a valid Coder license, can submit a support request or
contact your [account team](https://coder.com/contact).

We intend [Coder documentation](../../README.md) to be the
[single source of truth](https://en.wikipedia.org/wiki/Single_source_of_truth)
and all features should have some form of complete documentation that outlines
how to use or implement a feature. If you discover an error or if you have a
suggestion that could improve the documentation, please
[submit a GitHub issue](https://github.com/coder/internal/issues/new?title=request%28docs%29%3A+request+title+here&labels=["customer-feedback","docs"]&body=please+enter+your+request+here).

Some GA features can be disabled for air-gapped deployments. Consult the
feature's documentation or submit a support ticket for assistance.

---

# Upgrading from ESR 2.24 to 2.29

Source: https://coder.com/docs/install/releases/esr-2.24-2.29-upgrade

# Upgrading from ESR 2.24 to 2.29

## Guide Overview

Coder provides Extended Support Releases (ESR) bianually. This guide walks
through upgrading from the initial Coder 2.24 ESR to our new 2.29 ESR. It will
summarize key changes, highlight breaking updates, and provide a recommended
upgrade process.

Read more about the ESR release process
[here](./index.md#extended-support-release), and how Coder supports it.

## What's New in Coder 2.29

### Coder Tasks

Coder Tasks is an interface for running and interfacing with terminal-based
coding agents like Claude Code and Codex, powered by Coder workspaces. Beginning
in Coder 2.24, Tasks were introduced as an experimental feature that allowed
administrators and developers to run long-lived or automated operations from
templates. Over subsequent releases, Tasks matured significantly through UI
refinement, improved reliability, and underlying task-status improvements in the
server and database layers. By 2.29, Tasks were formally promoted to general
availability, with full CLI support, a task-specific UI, and consistent
visibility of task states across the dashboard. This transition establishes
Tasks as a stable automation and job-execution primitive within
Coder—particularly suited for long-running background operations like bug fixes,
documentation generation, PR reviews, and testing/QA.For more information, read
our documentation [here](https://coder.com/docs/ai-coder/tasks).

### AI Gateway

AI Gateway was introduced in 2.26, and is a smart gateway that acts as an
intermediary between users' coding agents/IDEs and AI providers like OpenAI and
Anthropic. It solves three key problems:

- Centralized authentication/authorization management (users authenticate via
  Coder instead of managing individual API tokens)
- Auditing and attribution of all AI interactions (whether autonomous or
  human-initiated)
- Secure communication between the Coder control plane and upstream AI APIs

This is a Premium/Beta feature that intercepts AI traffic to record prompts,
token usage, and tool invocations. For more information, read our documentation
[here](../../ai-coder/ai-gateway/index.md).

### Agent Firewall

Agent Firewall was introduced in 2.27 and is currently in Early Access. Agent
Firewall is a process-level firewall in Coder that restricts and audits what
autonomous programs (like AI agents) can access and do within a workspace. They
provide network policy enforcement—blocking specific domains and HTTP verbs to
prevent data exfiltration—and write logs to the workspace for auditability.
Agent Firewall supports any terminal-based agent, including custom ones, and can be
easily configured through existing Coder modules like the Claude Code module.
For more information, read our documentation
[here](../../ai-coder/agent-firewall/index.md).

### Performance Enhancements

Performance, particularly at scale, improved across nearly every system layer.
Database queries were optimized, several new indexes were added, and expensive
migrations—such as migration 371—were reworked to complete faster on large
deployments. Caching was introduced for Terraform installer files and
workspace/agent lookups, reducing repeated calls. Notification performance
improved through more efficient connection pooling. These changes collectively
enable deployments with hundreds or thousands of workspaces to operate more
smoothly and with lower resource contention.

### Server and API Updates

Core server capabilities expanded significantly across the releases. Prebuild
workflows gained timestamp-driven invalidation via last_invalidated_at, expired
API keys began being automatically purged, and new API key-scope documentation
was introduced to help administrators understand authorization boundaries. New
API endpoints were added, including the ability to modify a task prompt or look
up tasks by name. Template developers benefited from new Terraform
directory-persistence capabilities (opt-in on a per-template basis) and improved
`protobuf` configuration metadata.

### CLI Enhancements

The CLI gained substantial improvements between the two versions. Most notably,
beginning in 2.29, Coder’s CLI now stores session tokens in the operating system
keyring by default on macOS and Windows, enhancing credential security and
reducing exposure from plaintext token storage. Users who rely on directly
accessing the token file can opt out using `--use-keyring=false`. The CLI also
introduced cross-platform support for keyring storage, gained support for GA
Task commands, and integrated experimental functionality for the new Agent
Socket API.

## Changes to be Aware of

The following are changes introduced after 2.24.X that might break workflows, or
require other manual effort to address:

| Initial State (2.24 & before)                                      | New State (2.25–2.29)                                                                                 | Change Required                                                                                                                                                                                                                                                                 |
|--------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Workspace updates occur in place without stopping                  | Workspace updates now forcibly stop workspaces before updating                                        | Expect downtime during updates; update any scripted update flows that rely on seamless updates. See [`coder update` CLI reference](https://coder.com/docs/reference/cli/update).                                                                                                |
| Connection events (SSH, port-forward, browser) logged in Audit Log | Connection events moved to Connection Log; historical entries older than 90 days pruned               | Update compliance, audit, or ingestion pipelines to use the new [Connection Log](https://coder.com/docs/admin/monitoring/connection-logs) instead of [Audit Logs](https://coder.com/docs/admin/security/audit-logs) for connection events.                                      |
| CLI session tokens stored in plaintext file                        | CLI session tokens stored in OS keyring (macOS/Windows)                                               | Update scripts, automation, or SSO flows that read/modify the token file, or use `--use-keyring=false`. See [Sessions & API Tokens](https://coder.com/docs/admin/users/sessions-tokens) and [`coder login` CLI reference](https://coder.com/docs/reference/cli/login).          |
| `task_app_id` field available in `codersdk.WorkspaceBuild`         | `task_app_id` removed from `codersdk.WorkspaceBuild`                                                  | Migrate integrations to use `Task.WorkspaceAppID` instead. See [REST API reference](https://coder.com/docs/reference/api).                                                                                                                                                      |
| OIDC session handling more permissive                              | Sessions expire when access tokens expire (typically 1 hour) unless refresh tokens are configured     | Add `offline_access` to `CODER_OIDC_SCOPES` (e.g., `openid,profile,email,offline_access`); Google requires `CODER_OIDC_AUTH_URL_PARAMS='{"access_type":"offline","prompt":"consent"}'`. See [OIDC Refresh Tokens](https://coder.com/docs/admin/users/oidc-auth/refresh-tokens). |
| Devcontainer agent selection is random when multiple agents exist  | Devcontainer agent selection requires explicit choice                                                 | Update automated workflows to explicitly specify agent selection. See [Dev Containers Integration](https://coder.com/docs/user-guides/devcontainers) and [Configure a template for dev containers](https://coder.com/docs/admin/templates/extending-templates/devcontainers).   |
| Terraform execution uses clean directories per build               | Terraform workflows use persistent or cached directories when enabled                                 | Update templates that rely on clean execution directories or per-build isolation. See [External Provisioners](https://coder.com/docs/admin/provisioners) and [Template Dependencies](https://coder.com/docs/admin/templates/managing-templates/dependencies).                   |
| Agent and task lifecycle behaviors more permissive                 | Agent and task lifecycle behaviors enforce stricter permission checks, readiness gating, and ordering | Review workflows for compatibility with stricter readiness and permission requirements. See [Workspace Lifecycle](https://coder.com/docs/user-guides/workspace-lifecycle) and [Extending Templates](https://coder.com/docs/admin/templates/extending-templates).                |

## Upgrading

The following are recommendations by the Coder team when performing the upgrade:

- **Perform the upgrade in a staging environment first:** The cumulative changes
  between 2.24 and 2.29 introduce new subsystems and lifecycle behaviors, so
  validating templates, authentication flows, and workspace operations in
  staging helps avoid production issues
- **Audit scripts or tools that rely on the CLI token file:** Since 2.29 uses
  the OS keyring for session tokens on macOS and Windows, update any tooling
  that reads the plaintext token file or plan to use `--use-keyring=false`
- **Review templates using devcontainers or Terraform:** Explicit agent
  selection, optional persistent/cached Terraform directories, and updated
  metadata handling mean template authors should retest builds and startup
  behavior
- **Check and update OIDC provider configuration:** Stricter refresh-token
  requirements in later releases can cause unexpected logouts or failed CLI
  authentication if providers are not configured according to updated docs
- **Update integrations referencing deprecated API fields:** Code relying on
  `WorkspaceBuild.task_app_id` must migrate to `Task.WorkspaceAppID`, and any
  custom integrations built against 2.24 APIs should be validated against the
  new SDK
- **Communicate audit-logging changes to security/compliance teams:** From 2.25
  onward, connection events moved into the Connection Log, and older audit
  entries may be pruned, which can affect SIEM pipelines or compliance workflows
- **Validate workspace lifecycle automation:** Since updates now require
  stopping the workspace first, confirm that automated update jobs, scripts, or
  scheduled tasks still function correctly in this new model
- **Retest agent and task automation built on early experimental features:**
  Updates to agent readiness, permission checks, and lifecycle ordering may
  affect workflows developed against 2.24’s looser behaviors
- **Monitor workspace, template, and Terraform build performance:** New caching,
  indexes, and DB optimizations may change build times; observing performance
  post-upgrade helps catch regressions early
- **Prepare user communications around Tasks and UI changes:** Tasks are now GA
  and more visible in the dashboard, and many UI improvements will be new to
  users coming from 2.24, so a brief internal announcement can smooth the
  transition

---

# User Guides

Source: https://coder.com/docs/user-guides

# User Guides

These guides contain information on workspace management, workspace access via
IDEs, environment personalization, and workspace scheduling.

These are intended for end-user flows only. If you are an administrator, please
refer to our docs on configuring [templates](../admin/index.md) or the
[control plane](../admin/index.md).

Check out [Dev Containers integration](./devcontainers/index.md) for running
containerized development environments in your Coder workspace.

<children></children>

---

# Access Workspaces

Source: https://coder.com/docs/user-guides/workspace-access

# Access your workspace

There are many ways to connect to your workspace, the options are only limited
by the template configuration.

Deployment operators can learn more about different types of workspace
connections and performance in our
[networking docs](../../admin/infrastructure/index.md).

You can see the primary methods of connecting to your workspace in the workspace
dashboard.

![Workspace View](../../images/user-guides/workspace-view-connection-annotated.png)

## Web Terminal

The Web Terminal is a browser-based terminal that provides instant access to
your workspace's shell environment. It uses [xterm.js](https://xtermjs.org/)
and WebSocket technology for a responsive terminal experience with features
like persistent sessions, Unicode support, and clickable URLs.

![Terminal Access](../../images/user-guides/terminal-access.png)

Read the complete [Web Terminal documentation](./web-terminal.md) for
customization options, keyboard shortcuts, and troubleshooting guides.

## SSH

### Through with the CLI

Coder will use the optimal path for an SSH connection (determined by your
deployment's [networking configuration](../../admin/infrastructure/index.md))
when using the CLI:

```console
coder ssh my-workspace
```

Or, you can configure plain SSH on your client below.

> [!Note]
> The `coder ssh` command does not have full parity with the standard
> SSH command. For users who need the full functionality of SSH, use the
> configuration method below.

### Configure SSH

Coder generates [SSH key pairs](../../admin/security/secrets.md#ssh-keys) for
each user to simplify the setup process.

1. Use your terminal to authenticate the CLI with Coder web UI and your workspaces:

   ```bash
   coder login <accessURL>
   ```

1. Access Coder via SSH:

   ```shell
   coder config-ssh
   ```

1. Run `coder config-ssh --dry-run` if you'd like to see the changes that will be
   before you proceed:

   ```shell
   coder config-ssh --dry-run
   ```

1. Confirm that you want to continue by typing **yes** and pressing enter. If
successful, you'll see the following message:

   ```console
   You should now be able to ssh into your workspace.
   For example, try running:

   $ ssh coder.<workspaceName>
   ```

Your workspace is now accessible via `ssh coder.<workspace_name>`
(for example, `ssh coder.myEnv` if your workspace is named `myEnv`).

## Visual Studio Code

You can develop in your Coder workspace remotely with
[VS Code](https://code.visualstudio.com/download).
We support connecting with the desktop client and VS Code in the browser with [code-server](#code-server).

![Demo](https://github.com/coder/vscode-coder/raw/main/demo.gif?raw=true)

Read more details on [using VS Code in your workspace](./vscode.md).

## Cursor

[Cursor](https://cursor.sh/) is an IDE built on VS Code with enhanced AI capabilities.
Cursor connects using the Coder extension.

Read more about [using Cursor with your workspace](./cursor.md).

## Windsurf

[Windsurf](./windsurf.md) is Codeium's code editor designed for AI-assisted development.
Windsurf connects using the Coder extension.

## Antigravity

[Antigravity](https://antigravity.google/) is Google's desktop IDE.
Antigravity connects using the Coder extension.

Read more about [using Antigravity with your workspace](./antigravity.md).

## JetBrains IDEs

We support JetBrains IDEs using
[Gateway](https://www.jetbrains.com/remote-development/gateway/). The following
IDEs are supported for remote development:

- IntelliJ IDEA
- CLion
- GoLand
- PyCharm
- Rider
- RubyMine
- WebStorm
- [JetBrains Fleet](./jetbrains/fleet.md)

Read our [docs on JetBrains](./jetbrains/index.md) for more information
on connecting your JetBrains IDEs.

## code-server

[code-server](https://github.com/coder/code-server) is our supported method of
running VS Code in the web browser.
Learn more about [what makes code-server different from VS Code web](./code-server.md) or visit the
[documentation for code-server](https://coder.com/docs/code-server/latest).

![code-server in a workspace](../../images/code-server-ide.png)

## Other Web IDEs

We support a variety of other browser IDEs and tools to interact with your
workspace. Each of these can be configured by your template admin using our
[Web IDE guides](../../admin/templates/extending-templates/web-ides.md).

Supported IDEs:

- VS Code Web
- JupyterLab
- RStudio
- Airflow
- File Browser

Our [Module Registry](https://registry.coder.com/modules) also hosts a variety
of tools for extending the capability of your workspace. If you have a request
for a new IDE or tool, please file an issue in our
[Modules repo](https://github.com/coder/registry/issues).

## Ports and Port forwarding

You can manage listening ports on your workspace page through with the listening
ports window in the dashboard. These ports are often used to run internal
services or preview environments.

You can also [share ports](./port-forwarding.md#sharing-ports) with other users,
or [port-forward](./port-forwarding.md#the-coder-port-forward-command) through
the CLI with `coder port forward`. Read more in the
[docs on workspace ports](./port-forwarding.md).

![Open Ports window](../../images/networking/listeningports.png)

## Remote Desktops

Coder also supports connecting with an RDP solution, see our
[RDP guide](./remote-desktops.md) for details.

---

# Visual Studio Code

Source: https://coder.com/docs/user-guides/workspace-access/vscode

# Visual Studio Code

You can develop in your Coder workspace remotely with
[VS Code](https://code.visualstudio.com/download).
We support connecting with the desktop client and VS Code in the browser with
[code-server](https://github.com/coder/code-server).
Learn more about how VS Code Web and code-server compare in the
[code-server doc](./code-server.md).

## VS Code Desktop

VS Code desktop is a default app for workspaces.

Click `VS Code Desktop` in the dashboard to one-click enter a workspace. This
automatically installs the [Coder Remote](https://github.com/coder/vscode-coder)
extension, authenticates with Coder, and connects to the workspace.

![Demo](https://github.com/coder/vscode-coder/raw/main/demo.gif?raw=true)

> [!NOTE]
> The `VS Code Desktop` button can be hidden by enabling
> [Browser-only connections](../../admin/networking/index.md#browser-only-connections).

### Manual Installation

You can install our extension manually in VS Code using the command palette.
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press
enter.

```text
ext install coder.coder-remote
```

Alternatively, manually install the VSIX from the
[latest release](https://github.com/coder/vscode-coder/releases/latest).

## VS Code extensions

There are multiple ways to add extensions to VS Code Desktop:

1. Using the
   [public extensions marketplaces](#using-the-public-extensions-marketplaces)
   with Code Web (code-server)
1. Adding [extensions to custom images](#adding-extensions-to-custom-images)
1. Installing extensions
   [using its `vsix` file at the command line](#installing-extensions-using-its-vsix-file-at-the-command-line)
1. Installing extensions
   [from a marketplace using the command line](#installing-from-a-marketplace-at-the-command-line)

### Using the public extensions marketplaces

You can manually add an extension while you're working in the Code Web IDE. The
extensions can be from Coder's public marketplace, Eclipse Open VSX's public
marketplace, or the Eclipse Open VSX _local_ marketplace.

![Code Web Extensions](../../images/ides/code-web-extensions.png)

> [!NOTE]
> Microsoft does not allow any unofficial VS Code IDE to connect to the
> extension marketplace.

### Adding extensions to custom images

You can add extensions to a custom image and install them either through Code
Web or using the workspace's terminal.

1. Download the extension(s) from the Microsoft public marketplace.

   ![Code Web Extensions](../../images/ides/copilot.png)

1. Add the `vsix` extension files to the same folder as your Dockerfile.

   ```shell
   ~/images/base
    ➜  ls -l
    -rw-r--r-- 1 coder coder       0 Aug 1 19:23 Dockerfile
    -rw-r--r-- 1 coder coder 8925314 Aug 1 19:40 GitHub.copilot.vsix
   ```

1. In the Dockerfile, add instructions to make a folder and to copy the `vsix`
   files into the newly created folder.

   ```Dockerfile
   FROM codercom/enterprise-base:ubuntu

   # Run below commands as root user
   USER root

   # Download and install VS Code extensions into the container
   RUN mkdir -p /vsix
   ADD ./GitHub.copilot.vsix /vsix

   USER coder
   ```

1. Build the custom image, and push it to your image registry.

1. Pass in the image and below command into your template `startup_script` (be
   sure to update the filename below):

   **Startup Script**

   ```tf
   resource "coder_agent" "main" {
     ...
     startup_script = "code-server --install-extension /vsix/GitHub.copilot.vsix"
   }
   ```

   **Image Definition**

   ```tf
   resource "kubernetes_deployment" "main" {
     spec {
       template {
         spec {
           container {
             name   = "dev"
             image  = "registry.internal/image-name:tag"
           }
         }
       }
     }
   }
   ```

1. Create a workspace using the template.

You will now have access to the extension in your workspace.

### Installing extensions using its `vsix` file at the command line

Using the workspace's terminal or the terminal available inside `code-server`,
you can install an extension whose files you've downloaded from a marketplace:

```console
/path/to/code-server --install-extension /vsix/GitHub.copilot.vsix
```

### Installing from a marketplace at the command line

Using the workspace's terminal or the terminal available inside Code Web (code
server), run the following to install an extension (be sure to update the
snippets with the name of the extension you want to install):

```console
SERVICE_URL=https://extensions.coder.com/api ITEM_URL=https://extensions.coder.com/item /path/to/code-server --install-extension GitHub.copilot
```

Alternatively, you can install an extension from Open VSX's public marketplace:

```console
SERVICE_URL=https://open-vsx.org/vscode/gallery ITEM_URL=https://open-vsx.org/vscode/item /path/to/code-server --install-extension GitHub.copilot
```

### Using VS Code Desktop

For your local VS Code to pickup extension files in your Coder workspace,
include this command in your `startup_script`, or run in manually in your
workspace terminal:

```console
code --extensions-dir ~/.vscode-server/extensions --install-extension "$extension"
```

---

# Web Terminal

Source: https://coder.com/docs/user-guides/workspace-access/web-terminal

# Web Terminal

The Web Terminal is a browser-based terminal interface that provides instant
access to your workspace's shell environment directly from the Coder dashboard.
It's automatically enabled for all workspaces and requires no additional
configuration.

![Terminal Access](../../images/user-guides/terminal-access.png)

## Overview

The Web Terminal leverages [xterm.js](https://xtermjs.org/), an industry-standard
terminal emulator, combined with WebSocket technology to provide a responsive
and feature-rich terminal experience in your browser.

### Key Features

- **Instant Access**: Click the terminal icon in your workspace to open a shell
  session
- **Persistent Sessions**: Sessions are maintained using reconnection tokens,
  allowing you to resume your terminal even after page refreshes or network
  interruptions
- **Full Unicode Support**: Displays international characters and emojis
  correctly
- **Clickable Links**: Automatically detects and makes URLs clickable
- **Copy/Paste Support**: Select text to automatically copy it to your clipboard
- **Multiple Rendering Options**: Choose between different rendering engines for
  optimal performance

## Accessing the Terminal

### From the Dashboard

1. Navigate to your workspace in the Coder dashboard
2. Click the **Terminal** button or icon
3. The terminal will open in a new browser tab or window

The terminal automatically connects to your workspace agent using an optimized
WebSocket connection.

### Direct URL Access

You can also bookmark or share direct terminal URLs:

```text
https://coder.example.com/@username/workspace-name/terminal
```

To access a specific agent in a multi-agent workspace:

```text
https://coder.example.com/@username/workspace-name.agent-name/terminal
```

## Architecture

### How It Works

The Web Terminal creates a persistent connection between your browser and the
workspace:

1. **Browser**: Renders the terminal using xterm.js
2. **WebSocket**: Maintains a persistent, low-latency connection
3. **Coder Server**: Routes traffic between browser and workspace
4. **Workspace Agent**: Manages the pseudo-terminal (PTY) session
5. **Shell Process**: Your actual bash/zsh/fish shell

The connection flow is: Browser ↔ WebSocket ↔ Coder Server ↔ Workspace Agent ↔ Shell Process

### Reconnection & Persistence

The terminal uses reconnection tokens to maintain session state:

- Each terminal session has a unique UUID
- If the connection drops, the same token is used to reconnect
- The workspace agent buffers output during disconnections
- Your shell session continues running even when the browser is closed

## Customization

### Font Selection

You can customize the terminal font through your user settings:

1. Click your avatar in the top-right corner
2. Select **Settings** → **Appearance**
3. Choose from available fonts:
   - **Geist Mono** (default)
   - **IBM Plex Mono**
   - **Fira Code** (with ligatures)
   - **JetBrains Mono**
   - **Source Code Pro**

The font change applies immediately to all open terminal sessions.

### Rendering Engine

Administrators can configure the terminal renderer for performance optimization:

```yaml
# In your Coder deployment configuration
webTerminalRenderer: "canvas"  # Options: canvas, webgl, dom
```

Or via environment variable:

```bash
CODER_WEB_TERMINAL_RENDERER=canvas
```

**Renderer Options:**

- **`canvas`** (default): Best compatibility, good performance on most systems
- **`webgl`**: Hardware-accelerated, ideal for high-refresh terminals and
  complex rendering
- **`dom`**: Fallback option, useful for accessibility tools or older browsers

> **Note:** The renderer setting is deployment-wide and requires a Coder server
> restart to take effect.

## Keyboard Shortcuts

The Web Terminal supports standard terminal keybindings:

| Shortcut                            | Action                    |
|-------------------------------------|---------------------------|
| `Ctrl+Shift+C` (Mac: `Cmd+Shift+C`) | Copy selected text        |
| `Ctrl+Shift+V` (Mac: `Cmd+Shift+V`) | Paste from clipboard      |
| `Shift+Enter`                       | Insert literal newline    |
| `Ctrl+C`                            | Send interrupt (SIGINT)   |
| `Ctrl+D`                            | Send EOF / exit shell     |
| `Ctrl+Z`                            | Suspend process (SIGTSTP) |

### Copy/Paste Behavior

- **Auto-copy**: Selecting text automatically copies it to your clipboard
- **Paste**: Use the standard paste shortcut or middle-click (on Linux/X11)
- **Browser permissions**: First paste may prompt for clipboard access

## URL Handling

The terminal automatically detects URLs and makes them clickable. When you click
a URL:

- **External URLs** (e.g., `https://example.com`) open in a new tab
- **Localhost URLs** (e.g., `http://localhost:3000`) are automatically
  port-forwarded through Coder's [port forwarding](./port-forwarding.md) system
- **Port-forwarded URLs** use your configured workspace proxy

This makes it seamless to open development servers running in your workspace.

## Advanced Usage

### Custom Commands

You can open a terminal with a specific command by adding a query parameter:

```text
https://coder.example.com/@user/workspace/terminal?command=htop
```

When a `?command=` parameter is present, a confirmation dialog is shown before
the command executes. The user must click **Run command** to proceed or
**Cancel** to close the terminal window. This prevents external links from
silently executing arbitrary commands in a workspace.

Template-configured apps that use the `command` attribute in
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
are trusted and bypass the confirmation dialog. These apps use the `?app=`
parameter internally, which resolves the command from the agent's app list.

### Container Selection

For workspaces with multiple Docker containers, specify which container to
connect to:

```text
https://coder.example.com/@user/workspace/terminal?container=sidecar
```

You can also specify the container user:

```text
https://coder.example.com/@user/workspace/terminal?container=app&container_user=node
```

> **Note:** This feature only works with Docker containers.

### Debug Mode

Enable debug information to monitor connection latency:

```text
https://coder.example.com/@user/workspace/terminal?debug
```

This displays the current latency to your selected workspace proxy in the
bottom-right corner.

## Configuration File Support

The Web Terminal uses xterm.js under the hood, which is configured
programmatically rather than through a configuration file. However, you can
customize various aspects:

### User-Side Customization

End-users can customize:

- **Font family** via Settings → Appearance
- **Shell environment** via dotfiles or shell rc files
- **TERM variable** is automatically set to `xterm-256color`

### Shell Configuration

The terminal respects your shell's configuration files:

```bash
# ~/.bashrc or ~/.zshrc
export PS1="\u@\h:\w\$ "  # Custom prompt
alias ll="ls -lah"         # Custom aliases

# Set terminal colors
export CTERM=xterm-256color
```

## Troubleshooting

### Connection Issues

If the terminal fails to connect:

1. **Check workspace status**: Ensure your workspace is running
2. **Verify agent health**: Look for agent connection warnings
3. **Network issues**: Check if WebSockets are blocked by your firewall/proxy
4. **Browser console**: Open DevTools to see WebSocket error messages

### Display Issues

If characters or colors appear incorrect:

1. **Unicode support**: Ensure your shell locale is set correctly (`locale -a`)
2. **Terminal type**: The terminal sets `TERM=xterm-256color` automatically
3. **Color schemes**: Some applications may not render correctly in dark mode
4. **Font rendering**: Try switching terminal fonts in your appearance settings

---

# JetBrains IDEs

Source: https://coder.com/docs/user-guides/workspace-access/jetbrains

# JetBrains IDEs

Coder supports JetBrains IDEs using [Toolbox](https://www.jetbrains.com/toolbox/) and [Gateway](https://www.jetbrains.com/remote-development/gateway/). The following
IDEs are supported for remote development:

- IntelliJ IDEA
- CLion
- GoLand
- PyCharm
- Rider
- RubyMine
- WebStorm
- PhpStorm
- RustRover
- [JetBrains Fleet](./fleet.md)

> [!IMPORTANT]
> Remote development works with paid and non-commercial licenses of JetBrains IDEs

<children></children>

If you experience any issues, please
[create a GitHub issue](https://github.com/coder/coder/issues) or ask in
[our Discord channel](https://discord.gg/coder).

---

# JetBrains Fleet

Source: https://coder.com/docs/user-guides/workspace-access/jetbrains/fleet

# JetBrains Fleet

JetBrains Fleet is a code editor and lightweight IDE designed to support various
programming languages and development environments.

[See JetBrains's website](https://www.jetbrains.com/fleet/) to learn more about Fleet.

To connect Fleet to a Coder workspace:

1. [Install Fleet](https://www.jetbrains.com/fleet/download)

1. Install Coder CLI

   ```shell
   curl -L https://coder.com/install.sh | sh
   ```

1. Login and configure Coder SSH.

   ```shell
   coder login coder.example.com
   coder config-ssh
   ```

1. Connect via SSH with the Host set to `coder.workspace-name`
   ![Fleet Connect to Coder](../../../images/fleet/ssh-connect-to-coder.png)

---

# JetBrains Gateway

Source: https://coder.com/docs/user-guides/workspace-access/jetbrains/gateway

## JetBrains Gateway

> [! WARNING]
> Using Coder through JetBrains Gateway is not recommended at this time. Instead, we suggest using [JetBrains Toolbox](https://coder.com/docs/user-guides/workspace-access/jetbrains/toolbox) for stability and performance benefits. If you are currently using Gateway, we recommend [migration](https://www.jetbrains.com/help/toolbox-app/jetbrains-gateway-migrations-guide.html).

JetBrains Gateway is a compact desktop app that allows you to work remotely with
a JetBrains IDE without downloading one. Visit the
[JetBrains Gateway website](https://www.jetbrains.com/remote-development/gateway/)
to learn more about Gateway.

Gateway can connect to a Coder workspace using Coder's Gateway plugin or through a
manually configured SSH connection.

### How to use the plugin

> [!NOTE]
> If you experience problems, please
> [create a GitHub issue](https://github.com/coder/coder/issues) or share in
> [our Discord channel](https://discord.gg/coder).

1. [Install Gateway](https://www.jetbrains.com/help/idea/jetbrains-gateway.html)
   and open the application.
1. Under **Install More Providers**, find the Coder icon and click **Install**
   to install the Coder plugin.
1. After Gateway installs the plugin, it will appear in the **Run the IDE
   Remotely** section.

   Click **Connect to Coder** to launch the plugin:

   ![Gateway Connect to Coder](../../../images/gateway/plugin-connect-to-coder.png)

1. Enter your Coder deployment's
   [Access Url](../../../admin/setup/index.md#access-url) and click **Connect**.

   Gateway opens your Coder deployment's `cli-auth` page with a session token.
   Click the copy button, paste the session token in the Gateway **Session
   Token** window, then click **OK**:

   ![Gateway Session Token](../../../images/gateway/plugin-session-token.png)

1. To create a new workspace:

   Click the <kbd>+</kbd> icon to open a browser and go to the templates page in
   your Coder deployment to create a workspace.

1. If a workspace already exists but is stopped, select the workspace from the
   list, then click the green arrow to start the workspace.

1. When the workspace status is **Running**, click **Select IDE and Project**:

   ![Gateway IDE List](../../../images/gateway/plugin-select-ide.png)

1. Select the JetBrains IDE for your project and the project directory then
   click **Start IDE and connect**:

   ![Gateway Select IDE](../../../images/gateway/plugin-ide-list.png)

   Gateway connects using the IDE you selected:

   ![Gateway IDE Opened](../../../images/gateway/gateway-intellij-opened.png)

   The JetBrains IDE is remotely installed into `~/.cache/JetBrains/RemoteDev/dist`.

### Update a Coder plugin version

1. Click the gear icon at the bottom left of the Gateway home screen, then
   **Settings**.

1. In the **Marketplace** tab within Plugins, enter Coder and if a newer plugin
   release is available, click **Update** then **OK**:

   ![Gateway Settings and Marketplace](../../../images/gateway/plugin-settings-marketplace.png)

### Configuring the Gateway plugin to use internal certificates

When you attempt to connect to a Coder deployment that uses internally signed
certificates, you might receive the following error in Gateway:

```console
Failed to configure connection to https://coder.internal.enterprise/: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
```

To resolve this issue, you will need to add Coder's certificate to the Java
trust store present on your local machine as well as to the Coder plugin settings.

1. Add the certificate to the Java trust store:

   <div class="tabs">

   #### Linux

   ```none
   <Gateway installation directory>/jbr/lib/security/cacerts
   ```

   Use the `keytool` utility that ships with Java:

   ```shell
   keytool -import -alias coder -file <certificate> -keystore /path/to/trust/store
   ```

   #### macOS

   ```none
   <Gateway installation directory>/jbr/lib/security/cacerts
   /Library/Application Support/JetBrains/Toolbox/apps/JetBrainsGateway/ch-0/<app-id>/JetBrains Gateway.app/Contents/jbr/Contents/Home/lib/security/cacerts # Path for Toolbox installation
   ```

   Use the `keytool` included in the JetBrains Gateway installation:

   ```shell
   keytool -import -alias coder -file cacert.pem -keystore /Applications/JetBrains\ Gateway.app/Contents/jbr/Contents/Home/lib/security/cacerts
   ```

   #### Windows

   ```none
   C:\Program Files (x86)\<Gateway installation directory>\jre\lib\security\cacerts\%USERPROFILE%\AppData\Local\JetBrains\Toolbox\bin\jre\lib\security\cacerts # Path for Toolbox installation
   ```

   Use the `keytool` included in the JetBrains Gateway installation:

   ```powershell
   & 'C:\Program Files\JetBrains\JetBrains Gateway <version>/jbr/bin/keytool.exe' 'C:\Program Files\JetBrains\JetBrains Gateway <version>/jre/lib/security/cacerts' -import -alias coder -file <cert>

   # command for Toolbox installation
   & '%USERPROFILE%\AppData\Local\JetBrains\Toolbox\apps\Gateway\ch-0\<VERSION>\jbr\bin\keytool.exe' '%USERPROFILE%\AppData\Local\JetBrains\Toolbox\bin\jre\lib\security\cacerts' -import -alias coder -file <cert>
   ```

   </div>

1. In JetBrains, go to **Settings** > **Tools** > **Coder**.

1. Paste the path to the certificate in **CA Path**.

## Manually Configuring A JetBrains Gateway Connection

This is in lieu of using Coder's Gateway plugin which automatically performs these steps.

1. [Install Gateway](https://www.jetbrains.com/help/idea/jetbrains-gateway.html).

1. [Configure the `coder` CLI](../index.md#configure-ssh).

1. Open Gateway, make sure **SSH** is selected under **Remote Development**.

1. Click **New Connection**:

   ![Gateway Home](../../../images/gateway/gateway-home.png)

1. In the resulting dialog, click the gear icon to the right of **Connection**:

   ![Gateway New Connection](../../../images/gateway/gateway-new-connection.png)

1. Click <kbd>+</kbd> to add a new SSH connection:

   ![Gateway Add Connection](../../../images/gateway/gateway-add-ssh-configuration.png)

1. For the Host, enter `coder.<workspace name>`

1. For the Port, enter `22` (this is ignored by Coder)

1. For the Username, enter your workspace username.

1. For the Authentication Type, select **OpenSSH config and authentication
   agent**.

1. Make sure the checkbox for **Parse config file ~/.ssh/config** is checked.

1. Click **Test Connection** to validate these settings.

1. Click **OK**:

   ![Gateway SSH Configuration](../../../images/gateway/gateway-create-ssh-configuration.png)

1. Select the connection you just added:

   ![Gateway Welcome](../../../images/gateway/gateway-welcome.png)

1. Click **Check Connection and Continue**:

   ![Gateway Continue](../../../images/gateway/gateway-continue.png)

1. Select the JetBrains IDE for your project and the project directory. SSH into
   your server to create a directory or check out code if you haven't already.

   ![Gateway Choose IDE](../../../images/gateway/gateway-choose-ide.png)

   The JetBrains IDE is remotely installed into `~/.cache/JetBrains/RemoteDev/dist`

1. Click **Download and Start IDE** to connect.

   ![Gateway IDE Opened](../../../images/gateway/gateway-intellij-opened.png)

## Using an existing JetBrains installation in the workspace

You can ask your template administrator to [pre-install the JetBrains IDEs backend](../../../admin/templates/extending-templates/jetbrains-preinstall.md) in a template to make JetBrains IDE start faster on first connection.

---

# JetBrains Toolbox

Source: https://coder.com/docs/user-guides/workspace-access/jetbrains/toolbox

# JetBrains Toolbox (beta)

JetBrains Toolbox helps you manage JetBrains products and includes remote development capabilities for connecting to Coder workspaces.

For more details, visit the [official JetBrains documentation](https://www.jetbrains.com/help/toolbox-app/manage-providers.html#shx3a8_18).

## Install the Coder provider for Toolbox

1. Install [JetBrains Toolbox](https://www.jetbrains.com/toolbox-app/) version 2.6.0.40632 or later.
1. Open the Toolbox App.
1. From the switcher drop-down, select **Manage Providers**.
1. In the **Providers** window, under the Available node, locate the **Coder** provider and click **Install**.

![Install the Coder provider in JetBrains Toolbox](../../../images/user-guides/jetbrains/toolbox/install.png)

## Connect

1. In the Toolbox App, click **Coder**.
1. Enter the URL address and click **Sign In**.
   ![JetBrains Toolbox Coder provider URL](../../../images/user-guides/jetbrains/toolbox/login-url.png)
1. Authenticate to Coder adding a token for the session and click **Connect**.
   ![JetBrains Toolbox Coder provider token](../../../images/user-guides/jetbrains/toolbox/login-token.png)
   After the authentication is completed, you are connected to your development environment and can open and work on projects.
   ![JetBrains Toolbox Coder Workspaces](../../../images/user-guides/jetbrains/toolbox/workspaces.png)

## Use URI parameters

For direct connections or creating bookmarks, use custom URI links with parameters:

```shell
jetbrains://gateway/com.coder.toolbox?url=https://coder.example.com&token=<auth-token>&workspace=my-workspace
```

Required parameters:

- `url`: Your Coder deployment URL
- `token`: Coder authentication token
- `workspace`: Name of your workspace

Optional parameters:

- `agent_id`: ID of the agent (only required if workspace has multiple agents)
- `folder`: Specific project folder path to open
- `ide_product_code`: Specific IDE product code (e.g., "IU" for IntelliJ IDEA Ultimate)
- `ide_build_number`: Specific build number of the JetBrains IDE

For more details, see the [coder-jetbrains-toolbox repository](https://github.com/coder/coder-jetbrains-toolbox#connect-to-a-coder-workspace-via-jetbrains-toolbox-uri).

## Configure internal certificates

To connect to a Coder deployment that uses internal certificates, configure the certificates directly in the Coder plugin settings in JetBrains Toolbox:

1. In the Toolbox App, click **Coder**.
1. Click the (⋮) next to the username in top right corner.
1. Select **Settings**.
1. Add your certificate path in the **CA Path** field.
   ![JetBrains Toolbox Coder Provider certificate path](../../../images/user-guides/jetbrains/toolbox/certificate.png)

## Troubleshooting

If you encounter issues connecting to your Coder workspace via JetBrains Toolbox, follow these steps to enable and capture debug logs:

### Enable Debug Logging

1. Open Toolbox
1. Navigate to the **Toolbox App Menu (hexagonal menu icon) > Settings > Advanced**.
1. In the screen that appears, select `DEBUG` for the Log level: section.
1. Hit the back button at the top.
1. Retry the same operation

### Capture Debug Logs

1. Access logs via **Toolbox App Menu > About > Show log files**.
2. Locate the log file named `jetbrains-toolbox.log` and attach it to your support ticket.
3. If you need to capture logs for a specific workspace, you can also generate a ZIP file using the Workspace action menu, available either on the main Workspaces page in Coder view or within the individual workspace view, under the option labeled **Collect logs**.

## Additional Resources

- [JetBrains Toolbox documentation](https://www.jetbrains.com/help/toolbox-app)
- [Coder JetBrains Toolbox Plugin Github](https://github.com/coder/coder-jetbrains-toolbox)

---

# Remote Desktop

Source: https://coder.com/docs/user-guides/workspace-access/remote-desktops

# Remote Desktops

## RDP

The most common way to get a GUI-based connection to a Windows workspace is by using Remote Desktop Protocol (RDP).

<div class="tabs">

### Desktop Client

To use RDP with Coder, you'll need to install an
[RDP client](https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-clients)
on your local machine, and enable RDP on your workspace.

<div class="tabs">

#### Coder Desktop

[Coder Desktop](../desktop/index.md)'s **Coder Connect** feature creates a connection to your workspaces in the background. Use your favorite RDP client to connect to `<workspace-name>.coder`.

You can use the [RDP Desktop](https://registry.coder.com/modules/coder/local-windows-rdp) module to add a single-click button to open an RDP session in the browser.

![RDP Desktop Button](../../images/user-guides/remote-desktops/rdp-button.gif)

You can also use a URI handler to launch an RDP session directly.

The URI format is:

```text
coder://<your Coder server name>/v0/open/ws/<workspace name>/agent/<agent name>/rdp?username=<username>&password=<password>
```

For example:

```text
coder://coder.example.com/v0/open/ws/myworkspace/agent/main/rdp?username=Administrator&password=coderRDP!
```

To include a Coder Desktop button on the workspace dashboard page, add a `coder_app` resource to the template:

```tf
locals {
  server_name = regex("https?:\\/\\/([^\\/]+)", data.coder_workspace.me.access_url)[0]
}

resource "coder_app" "rdp-coder-desktop" {
  agent_id     = resource.coder_agent.main.id
  slug         = "rdp-desktop"
  display_name = "RDP Desktop"
  url          = "coder://${local.server_name}/v0/open/ws/${data.coder_workspace.me.name}/agent/main/rdp?username=Administrator&password=coderRDP!"
  icon         = "/icon/desktop.svg"
  external     = true
}
```

#### CLI

Use the following command to forward the RDP port to your local machine:

```console
coder port-forward <workspace-name> --tcp 3399:3389
```

Then, connect to your workspace via RDP at `localhost:3399`.
![windows-rdp](../../images/user-guides/remote-desktops/windows_rdp_client.png)

</div>

> [!NOTE]
> Some versions of Windows, including Windows Server 2022, do not communicate correctly over UDP when using Coder Connect because they do not respect the maximum transmission unit (MTU) of the link. When this happens, the RDP client will appear to connect, but displays a blank screen.
>
> To avoid this error, Coder's [Windows RDP](https://registry.coder.com/modules/windows-rdp) module [disables RDP over UDP automatically](https://github.com/coder/registry/blob/b58bfebcf3bcdcde4f06a183f92eb3e01842d270/registry/coder/modules/windows-rdp/powershell-installation-script.tftpl#L22).
>
> To disable RDP over UDP manually, run the following in PowerShell:
>
> ```powershell
> New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name "SelectTransport" -Value 1 -PropertyType DWORD -Force
> Restart-Service -Name "TermService" -Force
> ```

### Browser

Our [RDP Web](https://registry.coder.com/modules/windows-rdp) module in the Coder Registry adds a one-click button to open an RDP session in the browser. This requires just a few lines of Terraform in your template, see the documentation on our registry for setup.

![Windows RDP Web](../../images/user-guides/remote-desktops/web-rdp-demo.png)

</div>

> [!NOTE]
> The default username is `Administrator` and the password is `coderRDP!`.

## Amazon DCV

Our [Amazon DCV Windows](https://registry.coder.com/modules/amazon-dcv-windows) installs and configures the Amazon DCV server for seamless remote desktop access. It allows connecting through the both the [Amazon DCV desktop clients](https://docs.aws.amazon.com/dcv/latest/userguide/using-connecting.html) and a [web browser](https://docs.aws.amazon.com/dcv/latest/userguide/using-connecting-browser-connect.html).

<div class="tabs">

### Desktop Client

Connect using the [Amazon DCV Desktop client](https://docs.aws.amazon.com/dcv/latest/userguide/using-connecting.html) by forwarding the DCV port to your local machine:

<div class="tabs">

#### Coder Desktop

[Coder Desktop](../desktop/index.md)'s **Coder Connect** feature creates a connection to your workspaces in the background. Use DCV client to connect to `<workspace-name>.coder:8443`.

#### CLI

Use the following command to forward the DCV port to your local machine:

```console
coder port-forward <workspace-name> --tcp 8443:8443
```

</div>

### Browser

Our [Amazon DCV Windows](https://registry.coder.com/modules/amazon-dcv-windows) module adds a one-click button to open an Amazon DCV session in the browser. This requires just a few lines of Terraform in your template, see the documentation on our registry for setup.

</div>

![Amazon DCV](../../images/user-guides/remote-desktops/amazon-dcv-windows-demo.png)

## VNC

The common way to connect to a desktop session of a Linux workspace is to use a VNC client. The VNC client can be installed on your local machine or accessed through a web browser. There is an additional requirement to install the VNC server on the workspace.

Installation instructions vary depending on your workspace's operating system, platform, and build system. Refer to the [enterprise-desktop](https://github.com/coder/images/tree/main/images/desktop) image for a starting point which can be used to provision a Dockerized workspace with the following software:

- Ubuntu 24.04
- XFCE Desktop
- KasmVNC Server and Web Client

<div class="tabs">

### Desktop Client

Use a VNC client (e.g., [TigerVNC](https://tigervnc.org/)) by forwarding the VNC port to your local machine.

<div class="tab">

#### Coder Desktop

[Coder Desktop](../desktop/index.md)'s **Coder Connect** feature allows you to connect to your workspace's VNC server at `<workspace-name>.coder:5900`.

#### CLI

Use the following command to forward the VNC port to your local machine:

```bash
coder port-forward <workspace-name> --tcp 5900:5900
```

Now you can connect to your workspace's VNC server using a VNC client at `localhost:5900`.

</div>

### Browser

The [KasmVNC module](https://registry.coder.com/modules/coder/kasmvnc) allows browser-based access to your workspace by installing and configuring the [KasmVNC](https://github.com/kasmtech/KasmVNC) server and web client.

</div>

![VNC Desktop in Coder](../../images/user-guides/remote-desktops/vnc-desktop.png)

---

# Emacs TRAMP

Source: https://coder.com/docs/user-guides/workspace-access/emacs-tramp

# Emacs TRAMP

[Emacs TRAMP](https://www.emacswiki.org/emacs/TrampMode) is a method of running
editing operations on a remote server.

## Connecting To A Workspace

To connect to your workspace first run:

```shell
coder config-ssh
```

Then you can connect to your workspace by its name in the format:
`coder.<WORKSPACE NAME>`.

In Emacs type `C-x d` and then input: `/-:coder.<WORKSPACE NAME>:` and hit
enter. This will open up Dired on the workspace's home directory.

### Using SSH

By default Emacs TRAMP is setup to use SCP to access files on the Coder
workspace instance. However you might want to use SSH if you have a jumpbox or
some other complex network setup.

To do so set the following in your Emacs `init.el` file:

```lisp
(setq tramp-default-method "ssh")
```

Then when you access the workspace instance via `/-:coder.<WORKSPACE NAME>`
Emacs will use SSH. Setting `tramp-default-method` will also tell `ansi-term`
mode the correct way to access the remote when directory tracking.

## Directory Tracking

### ansi-term

If you run your terminal in Emacs via `ansi-term` then you might run into a
problem where while SSH-ed into a workspace Emacs will not change its
`default-directory` to open files in the directory your shell is in.

To fix this:

1. In your workspace Terraform template be sure to add the following:

   ```tf
   data "coder_workspace" "me" {
   }

   resource "coder_agent" "main" {
     # ...
     env = {
       name = "CODER_WORKSPACE_NAME"
       value = data.coder_workspace.me.name
     }
   }
   ```

2. Next in the shell profile file on the workspace (ex., `~/.bashrc` for Bash
   and `~/.zshrc` for Zsh) add the following:

   ```bash
   ansi_term_announce_host() {
       printf '\033AnSiTh %s\n' "coder.$CODER_WORKSPACE_NAME"
   }

   ansi_term_announce_user() {
       printf '\033AnSiTu %s\n' "$USER"
   }

   ansi_term_announce_pwd() {
       printf '\033AnSiTc %s\n' "$PWD"
   }

   ansi_term_announce() {
       ansi_term_announce_host
       ansi_term_announce_user
       ansi_term_announce_pwd
   }

   cd()    { command cd    "$@"; ansi_term_announce_pwd; }
   pushd() { command pushd "$@"; ansi_term_announce_pwd; }
   popd()  { command popd  "$@"; ansi_term_announce_pwd; }

   ansi_term_announce
   ```

   Ansi Term expects the terminal running inside of it to send escape codes to
   inform Emacs of the hostname, user, and working directory. The above code
   sends these escape codes and associated data whenever the terminal logs in
   and whenever the directory changes.

### eshell

The `eshell` mode will perform directory tracking by default, no additional
configuration is needed.

## Language Servers (Code Completion)

If you use [`lsp-mode`](https://emacs-lsp.github.io/lsp-mode) for code
intelligence and completion some additional configuration is required.

In your Emacs `init.el` file you must register a LSP client and tell `lsp-mode`
how to find it on the remote machine using the `lsp-register-client` function.
For each LSP server you want to use in your workspace add the following:

```lisp
(lsp-register-client (make-lsp-client :new-connection (lsp-tramp-connection "<LSP SERVER BINARY>")
              :major-modes '(<LANGUAGE MODE>)
              :remote? t
              :server-id '<LANGUAGE SERVER ID>))
```

This tells `lsp-mode` to look for a language server binary named
`<LSP SERVER BINARY>` for use in `<LANGUAGE MODE>` on a machine named
`coder.<WORKSPACE NAME>`. Be sure to replace the values between angle brackets:

- `<LSP SERVER BINARY>` : The name of the language server binary, without any
  path components. For example to use the Deno Javascript language server use
  the value `deno`.
- `<LANGUAGE MODE>`: The name of the Emacs major mode for which the language
  server should be used. For example to enable the language server for
  Javascript development use the value `web-mode`.
- `<LANGUAGE SERVER ID>`: This is just the name that `lsp-mode` will use to
  refer to this language server. If you are ever looking for output buffers or
  files they may have this name in them.

Calling the `lsp-register-client` function will tell `lsp-mode` the name of the
LSP server binary. However this binary must be accessible via the path. If the
language server binary is not in the path you must modify `tramp-remote-path` so
that `lsp-mode` knows in what directories to look for the LSP server. To do this
use TRAMP's connection profiles functionality. These connection profiles let you
customize variables depending on what machine you are connected to. Add the
following to your `init.el`:

```lisp
(connection-local-set-profile-variables 'remote-path-lsp-servers
                                 '((tramp-remote-path . ("<PATH TO ADD>" tramp-default-remote-path))))
(connection-local-set-profiles '(:machine "coder.<WORKSPACE NAME>") 'remote-path-lsp-servers)
```

The `connection-local-set-profile-variables` function creates a new connection
profile by the name `remote-path-lsp-servers`. The
`connection-local-set-profiles` then indicates this `remote-path-lsp-servers`
connection profile should be used when connecting to a server named
`coder.<WORKSPACE NAME>`. Be sure to replace `<PATH TO ADD>` with the directory
in which a LSP server is present.

TRAMP and `lsp-mode` are fickle friends, sometimes there is weird behavior. If
you find that language servers are hanging in the `starting` state then
[it might be helpful](https://github.com/emacs-lsp/lsp-mode/issues/2709#issuecomment-800868919)
to set the `lsp-log-io` variable to `t`.

More details on configuring `lsp-mode` for TRAMP can be found
[in the `lsp-mode` documentation](https://emacs-lsp.github.io/lsp-mode/page/remote/).
The
[TRAMP `tramp-remote-path` documentation](https://www.gnu.org/software/emacs/manual/html_node/tramp/Remote-programs.html#Remote-programs)
contains more examples and details of connection profiles.

---

# Port Forwarding

Source: https://coder.com/docs/user-guides/workspace-access/port-forwarding

# Workspace Ports

## Port forwarding

Port forwarding lets developers securely access processes on their Coder
workspace from a local machine. A common use case is testing web applications in
a browser.

There are multiple ways to forward ports in Coder:

| Method                                                          | Details                                                                                                                                                                 |
|:----------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Coder Desktop](#coder-desktop)                                 | Uses a VPN tunnel to your workspaces and provides access to all running ports. Supports peer-to-peer connections for the best performance.                              |
| [`coder port-forward` command](#the-coder-port-forward-command) | Can be used to forward specific TCP or UDP ports from the remote workspace so they can be accessed locally. Supports peer-to-peer connections for the best performance. |
| [Dashboard](#dashboard)                                         | Proxies traffic through the Coder control plane.                                                                                                                        |
| [SSH](#ssh)                                                     | Forwards ports over an SSH connection.                                                                                                                                  |

## Coder Desktop

[Coder Desktop](../desktop/index.md) provides seamless access to your remote workspaces, eliminating the need to install a CLI or manually configure port forwarding.
Access all your ports at `<workspace-name>.coder:PORT`.

## The `coder port-forward` command

This command can be used to forward TCP or UDP ports from the remote workspace
so they can be accessed locally. Both the TCP and UDP command line flags
(`--tcp` and `--udp`) can be given once or multiple times.

The supported syntax variations for the `--tcp` and `--udp` flag are:

- Single port with optional remote port: `local_port[:remote_port]`
- Comma separation `local_port1,local_port2`
- Port ranges `start_port-end_port`
- Any combination of the above

### Examples

Forward the remote TCP port `8080` to local port `8000`:

```console
coder port-forward myworkspace --tcp 8000:8080
```

Forward the remote TCP port `3000` and all ports from `9990` to `9999` to their
respective local ports.

```console
coder port-forward myworkspace --tcp 3000,9990-9999
```

For more examples, see `coder port-forward --help`.

## Dashboard

To enable port forwarding via the dashboard, Coder must be configured with a
[wildcard access URL](../../admin/setup/index.md#wildcard-access-url). If an
access URL is not specified, Coder will create
[a publicly accessible URL](../../admin/setup/index.md#tunnel) to reverse
proxy the deployment, and port forwarding will work.

There is a
[DNS limitation](https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.1)
where each segment of hostnames must not exceed 63 characters. If your app
name, agent name, workspace name and username exceed 63 characters in the
hostname, port forwarding via the dashboard will not work.

### From a coder_app resource

One way to port forward is to configure a `coder_app` resource in the
workspace's template. This approach shows a visual application icon in the
dashboard. See the following `coder_app` example for a Node React app and note
the `subdomain` and `share` settings:

```tf
# node app
resource "coder_app" "node-react-app" {
  agent_id  = coder_agent.dev.id
  slug      = "node-react-app"
  icon      = "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"
  url       = "http://localhost:3000"
  subdomain = true
  share     = "authenticated"

  healthcheck {
    url       = "http://localhost:3000/healthz"
    interval  = 10
    threshold = 30
  }

}
```

Valid `share` values include `owner` - private to the user, `authenticated` -
accessible by any user authenticated to the Coder deployment, and `public` -
accessible by users outside of the Coder deployment.

![Port forwarding from an app in the UI](../../images/networking/portforwarddashboard.png)

## Accessing workspace ports

Another way to port forward in the dashboard is to use the "Open Ports" button
to specify an arbitrary port. Coder will also detect if apps inside the
workspace are listening on ports, and list them below the port input (this is
only supported on Windows and Linux workspace agents).

![Port forwarding in the UI](../../images/networking/listeningports.png)

### Sharing ports

You can share ports as URLs, either with other authenticated coder users or
publicly. Using the open ports interface, you can assign a sharing levels that
match our `coder_app`’s share option in
[Coder terraform provider](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#share).

- `owner` (Default): The implicit sharing level for all listening ports, only
  visible to the workspace owner
- `organization`: Accessible by authenticated users in the same organization as
  the workspace.
- `authenticated`: Accessible by other authenticated Coder users on the same
  deployment.
- `public`: Accessible by any user with the associated URL.

Once a port is shared at either `authenticated` or `public` levels, it will stay
pinned in the open ports UI for better visibility regardless of whether or not
it is still accessible.

![Annotated port controls in the UI](../../images/networking/annotatedports.png)

> [!NOTE]
> The sharing level is limited by the maximum level enforced in the template
> settings in licensed deployments, and not restricted in OSS deployments.

This can also be used to change the sharing level of port-based `coder_app`s by
entering their port number in the sharable ports UI. The `share` attribute on
`coder_app` resource uses a different method of authentication and **is not
impacted by the template's maximum sharing level**, nor the level of a shared
port that points to the app.

### Configuring port protocol

Both listening and shared ports can be configured to use either `HTTP` or
`HTTPS` to connect to the port. For listening ports the protocol selector
applies to any port you input or select from the menu. Shared ports have
protocol configuration for each shared port individually.

You can also access any port on the workspace and can configure the port
protocol manually by appending a `s` to the port in the URL.

```console
# Uses HTTP
https://33295--agent--workspace--user--apps.example.com/
# Uses HTTPS
https://33295s--agent--workspace--user--apps.example.com/
```

## SSH

First, [configure SSH](./index.md#configure-ssh) on your local machine. Then,
use `ssh` to forward like so:

```console
ssh -L 8080:localhost:8000 coder.myworkspace
```

You can read more on SSH port forwarding
[here](https://www.ssh.com/academy/ssh/tunneling/example).

---

# Filebrowser

Source: https://coder.com/docs/user-guides/workspace-access/filebrowser

# File Browser

File Browser is a file manager for the web that can be used to upload, download,
and view files in your workspace. A template administrator can add it by
following the
[Extending Templates](../../admin/templates/extending-templates/web-ides.md#file-browser)
guide. ![File Browser](../../images/file-browser.png)

---

# Web IDEs and Coder Apps

Source: https://coder.com/docs/user-guides/workspace-access/web-ides

# Web IDEs

By default, Coder workspaces allow connections via:

- Web terminal
- [SSH](./index.md#ssh)

It's common to also connect via web IDEs for uses cases like zero trust
networks, data science, contractors, and infrequent code contributors.

![Row of IDEs](../../images/ide-row.png)

In Coder, web IDEs are defined as
[coder_app](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
resources in the template. With our generic model, any web application can be
used as a Coder application. For example:

To learn more about configuring IDEs in templates, see our docs on
[template administration](../../admin/templates/index.md).

![External URLs](../../images/external-apps.png)

## code-server

[`code-server`](https://github.com/coder/code-server) is our supported method of
running VS Code in the web browser. You can read more in our
[documentation for code-server](https://coder.com/docs/code-server).

![code-server in a workspace](../../images/code-server-ide.png)

## VS Code Web

We also support Microsoft's official product for using VS Code in the browser. A
template administrator can add it by following the
[Extending Templates](../../admin/templates/extending-templates/web-ides.md#vs-code-web)
guide.

![VS Code Web in Coder](../../images/vscode-web.gif)

## Jupyter Notebook

Jupyter Notebook is a web-based interactive computing platform. A template
administrator can add it by following the
[Extending Templates](../../admin/templates/extending-templates/web-ides.md#jupyter-notebook)
guide.

![Jupyter Notebook in Coder](../../images/jupyter-notebook.png)

## JupyterLab

In addition to Jupyter Notebook, you can use Jupyter lab in your workspace. A
template administrator can add it by following the
[Extending Templates](../../admin/templates/extending-templates/web-ides.md#jupyterlab)
guide.

![JupyterLab in Coder](../../images/jupyter.png)

## RStudio

RStudio is a popular IDE for R programming language. A template administrator
can add it to your workspace by following the
[Extending Templates](../../admin/templates/extending-templates/web-ides.md#rstudio)
guide.

![RStudio in Coder](../../images/rstudio-port-forward.png)

## Airflow

Apache Airflow is an open-source workflow management platform for data
engineering pipelines. A template administrator can add it by following the
[Extending Templates](../../admin/templates/extending-templates/web-ides.md#airflow)
guide.

![Airflow in Coder](../../images/airflow-port-forward.png)

## SSH Fallback

If you prefer to run web IDEs in localhost, you can port forward using
[SSH](./index.md#ssh) or the Coder CLI `port-forward` sub-command. Some web IDEs
may not support URL base path adjustment so port forwarding is the only
approach.

---

# code-server

Source: https://coder.com/docs/user-guides/workspace-access/code-server

# code-server

[code-server](https://github.com/coder/code-server) is our supported method of running VS Code in the web browser.

![code-server in a workspace](../../images/code-server-ide.png)

## Differences between code-server and VS Code Web

Some of the key differences between code-server and VS Code Web are:

| Feature                  | code-server                                                                 | VS Code Web                                                       |
|--------------------------|-----------------------------------------------------------------------------|-------------------------------------------------------------------|
| Authentication           | Optional login form                                                         | No built-in auth                                                  |
| Built-in proxy           | Includes development proxy (not needed with Coder)                          | No built-in development proxy                                     |
| Clipboard integration    | Supports piping text from terminal (similar to `xclip`)                     | More limited                                                      |
| Display languages        | Supports language pack extensions                                           | Limited language support                                          |
| File operations          | Options to disable downloads and uploads                                    | No built-in restrictions                                          |
| Health endpoint          | Provides `/healthz` endpoint                                                | Limited health monitoring                                         |
| Marketplace              | Open VSX by default, configurable via flags/env vars                        | Uses Microsoft marketplace; modify `product.json` to use your own |
| Path-based routing       | Has fixes for state collisions when used path-based                         | May have issues with path-based routing in certain configurations |
| Proposed API             | Always enabled for all extensions                                           | Only Microsoft extensions without configuration                   |
| Proxy integration        | Integrates with Coder's proxy for ports panel                               | Integration is more limited                                       |
| Sourcemaps               | Loads locally                                                               | Uses CDN                                                          |
| Telemetry                | Configurable endpoint                                                       | Does not allow a configurable endpoint                            |
| Terminal access to files | You can use a terminal outside of the integrated one to interact with files | Limited to integrated terminal access                             |
| User settings            | Stored on remote disk                                                       | Stored in browser                                                 |
| Web views                | Self-contained                                                              | Uses Microsoft CDN                                                |

For more information about code-server, visit the [code-server FAQ](https://coder.com/docs/code-server/FAQ).

---

# Zed

Source: https://coder.com/docs/user-guides/workspace-access/zed

# Zed

[Zed](https://zed.dev/) is an [open-source](https://github.com/zed-industries/zed)
multiplayer code editor from the creators of Atom and Tree-sitter.

## Use Zed to connect to Coder via SSH

Use the Coder CLI to log in and configure SSH, then connect to your workspace with Zed:

1. [Install Zed](https://zed.dev/docs/)
1. Install Coder CLI:

   <!-- copied from docs/install/cli.md - make changes there -->

   <div class="tabs">

   ### Linux/macOS

   Our install script is the fastest way to install Coder on Linux/macOS:

   ```sh
   curl -L https://coder.com/install.sh | sh
   ```

   Refer to [GitHub releases](https://github.com/coder/coder/releases) for
   alternate installation methods (e.g. standalone binaries, system packages).

   ### Windows

   Use [GitHub releases](https://github.com/coder/coder/releases) to download the
   Windows installer (`.msi`) or standalone binary (`.exe`).

   ![Windows setup wizard](../../images/install/windows-installer.png)

   Alternatively, you can use the
   [`winget`](https://learn.microsoft.com/en-us/windows/package-manager/winget/#use-winget)
   package manager to install Coder:

   ```powershell
   winget install Coder.Coder
   ```

   </div>

   Consult the [Coder CLI documentation](../../install/cli.md) for more options.

1. Log in to your Coder deployment and authenticate when prompted:

   ```shell
   coder login coder.example.com
   ```

1. Configure Coder SSH:

   ```shell
   coder config-ssh
   ```

1. Connect to the workspace via SSH:

   ```shell
   zed ssh://coder.workspace-name
   ```

   Or use Zed's [Remote Development](https://zed.dev/docs/remote-development#setup) to connect to the workspace:

   ![Zed open remote project](../../images/zed/zed-ssh-open-remote.png)

> [!NOTE]
> If you have any suggestions or experience any issues, please
> [create a GitHub issue](https://github.com/coder/coder/issues) or share in
> [our Discord channel](https://discord.gg/coder).

---

# Cursor

Source: https://coder.com/docs/user-guides/workspace-access/cursor

# Cursor

[Cursor](https://cursor.sh/) is a modern IDE built on top of VS Code with enhanced AI capabilities.

Follow this guide to use Cursor to access your Coder workspaces.

If your team uses Cursor regularly, ask your Coder administrator to add a [Cursor module](https://registry.coder.com/modules/cursor) to your template.

## Install Cursor

Cursor can connect to a Coder workspace using the Coder extension:

1. [Install Cursor](https://docs.cursor.com/get-started/installation) on your local machine.

1. Open Cursor and log in or [create a Cursor account](https://authenticator.cursor.sh/sign-up)
   if you don't have one already.

## Install the Coder extension

1. You can install the Coder extension through the Marketplace built in to Cursor or manually.

   <div class="tabs">

   ## Extension Marketplace

   1. Search for Coder from the Extensions Pane and select **Install**.

   1. Coder Remote uses the **Remote - SSH extension** to connect.

      You can find it in the **Extension Pack** tab of the Coder extension.

   ## Manually

   1. Download the [latest vscode-coder extension](https://github.com/coder/vscode-coder/releases/latest) `.vsix` file.

   1. Drag the `.vsix` file into the extensions pane of Cursor.

      Alternatively:

      1. Open the Command Palette
   (<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>)
   and search for `vsix`.

      1. Select **Extensions: Install from VSIX** and select the vscode-coder extension you downloaded.

   </div>

1. Coder Remote uses the **Remote - SSH extension** to connect.

   You can find it in the **Extension Pack** tab of the Coder extension.

## Open a workspace in Cursor

1. From the Cursor Command Palette
(<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>),
enter `coder` and select **Coder: Login**.

1. Follow the prompts to login and copy your session token.

   Paste the session token in the **Paste your API key** box in Cursor.

1. Select **Open Workspace** or use the Command Palette to run **Coder: Open Workspace**.

---

# Windsurf

Source: https://coder.com/docs/user-guides/workspace-access/windsurf

# Windsurf

[Windsurf](https://codeium.com/windsurf) is Codeium's code editor designed for AI-assisted
development.

Follow this guide to use Windsurf to access your Coder workspaces.

If your team uses Windsurf regularly, ask your Coder administrator to add Windsurf as a workspace application in your template.
You can also use the [Windsurf module](https://registry.coder.com/modules/coder/windsurf) to easily add Windsurf to your Coder templates.

## Install Windsurf

Windsurf can connect to your Coder workspaces via SSH:

1. [Install Windsurf](https://docs.codeium.com/windsurf/getting-started) on your local machine.

1. Open Windsurf and select **Get started**.

   Import your settings from another IDE, or select **Start fresh**.

1. Complete the setup flow and log in or [create a Codeium account](https://codeium.com/windsurf/signup)
   if you don't have one already.

## Install the Coder extension

![Coder extension in Windsurf](../../images/user-guides/ides/windsurf-coder-extension.png)

1. You can install the Coder extension through the Marketplace built in to Windsurf or manually.

   <div class="tabs">

   ## Extension Marketplace

   Search for Coder from the Extensions Pane and select **Install**.

   ## Manually

   1. Download the [latest vscode-coder extension](https://github.com/coder/vscode-coder/releases/latest) `.vsix` file.

   1. Drag the `.vsix` file into the extensions pane of Windsurf.

      Alternatively:

      1. Open the Command Palette
         (<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>) and search for `vsix`.

      1. Select **Extensions: Install from VSIX** and select the vscode-coder extension you downloaded.

   </div>

## Open a workspace in Windsurf

1. From the Windsurf Command Palette (<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>),
   enter `coder` and select **Coder: Login**.

1. Follow the prompts to login and copy your session token.

   Paste the session token in the **Coder API Key** dialogue in Windsurf.

1. Windsurf prompts you to open a workspace, or you can use the Command Palette to run **Coder: Open Workspace**.

---

# Antigravity

Source: https://coder.com/docs/user-guides/workspace-access/antigravity

# Antigravity

[Antigravity](https://antigravity.google/) is Google's desktop IDE.

Follow this guide to use Antigravity to access your Coder workspaces.

If your team uses Antigravity regularly, ask your Coder administrator to add Antigravity as a workspace application in your template.
You can also use the [Antigravity module](https://registry.coder.com/modules/coder/antigravity) to easily add Antigravity to your Coder templates.

## Install Antigravity

Antigravity connects to your Coder workspaces using the Coder extension:

1. [Install Antigravity](https://antigravity.google/) on your local machine.

1. Open Antigravity and sign in with your Google account.

## Install the Coder extension

1. You can install the Coder extension through the Marketplace built in to Antigravity or manually.

   <div class="tabs">

   ## Extension Marketplace

   Search for Coder from the Extensions Pane and select **Install**.

   ## Manually

   1. Download the [latest vscode-coder extension](https://github.com/coder/vscode-coder/releases/latest) `.vsix` file.

   1. Drag the `.vsix` file into the extensions pane of Antigravity.

      Alternatively:

      1. Open the Command Palette
         (<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>) and search for `vsix`.

      1. Select **Extensions: Install from VSIX** and select the vscode-coder extension you downloaded.

   </div>

## Open a workspace in Antigravity

1. From the Antigravity Command Palette (<kdb>Ctrl</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb> or <kdb>Cmd</kdb>+<kdb>Shift</kdb>+<kdb>P</kdb>),
   enter `coder` and select **Coder: Login**.

1. Follow the prompts to login and copy your session token.

   Paste the session token in the **Coder API Key** dialogue in Antigravity.

1. Antigravity prompts you to open a workspace, or you can use the Command Palette to run **Coder: Open Workspace**.

## Template configuration

Your Coder administrator can add Antigravity as a one-click workspace app using
the [Antigravity module](https://registry.coder.com/modules/coder/antigravity)
from the Coder registry:

```tf
module "antigravity" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/antigravity/coder"
  version  = "1.0.0"
  agent_id = coder_agent.example.id
  folder   = "/home/coder/project"
}
```

---

# Coder Desktop

Source: https://coder.com/docs/user-guides/desktop

# Coder Desktop

Coder Desktop provides seamless access to your remote workspaces through a native application. Connect to workspace services using simple hostnames like `myworkspace.coder`, launch applications with one click, and synchronize files between local and remote environments—all without installing a CLI or configuring manual port forwarding.

## What You'll Need

- A Coder deployment running `v2.20.0` or [later](https://github.com/coder/coder/releases/latest)
- Administrator privileges on your local machine (for VPN extension installation)
- Access to your Coder deployment URL

## Quick Start

1. Install: `brew install --cask coder/coder/coder-desktop` (macOS) or `winget install Coder.CoderDesktop` (Windows)
1. Open Coder Desktop and approve any system prompts to complete the installation.
1. Sign in with your deployment URL and session token
1. Enable "Coder Connect" toggle
1. Access workspaces at `workspace-name.coder`

## How It Works

**Coder Connect**, the primary component of Coder Desktop, creates a secure tunnel to your Coder deployment, allowing you to:

- **Access workspaces directly**: Connect via `workspace-name.coder` hostnames
- **Use any application**: SSH clients, browsers, IDEs work seamlessly
- **Sync files**: Bidirectional sync between local and remote directories
- **Work offline**: Edit files locally, sync when reconnected

The VPN extension routes only Coder traffic—your other internet activity remains unchanged.

## Installation

<div class="tabs">

### macOS

<div class="tabs">

#### Homebrew (Recommended)

```shell
brew install --cask coder/coder/coder-desktop
```

#### Manual Installation

1. Download the latest release from [coder-desktop-macos releases](https://github.com/coder/coder-desktop-macos/releases)
1. Run `Coder-Desktop.pkg` and follow the prompts to install
1. `Coder Desktop.app` will be installed to your Applications folder

</div>

Coder Desktop requires VPN extension permissions:

1. When prompted with **"Coder Desktop" would like to use a new network extension**, select **Open System Settings**
1. In **Network Extensions** settings, enable the Coder Desktop extension
1. You may need to enter your password to authorize the extension

✅ **Verify Installation**: Coder Desktop should appear in your menu bar

### Windows

<div class="tabs">

#### WinGet (Recommended)

```shell
winget install Coder.CoderDesktop
```

#### Manual Installation

1. Download the latest `CoderDesktop` installer (`.exe`) from [coder-desktop-windows releases](https://github.com/coder/coder-desktop-windows/releases)
1. Choose the correct architecture (`x64` or `arm64`) for your system
1. Run the installer and accept the license terms
1. If prompted, install the .NET Windows Desktop Runtime
1. Install Windows App Runtime SDK if prompted

</div>

- [.NET Windows Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) (installed automatically if not present)
- Windows App Runtime SDK (may require manual installation)

✅ **Verify Installation**: Coder Desktop should appear in your system tray (you may need to click **^** to show hidden icons)

</div>

## Testing Your Connection

Once connected, test access to your workspaces:

<div class="tabs">

### SSH Connection

```shell
ssh your-workspace.coder
```

### Ping Test

```shell
# macOS
ping6 -c 3 your-workspace.coder

# Windows
ping -n 3 your-workspace.coder
```

### Web Services

Open `http://your-workspace.coder:PORT` in your browser, replacing `PORT` with the specific service port you want to access (e.g. 3000 for frontend, 8080 for API)

</div>

## Administrator Configuration

Organizations that manage Coder Desktop deployments can configure the application using MDM (Mobile Device Management) or group policy.

### Disable Automatic Updates

Administrators can disable the built-in auto-updater to manage updates through their own software distribution system.

<div class="tabs">

### macOS

Set the `disableUpdater` preference to `true` using the `defaults` command:

```shell
defaults write com.coder.Coder-Desktop disableUpdater -bool true
```

Organization administrators can also enforce this setting across managed devices using MDM (Mobile Device Management) software by deploying a configuration profile that sets this preference.

### Windows

Set the `Updater:Enable` registry value to `0` under `HKEY_LOCAL_MACHINE\SOFTWARE\Coder Desktop\App`:

```powershell
New-Item -Path "HKLM:\SOFTWARE\Coder Desktop\App" -Force
New-ItemProperty -Path "HKLM:\SOFTWARE\Coder Desktop\App" -Name "Updater:Enable" -Value 0 -PropertyType DWord -Force
```

You can also configure a `Updater:ForcedChannel` string value to lock users to a specific update channel (e.g. `stable`).

> [!NOTE]
> For security, updater settings can only be configured at the machine level (`HKLM`), not per-user (`HKCU`).

</div>

## Troubleshooting

### Connection Issues

#### Can't connect to workspace

- Verify Coder Connect is enabled (toggle should be ON)
- Check that your deployment URL is correct
- Ensure your session token hasn't expired
- Try disconnecting and reconnecting Coder Connect

#### VPN extension not working

- Restart Coder Desktop
- Check system permissions for network extensions
- Ensure only one copy of Coder Desktop is installed

### Getting Help

If you encounter issues not covered here:

- **File an issue**: [macOS](https://github.com/coder/coder-desktop-macos/issues) | [Windows](https://github.com/coder/coder-desktop-windows/issues) | [General](https://github.com/coder/coder/issues)
- **Community support**: [Discord](https://coder.com/chat)

## Uninstalling

<div class="tabs">

### macOS

1. **Disable Coder Connect** in the app menu
2. **Quit Coder Desktop** completely
3. **Remove VPN extension** from System Settings > Network Extensions
4. **Delete the app** from Applications folder
5. **Remove configuration** (optional): `rm -rf ~/Library/Application\ Support/Coder\ Desktop`

### Windows

1. **Disable Coder Connect** in the app menu
2. **Quit Coder Desktop** from system tray
3. **Uninstall** via Settings > Apps or Control Panel
4. **Remove configuration** (optional): Delete `%APPDATA%\Coder Desktop`

</div>

## Next Steps

- [Using Coder Connect and File Sync](./desktop-connect-sync.md)

---

# Coder Desktop Connect and Sync

Source: https://coder.com/docs/user-guides/desktop/desktop-connect-sync

# Coder Desktop Connect and Sync

Use Coder Desktop to work on your workspaces and files as though they're on your LAN.

> [!NOTE]
> Coder Desktop requires a Coder deployment running [v2.20.0](https://github.com/coder/coder/releases/tag/v2.20.0) or later.

## Coder Connect

While active, Coder Connect will list the workspaces you own and will configure your system to connect to them over private IPv6 addresses and custom hostnames ending in `.coder`.

![Coder Desktop list of workspaces](../../images/user-guides/desktop/coder-desktop-workspaces.png)

To copy the `.coder` hostname of a workspace agent, select the copy icon beside it.

You can also connect to the SSH server in your workspace using any SSH client, such as OpenSSH or PuTTY:

   ```shell
   ssh your-workspace.coder
   ```

Any services listening on ports in your workspace will be available on the same hostname. For example, you can access a web server on port `8080` by visiting `http://your-workspace.coder:8080` in your browser.

> [!NOTE]
> For Coder versions v2.21.3 and earlier: the Coder IDE extensions for VSCode and JetBrains create their own tunnel and do not utilize the Coder Connect tunnel to connect to workspaces.

### Ping your workspace

<div class="tabs">

### macOS

Use `ping6` in your terminal to verify the connection to your workspace:

   ```shell
   ping6 -c 5 your-workspace.coder
   ```

### Windows

Use `ping` in a Command Prompt or PowerShell terminal to verify the connection to your workspace:

   ```shell
   ping -n 5 your-workspace.coder
   ```

</div>

## Sync a local directory with your workspace

Coder Desktop file sync provides bidirectional synchronization between a local directory and your workspace.
You can work offline, add screenshots to documentation, or use local development tools while keeping your files in sync with your workspace.

1. Create a new local directory.

   If you select an existing clone of your repository, Desktop will recognize it as conflicting files.

1. In the Coder Desktop app, select **File sync**.

   ![Coder Desktop File Sync screen](../../images/user-guides/desktop/coder-desktop-file-sync.png)

1. Select the **+** in the corner to select the local path, workspace, and remote path, then select **Add**:

   ![Coder Desktop File Sync add paths](../../images/user-guides/desktop/coder-desktop-file-sync-add.png)

1. File sync clones your workspace directory to your local directory, then watches for changes:

   ![Coder Desktop File Sync watching](../../images/user-guides/desktop/coder-desktop-file-sync-watching.png)

   For more information about the current status, hover your mouse over the status.

File sync excludes version control system directories like `.git/` from synchronization, so keep your Git-cloned repository wherever you run Git commands.
This means that if you use an IDE with a built-in terminal to edit files on your remote workspace, that should be the Git clone and your local directory should be for file syncs.

> [!NOTE]
> Coder Desktop uses `alpha` and `beta` to distinguish between the:
>
> - Local directory: `alpha`
> - Remote directory: `beta`

### File sync conflicts

File sync shows a `Conflicts` status when it detects conflicting files.

You can hover your mouse over the status for the list of conflicts:

![Desktop file sync conflicts mouseover](../../images/user-guides/desktop/coder-desktop-file-sync-conflicts-mouseover.png)

If you encounter a synchronization conflict, delete the conflicting file that contains changes you don't want to keep.

## Troubleshooting

### Accessing web apps in a secure browser context

Some web applications require a [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) to function correctly.
A browser typically considers an origin secure if the connection is to `localhost`, or over `HTTPS`.

Because Coder Connect uses its own hostnames and does not provide TLS to the browser, Google Chrome and Firefox will not allow any web APIs that require a secure context.
Even though the browser displays a warning about an insecure connection without `HTTPS`, the underlying tunnel is encrypted with WireGuard in the same fashion as other Coder workspace connections (e.g. `coder port-forward`).

<details><summary>If you require secure context web APIs, identify the workspace hostnames as secure in your browser settings.</summary>

<div class="tabs">

### Chrome

1. Open Chrome and visit `chrome://flags/#unsafely-treat-insecure-origin-as-secure`.

1. Enter the full workspace hostname, including the `http` scheme and the port (e.g. `http://your-workspace.coder:8080`), into the **Insecure origins treated as secure** text field.

   If you need to enter multiple URLs, use a comma to separate them.

   ![Google Chrome insecure origin settings](../../images/user-guides/desktop/chrome-insecure-origin.png)

1. Ensure that the dropdown to the right of the text field is set to **Enabled**.

1. You will be prompted to relaunch Google Chrome at the bottom of the page. Select **Relaunch** to restart Google Chrome.

1. On relaunch and subsequent launches, Google Chrome will show a banner stating "You are using an unsupported command-line flag". This banner can be safely dismissed.

1. Web apps accessed on the configured hostnames and ports will now function correctly in a secure context.

### Firefox

1. Open Firefox and visit `about:config`.

1. Read the warning and select **Accept the Risk and Continue** to access the Firefox configuration page.

1. Enter `dom.securecontext.allowlist` into the search bar at the top.

1. Select **String** on the entry with the same name at the bottom of the list, then select the plus icon on the right.

1. In the text field, enter the full workspace hostname, without the `http` scheme and port: `your-workspace.coder`. Then select the tick icon.

   If you need to enter multiple URLs, use a comma to separate them.

   ![Firefox insecure origin settings](../../images/user-guides/desktop/firefox-insecure-origin.png)

1. Web apps accessed on the configured hostnames will now function correctly in a secure context without requiring a restart.

</div>

</details>

We are planning some changes to Coder Desktop that will make accessing secure context web apps easier in future versions.

---

# Workspace Management

Source: https://coder.com/docs/user-guides/workspace-management

# Workspaces

A workspace is the environment that a developer works in. Developers in a team
each work from their own workspace and can use
[multiple IDEs](./workspace-access/index.md).

A developer creates a workspace from a
[shared template](../admin/templates/index.md). This lets an entire team work in
environments that are identically configured and provisioned with the same
resources.

## Creating workspaces

You can create a workspace in the UI. Log in to your Coder instance, go to the
**Templates** tab, find the template you need, and select **Create Workspace**.

![Creating a workspace in the UI](../images/creating-workspace-ui.png)

When you create a workspace, you will be prompted to give it a name. You might
also be prompted to set some parameters that the template provides.

You can manage your existing templates in the **Workspaces** tab.

You can also create a workspace from the command line:

Each Coder user has their own workspaces created from
[templates](../admin/templates/index.md):

```shell
# create a workspace from the template; specify any variables
coder create --template="<templateName>" <workspaceName>

# show the resources behind the workspace and how to connect
coder show <workspace-name>
```

### Workspace name rules and restrictions

| Constraint       | Rule                                       |
|------------------|--------------------------------------------|
| Start/end with   | Must start and end with a letter or number |
| Character types  | Letters, numbers, and hyphens only         |
| Length           | 1-32 characters                            |
| Case sensitivity | Case-insensitive (lowercase recommended)   |
| Reserved names   | Cannot use `new` or `create`               |
| Uniqueness       | Must be unique within your workspaces      |

## Workspace filtering

In the Coder UI, you can filter your workspaces using pre-defined filters or
Coder's filter query. Filters follow the pattern `[filter name]:[filter text]`
and multiple filters can be specified separated by a space i.e
`owner:me status:running`

The following filters are supported:

- `owner` - Represents the `username` of the owner. You can also use `me` as a
  convenient alias for the logged-in user, e.g., `owner:me`
- `name` - Name of the workspace.
- `template` - Name of the template.
- `status` - Indicates the status of the workspace, e.g, `status:failed` For a
  list of supported statuses, see
  [WorkspaceStatus documentation](https://pkg.go.dev/github.com/coder/coder/codersdk#WorkspaceStatus).
- `outdated` - Filters workspaces using an outdated template version, e.g,
  `outdated:true`
- `dormant` - Filters workspaces based on the dormant state, e.g `dormant:true`
- `has-agent` - Only applicable for workspaces in "start" transition. Stopped
  and deleted workspaces don't have agents. List of supported values
  `connecting|connected|timeout|disconnected`, e.g, `has-agent:connecting`
- `id` - Workspace UUID
- `healthy` - Only applicable for workspaces in "start" transition. `healthy:false` is an alias for `has-agent:timeout,disconnected`, `healthy:true` is an alias for `has-agent:connected`.

## Updating workspaces

After updating the default version of the template that a workspace was created
from, you can update the workspace.

![Updating a workspace](../images/workspace-update.png)

If the workspace is running, Coder stops it, updates it, then starts the
workspace again.

### Updating via the CLI

Update a workspace through the command line:

```shell
coder update <workspace-name>
```

### Automatic updates

It can be tedious to manually update a workspace everytime an update is pushed
to a template. Users can choose to opt-in to automatic updates to update to the
active template version whenever the workspace is started.

Note: If a template is updated such that new parameter inputs are required from
the user, autostart will be disabled for the workspace until the user has
manually updated the workspace.

![Automatic Updates](../images/workspace-automatic-updates.png)

## Bulk operations

Admins may apply bulk operations (update, delete, start, stop) in the
**Workspaces** tab. Select the workspaces you'd like to modify with the
checkboxes on the left, then use the top-right **Actions** dropdown to apply the
operation.

The start and stop operations can only be applied to a set of workspaces which
are all in the same state. For update and delete, the user will be prompted for
confirmation before any action is taken.

![Bulk workspace actions](../images/user-guides/workspace-bulk-actions.png)

## Starting and stopping workspaces

By default, you manually start and stop workspaces as you need. You can also
schedule a workspace to start and stop automatically.

To set a workspace's schedule, go to the workspace, then **Settings** >
**Schedule**.

![Scheduling UI](../images/schedule.png)

Coder might also stop a workspace automatically if there is a
[template update](../admin/templates/managing-templates/index.md#updating-templates)
available.

Learn more about [workspace lifecycle](./workspace-lifecycle.md) and our
[scheduling features](./workspace-scheduling.md).

## Workspace resources

Workspaces in Coder are started and stopped, often based on whether there was
any activity or if there was a [template update](../admin/templates/index.md)
available.

Resources are often destroyed and re-created when a workspace is restarted,
though the exact behavior depends on the template. For more information, see
[Resource Persistence](../admin/templates/extending-templates/resource-persistence.md).

## Repairing workspaces

Use the following command to re-enter template input variables in an existing
workspace. This command is useful when a workspace fails to build because its
state is out of sync with the template.

```shell
coder update <your workspace name> --always-prompt
```

First, try re-entering parameters from a workspace. In the Coder UI, you can
filter your workspaces using pre-defined filters or employing the Coder's filter
query. Take a look at the following examples to understand how to use the
Coder's filter query:

- To find the workspaces that you own, use the filter `owner:me`.
- To find workspaces that are currently running, use the filter
  `status:running`.

![Re-entering template variables](../images/templates/template-variables.png)

You can also do this in the CLI with the following command:

```shell
coder update <your workspace name> --always-prompt
```

If that does not work, a Coder admin can manually push and pull the Terraform
state for a given workspace. This can lead to state corruption or deleted
resources if you do not know what you are doing.

```shell
coder state pull <username>/<workspace name>
# Make changes
coder state push <username>/<workspace name>
```

## Logging

Coder stores macOS and Linux logs at the following locations:

| Service           | Location                         |
|-------------------|----------------------------------|
| `startup_script`  | `/tmp/coder-startup-script.log`  |
| `shutdown_script` | `/tmp/coder-shutdown-script.log` |
| Agent             | `/tmp/coder-agent.log`           |

> [!NOTE]
> Logs are truncated once they reach 5MB in size.

---

# Workspace Sharing

Source: https://coder.com/docs/user-guides/shared-workspaces

# Shared Workspaces

Multiple users can securely connect to a single Coder workspace for programming and debugging.

<!-- Insert screenshot of UI here -->

## Features

Workspace sharing is available to all Coder users by default, but platform admins with a Premium subscription can choose to disable sharing within their organizations or for their entire deployment.

Owners of a workspace can grant access to other users or groups with scoped roles.

This is helpful in a number of scenarios, including:

- Developers can do ad-hoc debugging or pair programming.
- A workspace can be owned by a group of users for QA, on-call rotations, or shared staging.
- AI workflows where an agent prepares a workspace and a developer takes over to review or finalize the work (ex. with [Coder Tasks](https://coder.com/docs/ai-coder/tasks).)

## Getting Started

Workspaces can be shared through either the Coder CLI or UI.

Before you begin, ensure that you have a version of Coder with workspace sharing enabled and that your account has permission to share workspaces. This is true by default if you are an OSS user, but deployments with Premium licenses may be restricted by admins.

### CLI

To share a workspace:

- `coder sharing share <workspace> --user alice`
  - Shares the workspace with a single user, `alice`, with `use` permissions
- `coder sharing share <workspace> --user alice:admin,bob`
  - Shares the workspace with two users - `alice` with `admin` permissions, and `bob` with `use` permissions
- `coder sharing share <workspace> --group contractor`
  - Shares the workspace with `contractor`, which is a group of users

To remove sharing from a workspace:

- `coder sharing remove <workspace> --user alice`
  - Workspace is no longer shared with the user `alice`.
- `coder sharing remove <workspace> --group contractor`
  - Workspace is no longer shared with the group `contractor`.

> [!Important]
> The workspace must be restarted for the user or group removal to take effect.

To show who a workspace is shared with:

- `coder sharing status <workspace>`

To list shared workspaces:

- `coder list --search shared:true`
- `coder list --search shared_with_user:<user>`
- `coder list --search shared_with_group:<group>`

### UI

#### Sharing your Workspace

1. Open a workspace that you own.

1. Locate and click the 'Share' button.

![Sharing a workspace](../images/user-guides/workspace-sharing-button-highlight.png)

1. Add the users or groups that you want to share the workspace with. For each one, select a role.

![Sharing with a user or group](../images/user-guides/workspace-sharing-roles.png)

- `use` allows for connection via SSH and apps, the ability to start and stop the workspace, view logs and stats, and update on start when required.
- `admin` allows for all of the above, as well as the ability to rename the workspace, update at any time, and invite others with the `use` role.
- Neither role allows for the user to delete the workspace.
- After removing a user/group, a workspace restart is required for the removal to take effect.

#### Using a shared workspace

Once a workspace is shared, you can find the shared workspace by filtering for "Shared" in the Workspaces page.

![Sharing with a user or group](../images/user-guides/workspace-sharing-shared-view.png)

#### Accessing workspace apps in shared workspaces

Sharing a workspace grants SSH and terminal access to other users. However,
workspace apps like code-server may return a **404 page** for non-owners
depending on how the app is routed.

By default, workspace apps that don't set `subdomain = true` use **path-based
routing** (e.g., `coder.example.com/@user/workspace/apps/code-server/`).
Path-based apps share the same origin as the Coder dashboard, so Coder blocks
non-owners from accessing them to prevent
[cross-site scripting risks](../tutorials/best-practices/security-best-practices.md#disable-path-based-apps).
This restriction applies even when the user has been granted access through
workspace sharing.

To allow other users to access workspace apps, configure subdomain-based access:

1. Set a
   [wildcard access URL](../admin/networking/wildcard-access-url.md)
   on your deployment
   (e.g., `CODER_WILDCARD_ACCESS_URL=*.coder.example.com`).
2. Set `subdomain = true` on the workspace app. For example, if you use the
   [code-server module](https://registry.coder.com/modules/coder/code-server):

   ```hcl
   module "code-server" {
     source    = "registry.coder.com/coder/code-server/coder"
     agent_id  = coder_agent.main.id
     subdomain = true
     # ...
   }
   ```

Subdomain-based apps run in an isolated browser security context, so Coder
allows other users to access them without additional configuration.

### Policies

There are several sharing policy levels that can be selected on a per-organization basis.

- **Everyone** – Anybody can share their workspace with any individual or group in the same organization.
- **Service Accounts Only** – Only workspaces owned by service accounts can be shared with any individual or group in the same organization.
- **Disabled** – Workspaces within the organization cannot be shared.

The **Disabled** policy can also be applied to the entire deployment by [setting the `CODER_DISABLE_WORKSPACE_SHARING` environment variable, or by using the corresponding command argument or config value](https://coder.com/docs/reference/cli/server#--disable-workspace-sharing).

---

# Workspace Scheduling

Source: https://coder.com/docs/user-guides/workspace-scheduling

# Managing workspace schedules

Scheduling helps minimize cloud costs without sacrificing the availability of
your workspaces.

You can configure each workspace to automatically start in the morning, and
automatically stop once you log off. Coder also features an inactivity timeout,
configured by your template admin, which will stop a workspace when a user's
absence is detected.

To learn more workspace states and schedule, read the
[workspace lifecycle](../user-guides/workspace-lifecycle.md) documentation.

## Where to find the schedule settings

Click on any workspace the **Workspaces** tab of the dashboard, then go to
**Workspace settings** in the top right.

![Workspace settings location](../images/user-guides/workspace-settings-location.png)

Then open the **Schedule** tab to see your workspace scheduling options.

![Workspace schedule settings](../images/user-guides/schedule-settings-workspace.png)

## Autostart

Autostart must be enabled in the template settings by your administrator.

Use autostart to start a workspace at a specified time and which days of the
week. Also, you can choose your preferred timezone. Admins may restrict which
days of the week your workspace is allowed to autostart.

![Autostart UI](../images/workspaces/autostart.png)

## Autostop

Use autostop to stop a workspace after a number of hours. Autostop won't stop a
workspace if you're still using it. It will wait for the user to become inactive
before checking connections again (1 hour by default). Template admins can
modify this duration with the **activity bump** template setting.

> [!NOTE]
> Autostop must be enabled on the template prior to workspace creation, it is not applied to existing running workspaces.

![Autostop UI](../images/workspaces/autostop.png)

## Activity detection

Workspaces automatically shut down after a period of inactivity. The **activity bump**
duration can be configured at the template level and is visible in the autostop description
for your workspace.

### What counts as workspace activity?

A workspace is considered "active" when Coder detects one or more active sessions with your workspace. Coder specifically tracks these session types:

- **VSCode sessions**: Using code-server or VS Code with a remote extension
- **JetBrains IDE sessions**: Using JetBrains Gateway or remote IDE plugins
- **Terminal sessions**: Using the web terminal (including reconnecting to the web terminal)
- **SSH sessions**: Connecting via `coder ssh` or SSH config integration
- **AI agent task status**: When a coding agent reports "working" status via
  [Coder Tasks](../ai-coder/tasks.md), the workspace deadline is extended

Activity is only detected when there is at least one active session. An open session will keep your workspace marked as active and prevent automatic shutdown.

The following actions do **not** count as workspace activity:

- Viewing workspace details in the dashboard
- Viewing or editing workspace settings
- Viewing build logs or audit logs
- Accessing ports through direct URLs without an active session
- Background agent statistics reporting (note: AI agent _task status_
  reporting is different and does count as activity, see above)

To avoid unexpected cloud costs, close your connections, this includes IDE windows, SSH sessions, and others, when you finish using your workspace.

## Autostop requirement

> [!NOTE]
> Autostop requirement is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Licensed template admins may enforce a required stop for workspaces to apply
updates or undergo maintenance. These stops ignore any active connections or
inactivity bumps. Rather than being specified with a CRON, admins set a
frequency for updates, either in **days** or **weeks**. Workspaces will apply
the template autostop requirement on the given day **in the user's timezone**
and specified quiet hours (see below).

Admins: See the template schedule settings for more information on configuring
Autostop Requirement.

### User quiet hours

> [!NOTE]
> User quiet hours are a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

User quiet hours can be configured in the user's schedule settings page.
Workspaces on templates with an autostop requirement will only be forcibly
stopped due to the policy at the **start** of the user's quiet hours.

![User schedule settings](../images/admin/templates/schedule/user-quiet-hours.png)

## Scheduling configuration examples

The combination of autostart, autostop, and the activity bump create a
powerful system for scheduling your workspace. However, synchronizing all of
them simultaneously can be somewhat challenging, here are a few example
configurations to better understand how they interact.

> [!NOTE]
> The activity bump must be configured by your template admin.

### Working hours

The intended configuration for autostop is to combine it with autostart, and set
a "working schedule" for your workspace. It's pretty intuitive:

If I want to use my workspace from 9 to 5 on weekdays, I would set my autostart
to 9:00 AM every day with an autostop of 9 hours. My workspace will always be
available during these hours, regardless of how long I spend away from my
laptop. If I end up working overtime and log off at 6:00 PM, the activity bump
will kick in, postponing the shutdown until 7:00 PM.

#### Basing solely on activity detection

If you'd like to ignore the TTL from autostop and have your workspace solely
function on activity detection, you can set your autostop equal to activity
bump duration.

Let's say that both are set to 5 hours. When either your workspace autostarts or
you sign in, you will have confidence that the only condition for shutdown is 5
hours of inactivity.

## Dormancy

> [!NOTE]
> Dormancy is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Dormancy automatically deletes workspaces that remain unused for long
durations. Template admins configure a dormancy threshold that determines how long
a workspace can be inactive before it is marked as `dormant`. A separate setting
determines how long workspaces will remain in the dormant state before automatic deletion.

Licensed admins may also configure failure cleanup, which will automatically
delete workspaces that remain in a `failed` state for too long.

---

# Workspace Lifecycle

Source: https://coder.com/docs/user-guides/workspace-lifecycle

# Workspace lifecycle

Workspaces are flexible, reproducible, and isolated units of compute. Workspaces
are created via Terraform, managed through the Coder control plane, accessed
through the Coder agent, then stopped and deleted again by Terraform.

This page covers how workspaces move through this lifecycle. To learn about
automating workspace schedules for cost control, read the
[workspace scheduling docs](./workspace-scheduling.md).

## Workspace ephemerality

Workspaces are composed of resources which may be _ephemeral_ or _persistent_.
Persistent resources stay provisioned when the workspace is stopped, where as
ephemeral resources are destroyed and recreated on restart. All resources are
destroyed when a workspace is deleted.

Template administrators can learn more about resource configuration in the
[extending templates docs](../admin/templates/extending-templates/resource-persistence.md).

## Workspace States

Generally, there are 3 states that a workspace may fall into:

- Running: Started and ready for connections
- Stopped: Ephemeral resources destroyed, persistent resources idle
- Deleted: All resources destroyed, workspace records removed from database

If some error occurs during the above, a workspace may fall into one of the
following broken states:

- Failed: Failure during provisioning, no resource consumption
- Unhealthy: Resources have been provisioned, but the agent can't facilitate
  connections

## Workspace creation

Workspaces are created from [templates](../admin/templates/index.md) via the
CLI, API, or dashboard.

By default, there is no limit on the number of workspaces a user may create,
regardless of the template's resource demands. Enterprise administrators may
limit the number of workspaces per template, group, and organization using
[quotas](../admin/users/quotas.md) to prevent over provisioning and control
costs.

When a user creates a workspace, they're sending a build request to the control
plane. Coder takes this and uses [Terraform](https://www.terraform.io/) to
provision a workspace defined by your [template](../admin/templates/index.md).
Generally, templates define the resources and environment of a workspace.

The resources that run the agent are described as _computational resources_,
while those that don't are called _peripheral resources_. A workspace must
contain some computational resource to run the Coder agent process.

The provisioned workspace's computational resources start the agent process,
which opens connections to your workspace via SSH, the terminal, and IDES such
as [JetBrains](./workspace-access/jetbrains/index.md) or
[VSCode](./workspace-access/vscode.md).

Once started, the Coder agent is responsible for running your workspace startup
scripts. These may configure tools, service connections, or personalization with
[dotfiles](./workspace-dotfiles.md). For complex initialization with multiple
dependent scripts, see
[Workspace Startup Coordination](../admin/templates/startup-coordination/index.md).

Once these steps have completed, your workspace will now be in the `Running`
state. You can access it via any of the [supported methods](./index.md), stop it
when you're away, or delete it once it's no longer in use.

## Stopping workspaces

Workspaces may be stopped manually by users and admins in the dashboard, CLI, or
API. Workspaces may be automatically stopped due to template updates or
inactivity by [scheduling configuration](./workspace-scheduling.md).

Once stopped, a workspace may resume running by starting it manually, or via
user connection if automatic start is enabled.

## Deleting workspaces

Similarly to stopping, workspaces may be deleted manually or automatically by
Coder through workspace dormancy.

A delete workspace build runs `terraform destroy`, destroying both persistent
and ephemeral resources. This action can not be reverted.

When enabled on enterprise deployments, workspaces will become dormant after a
specified duration of inactivity. Then, if left dormant, the workspaces will be
queued for deletion. Learn about configuring workspace dormancy in the template
scheduling docs.

### Orphan resources

Typically, when a workspace is deleted, all of the workspace's resources are
deleted along with it. Rarely, one may wish to delete a workspace without
deleting its resources, e.g. a workspace in a broken state. Users with the
Template Admin role have the option to do so both in the UI, and also in the CLI
by running the delete command with the `--orphan` flag. This option should be
considered cautiously as orphaning may lead to unaccounted cloud resources.

## Broken workspace states

During a workspace start or stop build, one of two errors may lead to a broken
state. If the call to `terraform apply` fails to correctly provision resources,
a workspace build has **failed**. If the computational resources fail to connect
the agent, a workspace becomes **unhealthy**.

A failed workspace is most often caused by misalignment from the definition in
your template's Terraform file and the target resources on your infrastructure.
Unhealthy workspaces are usually caused by a misconfiguration in the agent or
workspace startup scripts.

## Workspace build times

After a successful build, you can see a timing breakdown of the workspace
startup process from the dashboard (starting in v2.17). We capture and display
both time taken to provision the workspace's compute and agent startup steps.
These include any
[`coder_script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script)s
such as [dotfiles](./workspace-dotfiles.md) or
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
startups.

![Workspace build timings UI](../images/admin/templates/troubleshooting/workspace-build-timings-ui.png)

### Next steps

- [Connecting to your workspace](./index.md)
- [Creating templates](../admin/templates/index.md)
- [Workspace scheduling](./workspace-scheduling.md)

---

# Dev Containers

Source: https://coder.com/docs/user-guides/devcontainers

# Dev Containers

[Dev containers](https://containers.dev/) define your development environment
as code using a `devcontainer.json` file. Coder's Dev Containers integration
uses the [`@devcontainers/cli`](https://github.com/devcontainers/cli) and
[Docker](https://www.docker.com) to seamlessly build and run these containers,
with management in your dashboard.

This guide covers the Dev Containers integration. For workspaces without Docker,
administrators can configure
[Envbuilder](../../admin/integrations/devcontainers/envbuilder/index.md) instead,
which builds the workspace image itself from your dev container configuration.

![Two dev containers running as sub-agents in a Coder workspace](../../images/user-guides/devcontainers/devcontainer-running.png)_Dev containers appear as sub-agents with their own apps, SSH access, and port forwarding_

## Prerequisites

- Coder version 2.24.0 or later
- Docker available inside your workspace
- The `@devcontainers/cli` installed in your workspace

Dev Containers integration is enabled by default. Your workspace needs Docker
(via Docker-in-Docker or a mounted socket) and the devcontainers CLI. Most
templates with Dev Containers support include both. See
[Configure a template for dev containers](../../admin/integrations/devcontainers/integration.md)
for setup details.

## Features

- Automatic dev container detection from repositories
- Seamless container startup during workspace initialization
- Change detection with outdated status indicator
- On-demand container rebuild via dashboard button
- Template-defined apps, scripts, and environment variables via Terraform (see [limitations](../../admin/integrations/devcontainers/integration.md#interaction-with-devcontainerjson-customizations))
- Integrated IDE experience with VS Code
- Direct SSH access to containers
- Automatic port detection

## Getting started

### Add a devcontainer.json

Add a `devcontainer.json` file to your repository. This file defines your
development environment. You can place it in:

- `.devcontainer/devcontainer.json` (recommended)
- `.devcontainer.json` (root of repository)
- `.devcontainer/<folder>/devcontainer.json` (for multiple configurations)

The third option allows monorepos to define multiple dev container
configurations in separate sub-folders. See the
[Dev Container specification](https://containers.dev/implementors/spec/#devcontainerjson)
for details.

Here's a minimal example:

```json
{
  "name": "My Dev Container",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu"
}
```

For more configuration options, see the
[Dev Container specification](https://containers.dev/).

### Start your dev container

Coder automatically discovers dev container configurations in your repositories
and displays them in your workspace dashboard. From there, you can start a dev
container with a single click.

![Discovered dev containers with Start buttons](../../images/user-guides/devcontainers/devcontainer-discovery.png)_Coder detects dev container configurations and displays them with a Start button_

If your template administrator has configured automatic startup (via the
`coder_devcontainer` Terraform resource or autostart settings), your dev
container will build and start automatically when the workspace starts.

### Connect to your dev container

Once running, your dev container appears as a sub-agent in your workspace
dashboard. You can connect via:

- **Web terminal** in the Coder dashboard
- **SSH** using `coder ssh <workspace>.<agent>`
- **VS Code** using the "Open in VS Code Desktop" button

See [Working with dev containers](./working-with-dev-containers.md) for detailed
connection instructions.

## How it works

The Dev Containers integration uses the `devcontainer` command from
[`@devcontainers/cli`](https://github.com/devcontainers/cli) to manage
containers within your Coder workspace.

When a workspace with Dev Containers integration starts:

1. If the template defines `coder_app`, `coder_script`, or `coder_env` resources
   attached to the dev container, a sub-agent is pre-created with these resources.
1. The workspace initializes the Docker environment.
1. The integration detects repositories with dev container configurations.
1. Detected dev containers appear in the Coder dashboard.
1. If auto-start is configured (via `coder_devcontainer` or autostart settings),
   the integration builds and starts the dev container automatically.
1. Coder creates a sub-agent (or updates the pre-created one) for the running
   container, enabling direct access.

Without auto-start, users can manually start discovered dev containers from the
dashboard.

### Agent naming

Each dev container gets its own agent name, derived from the workspace folder
path. For example, a dev container with workspace folder `/home/coder/my-app`
will have an agent named `my-app`.

Agent names are sanitized to contain only lowercase alphanumeric characters and
hyphens. You can also set a
[custom agent name](./customizing-dev-containers.md#custom-agent-name)
in your `devcontainer.json`.

## Limitations

- **Linux only**: Dev Containers are currently not supported in Windows or
  macOS workspaces
- Changes to `devcontainer.json` require manual rebuild using the dashboard
  button
- The `forwardPorts` property in `devcontainer.json` with `host:port` syntax
  (e.g., `"db:5432"`) for Docker Compose sidecar containers is not yet
  supported. For single-container dev containers, use `coder port-forward` to
  access ports directly on the sub-agent.
- Some advanced dev container features may have limited support

## Next steps

- [Working with dev containers](./working-with-dev-containers.md) — SSH, IDE
  integration, and port forwarding
- [Customizing dev containers](./customizing-dev-containers.md) — Custom agent
  names, apps, and display options
- [Troubleshooting dev containers](./troubleshooting-dev-containers.md) —
  Diagnose common issues
- [Dev Container specification](https://containers.dev/) — Advanced
  configuration options
- [Dev Container features](https://containers.dev/features) — Enhance your
  environment with pre-built tools

---

# Working with dev containers

Source: https://coder.com/docs/user-guides/devcontainers/working-with-dev-containers

# Working with Dev Containers

The dev container integration appears in your Coder dashboard, providing a
visual representation of the running environment:

![Two dev containers running as sub-agents in a Coder workspace](../../images/user-guides/devcontainers/devcontainer-running.png)_Dev containers appear as sub-agents with their own apps, SSH access, and port forwarding_

## SSH access

Each dev container has its own agent name, derived from the workspace folder
(e.g., `/home/coder/my-project` becomes `my-project`). You can find agent names
in your workspace dashboard, or see
[Agent naming](./index.md#agent-naming) for details on how names are generated.

### Using the Coder CLI

The simplest way to SSH into a dev container is using `coder ssh` with the
workspace and agent name:

```console
coder ssh <workspace>.<agent>
```

For example, to connect to a dev container with agent name `my-project` in
workspace `my-workspace`:

```console
coder ssh my-workspace.my-project
```

To SSH into the main workspace agent instead of the dev container:

```console
coder ssh my-workspace
```

### Using OpenSSH (config-ssh)

You can also use standard OpenSSH tools after generating SSH config entries with
`coder config-ssh`:

```console
coder config-ssh
```

This creates a wildcard SSH host entry that matches all your workspaces and
their agents, including dev container sub-agents. You can then connect using:

```console
ssh my-project.my-workspace.me.coder
```

The default hostname suffix is `.coder`. If your organization uses a different
suffix, adjust the hostname accordingly. The suffix can be configured via
[`coder config-ssh --hostname-suffix`](../../reference/cli/config-ssh.md) or
by your deployment administrator.

This method works with any SSH client, IDE remote extensions, `rsync`, `scp`,
and other tools that use SSH.

## Web terminal access

Once your workspace and dev container are running, you can use the web terminal
in the Coder interface to execute commands directly inside the dev container.

![Coder web terminal with dev container](../../images/user-guides/devcontainers/devcontainer-web-terminal.png)

## IDE integration (VS Code)

You can open your dev container directly in VS Code by:

1. Selecting **Open in VS Code Desktop** from the dev container agent in the
   Coder web interface.
1. Using the Coder CLI:

   ```console
   coder open vscode <workspace>.<agent>
   ```

   For example:

   ```console
   coder open vscode my-workspace.my-project
   ```

VS Code will automatically detect the dev container environment and connect
appropriately.

While optimized for VS Code, other IDEs with dev container support may also
work.

## Port forwarding

Since dev containers run as sub-agents, you can forward ports directly to them
using standard Coder port forwarding:

```console
coder port-forward <workspace>.<agent> --tcp 8080
```

For example, to forward port 8080 from a dev container with agent name
`my-project`:

```console
coder port-forward my-workspace.my-project --tcp 8080
```

This forwards port 8080 on your local machine directly to port 8080 in the dev
container. Coder also automatically detects ports opened inside the container.

### Exposing ports on the parent workspace

If you need to expose dev container ports through the parent workspace agent
(rather than the sub-agent), you can use the
[`appPort`](https://containers.dev/implementors/json_reference/#image-specific)
property in your `devcontainer.json`:

```json
{
  "appPort": ["8080:8080", "4000:3000"]
}
```

This maps container ports to the parent workspace, which can then be forwarded
using the main workspace agent.

## Dev container features

You can use standard [dev container features](https://containers.dev/features)
in your `devcontainer.json` file. Coder also maintains a
[repository of features](https://github.com/coder/devcontainer-features) to
enhance your development experience.

For example, the
[code-server](https://github.com/coder/devcontainer-features/blob/main/src/code-server)
feature from the [Coder features repository](https://github.com/coder/devcontainer-features):

```json
{
  "features": {
    "ghcr.io/coder/devcontainer-features/code-server:1": {
      "port": 13337,
      "host": "0.0.0.0"
    }
  }
}
```

## Rebuilding dev containers

When you modify your `devcontainer.json`, you need to rebuild the container for
changes to take effect. Coder detects changes and shows an **Outdated** status
next to the dev container.

![Dev container showing Outdated status with rebuild option](../../images/user-guides/devcontainers/devcontainer-outdated.png)_The Outdated indicator appears when changes to devcontainer.json are detected_

Click **Rebuild** to recreate your dev container with the updated configuration.

---

# Customizing dev containers

Source: https://coder.com/docs/user-guides/devcontainers/customizing-dev-containers

# Customizing dev containers

Coder supports custom configuration in your `devcontainer.json` file through the
`customizations.coder` block. These options let you control how Coder interacts
with your dev container without requiring template changes.

> [!TIP]
>
> Alternatively, template administrators can also define apps, scripts, and
> environment variables for dev containers directly in Terraform. See
> [Attach resources to dev containers](../../admin/integrations/devcontainers/integration.md#attach-resources-to-dev-containers)
> for details.

## Ignore a dev container

Use the `ignore` option to hide a dev container from Coder completely:

```json
{
  "name": "My Dev Container",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "customizations": {
    "coder": {
      "ignore": true
    }
  }
}
```

When `ignore` is set to `true`:

- The dev container won't appear in the Coder UI
- Coder won't manage or monitor the container

This is useful for dev containers in your repository that you don't want Coder
to manage.

## Auto-start

Control whether your dev container should auto-start using the `autoStart`
option:

```json
{
  "name": "My Dev Container",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "customizations": {
    "coder": {
      "autoStart": true
    }
  }
}
```

When `autoStart` is set to `true`, the dev container automatically builds and
starts during workspace initialization.

When `autoStart` is set to `false` or omitted, the dev container is discovered
and shown in the UI, but users must manually start it.

> [!NOTE]
>
> The `autoStart` option only takes effect when your template administrator has
> enabled [`CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE`](../../admin/integrations/devcontainers/integration.md#coder_agent_devcontainers_discovery_autostart_enable).
> If this setting is disabled at the template level, containers won't auto-start
> regardless of this option.

## Custom agent name

Each dev container gets an agent name derived from the workspace folder path by
default. You can set a custom name using the `name` option:

```json
{
  "name": "My Dev Container",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "customizations": {
    "coder": {
      "name": "my-custom-agent"
    }
  }
}
```

The name must contain only lowercase letters, numbers, and hyphens. This name
appears in `coder ssh` commands and the dashboard (e.g.,
`coder ssh my-workspace.my-custom-agent`).

## Display apps

Control which built-in Coder apps appear for your dev container using
`displayApps`:

![Dev container with all display apps disabled](../../images/user-guides/devcontainers/devcontainer-apps-bar.png)_Disable built-in apps to reduce clutter or guide developers toward preferred tools_

```json
{
  "name": "My Dev Container",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "customizations": {
    "coder": {
      "displayApps": {
        "web_terminal": true,
        "ssh_helper": true,
        "port_forwarding_helper": true,
        "vscode": true,
        "vscode_insiders": false
      }
    }
  }
}
```

Available display apps:

| App                      | Description                  | Default |
|--------------------------|------------------------------|---------|
| `web_terminal`           | Web-based terminal access    | `true`  |
| `ssh_helper`             | SSH connection helper        | `true`  |
| `port_forwarding_helper` | Port forwarding interface    | `true`  |
| `vscode`                 | VS Code Desktop integration  | `true`  |
| `vscode_insiders`        | VS Code Insiders integration | `false` |

## Custom apps

Define custom applications for your dev container using the `apps` array:

```json
{
  "name": "My Dev Container",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "customizations": {
    "coder": {
      "apps": [
        {
          "slug": "zed",
          "displayName": "Zed Editor",
          "url": "zed://ssh/${localEnv:CODER_WORKSPACE_AGENT_NAME}.${localEnv:CODER_WORKSPACE_NAME}.${localEnv:CODER_WORKSPACE_OWNER_NAME}.coder${containerWorkspaceFolder}",
          "external": true,
          "icon": "/icon/zed.svg",
          "order": 1
        }
      ]
    }
  }
}
```

This example adds a Zed Editor button that opens the dev container directly in
the Zed desktop app via its SSH remote feature.

Each app supports the following properties:

| Property      | Type    | Description                                                   |
|---------------|---------|---------------------------------------------------------------|
| `slug`        | string  | Unique identifier for the app (required)                      |
| `displayName` | string  | Human-readable name shown in the UI                           |
| `url`         | string  | URL to open (supports variable interpolation)                 |
| `command`     | string  | Command to run instead of opening a URL                       |
| `icon`        | string  | Path to an icon (e.g., `/icon/code.svg`)                      |
| `openIn`      | string  | `"tab"` or `"slim-window"` (default: `"slim-window"`)         |
| `share`       | string  | `"owner"`, `"authenticated"`, `"organization"`, or `"public"` |
| `external`    | boolean | Open as external URL (e.g., for desktop apps)                 |
| `group`       | string  | Group name for organizing apps in the UI                      |
| `order`       | number  | Sort order for display                                        |
| `hidden`      | boolean | Hide the app from the UI                                      |
| `subdomain`   | boolean | Use subdomain-based access                                    |
| `healthCheck` | object  | Health check configuration (see below)                        |

### Health checks

Configure health checks to monitor app availability:

```json
{
  "customizations": {
    "coder": {
      "apps": [
        {
          "slug": "web-server",
          "displayName": "Web Server",
          "url": "http://localhost:8080",
          "healthCheck": {
            "url": "http://localhost:8080/healthz",
            "interval": 5,
            "threshold": 2
          }
        }
      ]
    }
  }
}
```

Health check properties:

| Property    | Type   | Description                                     |
|-------------|--------|-------------------------------------------------|
| `url`       | string | URL to check for health status                  |
| `interval`  | number | Seconds between health checks                   |
| `threshold` | number | Number of failures before marking app unhealthy |

## Variable interpolation

App URLs and other string values support variable interpolation for dynamic
configuration.

### Environment variables

Use `${localEnv:VAR_NAME}` to reference environment variables, with optional
default values:

```json
{
  "customizations": {
    "coder": {
      "apps": [
        {
          "slug": "my-app",
          "url": "http://${localEnv:HOST:127.0.0.1}:${localEnv:PORT:8080}"
        }
      ]
    }
  }
}
```

### Coder-provided variables

Coder provides these environment variables automatically:

| Variable                            | Description                        |
|-------------------------------------|------------------------------------|
| `CODER_WORKSPACE_NAME`              | Name of the workspace              |
| `CODER_WORKSPACE_OWNER_NAME`        | Username of the workspace owner    |
| `CODER_WORKSPACE_AGENT_NAME`        | Name of the dev container agent    |
| `CODER_WORKSPACE_PARENT_AGENT_NAME` | Name of the parent workspace agent |
| `CODER_URL`                         | URL of the Coder deployment        |
| `CONTAINER_ID`                      | Docker container ID                |

### Dev container variables

Standard dev container variables are also available:

| Variable                      | Description                                |
|-------------------------------|--------------------------------------------|
| `${containerWorkspaceFolder}` | Workspace folder path inside the container |
| `${localWorkspaceFolder}`     | Workspace folder path on the host          |

### Session token

Use `$SESSION_TOKEN` in external app URLs to include the user's session token:

```json
{
  "customizations": {
    "coder": {
      "apps": [
        {
          "slug": "custom-ide",
          "displayName": "Custom IDE",
          "url": "custom-ide://open?token=$SESSION_TOKEN&folder=${containerWorkspaceFolder}",
          "external": true
        }
      ]
    }
  }
}
```

## Feature options as environment variables

When your dev container uses features, Coder exposes feature options as
environment variables. The format is `FEATURE_<FEATURE_NAME>_OPTION_<OPTION_NAME>`.

For example, with this feature configuration:

```json
{
  "features": {
    "ghcr.io/coder/devcontainer-features/code-server:1": {
      "port": 9090
    }
  }
}
```

Coder creates `FEATURE_CODE_SERVER_OPTION_PORT=9090`, which you can reference in
your apps:

```json
{
  "features": {
    "ghcr.io/coder/devcontainer-features/code-server:1": {
      "port": 9090
    }
  },
  "customizations": {
    "coder": {
      "apps": [
        {
          "slug": "code-server",
          "displayName": "Code Server",
          "url": "http://localhost:${localEnv:FEATURE_CODE_SERVER_OPTION_PORT:8080}",
          "icon": "/icon/code.svg"
        }
      ]
    }
  }
}
```

## Next steps

- [Working with dev containers](./working-with-dev-containers.md) — SSH, IDE
  integration, and port forwarding
- [Troubleshooting dev containers](./troubleshooting-dev-containers.md) —
  Diagnose common issues

---

# Troubleshooting dev containers

Source: https://coder.com/docs/user-guides/devcontainers/troubleshooting-dev-containers

# Troubleshooting dev containers

## Dev container not starting

If your dev container fails to start:

1. Check the agent logs for error messages:

   - `/tmp/coder-agent.log`
   - `/tmp/coder-startup-script.log`
   - `/tmp/coder-script-[script_id].log`

1. Verify Docker is available in your workspace (see below).
1. Ensure the `devcontainer.json` file is valid JSON.
1. Check that the repository has been cloned correctly.
1. Verify the resource limits in your workspace are sufficient.

## Docker not available

Dev containers require Docker, either via a running daemon (Docker-in-Docker) or
a mounted socket from the host. Your template determines which approach is used.

**If using Docker-in-Docker**, check that the daemon is running:

```console
sudo service docker status
sudo service docker start  # if not running
```

**If using a mounted socket**, verify the socket exists and is accessible:

```console
ls -la /var/run/docker.sock
docker ps  # test access
```

If you get permission errors, your user may need to be in the `docker` group.

## Finding your dev container agent

Use `coder show` to list all agents in your workspace, including dev container
sub-agents:

```console
coder show <workspace>
```

The agent name is derived from the workspace folder path. For details on how
names are generated, see [Agent naming](./index.md#agent-naming).

## SSH connection issues

If `coder ssh <workspace>.<agent>` fails:

1. Verify the agent name using `coder show <workspace>`.
1. Check that the dev container is running:

   ```console
   docker ps
   ```

1. Check the workspace agent logs for container-related errors:

   ```console
   grep -i container /tmp/coder-agent.log
   ```

## VS Code connection issues

VS Code connects to dev containers through the Coder extension. The extension
uses the sub-agent information to route connections through the parent workspace
agent to the dev container. If VS Code fails to connect:

1. Ensure you have the latest Coder VS Code extension.
1. Verify the dev container is running in the Coder dashboard.
1. Check the parent workspace agent is healthy.
1. Try restarting the dev container from the dashboard.

## Dev container features not working

If features from your `devcontainer.json` aren't being applied:

1. Rebuild the container to ensure features are installed fresh.
1. Check the container build output for feature installation errors.
1. Verify the feature reference format is correct:

   ```json
   {
     "features": {
       "ghcr.io/devcontainers/features/node:1": {}
     }
   }
   ```

## Slow container startup

If your dev container takes a long time to start:

1. **Use a pre-built image** instead of building from a Dockerfile. This avoids
   the image build step, though features and lifecycle scripts still run.
1. **Minimize features**. Each feature executes as a separate Docker layer
   during the image build, which is typically the slowest part. Changing
   `devcontainer.json` invalidates the layer cache, causing features to
   reinstall on rebuild.
1. **Check lifecycle scripts**. Commands in `postStartCommand` run on every
   container start. Commands in `postCreateCommand` run once per build, so
   they execute again after each rebuild.

## Getting more help

If you continue to experience issues:

1. Collect logs from `/tmp/coder-agent.log` (both workspace and container).
1. Note the exact error messages.
1. Check [Coder GitHub issues](https://github.com/coder/coder/issues) for
   similar problems.
1. Contact your Coder administrator for template-specific issues.

---

# Dotfiles

Source: https://coder.com/docs/user-guides/workspace-dotfiles

# Dotfiles

<!-- markdown-link-check-disable -->

Coder offers the `coder dotfiles <repo>` command which simplifies workspace
personalization. Our behavior is consistent with Codespaces, so
[their documentation](https://docs.github.com/en/codespaces/customizing-your-codespace/personalizing-codespaces-for-your-account#dotfiles)
explains how it loads your repo.

<!-- markdown-link-check-enable -->

You can read more on dotfiles best practices [here](https://dotfiles.github.io).

## From templates

Templates can prompt users for their dotfiles repo URL, which will personalize
your workspace automatically.

![Dotfiles in workspace creation](../images/user-guides/dotfiles-module.png)

> [!NOTE]
> Template admins: this can be enabled quite easily with a our
> [dotfiles module](https://registry.coder.com/modules/dotfiles) using just a
> few lines in the template.

## Personalize script

Templates may be configured to support executing a `~/personalize` script on
startup which users can populate with commands to customize their workspaces.

You can even fill `personalize` with `coder dotfiles <repo>`, but those looking
for a simpler approach can inline commands like so:

```bash
#!/bin/bash
sudo apt update
# Install some of my favorite tools every time my workspace boots
sudo apt install -y neovim fish cargo
```

> [!NOTE]
> Template admins: refer to
> [this module](https://registry.coder.com/modules/personalize) to enable the
> `~/personalize` script on templates.

## Setup script support

User can setup their dotfiles by creating one of the following script files in
their dotfiles repo:

- `install.sh`
- `install`
- `bootstrap.sh`
- `bootstrap`
- `script/bootstrap`
- `setup.sh`
- `setup`
- `script/setup`

If any of the above files are found (in the specified order), Coder will try to
execute the first match. After the first match is found, other files will be
ignored.

The setup script must be executable, otherwise the dotfiles setup will fail. If
you encounter this issue, you can fix it by making the script executable using
the following commands:

```shell
cd <path_to_dotfiles_repo>
chmod +x <script_name>
git commit -m "Make <script_name> executable" <script_name>
git push
```

---

# User secrets

Source: https://coder.com/docs/user-guides/user-secrets

# User secrets (Early Access)

User secrets let you store secret values in Coder and make them available in
every workspace you own.

> [!NOTE]
> User secrets are in Early Access and may change. For more information, see
> [feature stages](../install/releases/feature-stages.md#early-access-features).

## How user secrets work

Each user secret has:

- A name, used to manage the secret with the CLI or REST API.
- A value, which contains the sensitive content.
- An optional description.
- An optional environment variable target, file target, or both.

A secret without an environment variable target or file target is stored, but is
not injected into workspaces.

User secrets apply to all workspaces that you own. Coder injects user secrets
when a workspace starts. If you create, update, or delete a secret while a
workspace is running, restart the workspace before relying on that change.

Environment variable secrets are available to startup scripts and workspace
sessions. File secrets are written before startup scripts run.

Secret values are omitted from CLI output and REST API responses after you
create or update them.

> [!WARNING]
> Anyone with shell or file access to a workspace can read secrets injected into
> that workspace. Do not share a workspace that has injected secrets with users
> who should not access those values.

## Create a secret

Use `coder secret create <name>` to create a user secret. For sensitive values,
provide the value through non-interactive stdin with a pipe or redirect. This
keeps the value out of your shell history and process arguments.

### Create an environment variable secret

Use `--env` to inject a secret into your workspaces as an environment variable.
The secret is available under the environment variable name you provide. User
secret environment variables take precedence over template-defined environment
variables with the same name, including variables set with `coder_env`.

```sh
echo -n "$API_KEY" | coder secret create api-key \
  --description "API key for workspace tools" \
  --env API_KEY
```

### Create a file secret

Use `--file` to inject a secret as a file in your workspaces. File paths must
start with `~/` or `/`.

```sh
coder secret create tool-config \
  --description "Tool configuration" \
  --file ~/.config/tool/config.json \
  < ./tool-config.json
```

Coder creates parent directories as needed. If the file already exists, including
a file created by a template or image, Coder updates the contents and preserves
the existing permissions.

### Create a secret with environment variable and file targets

You can inject the same secret as both an environment variable and a file:

```sh
echo -n "$TOKEN" | coder secret create service-token \
  --description "Service token for workspace tools" \
  --env SERVICE_TOKEN \
  --file ~/.config/service/token
```

### Use `--value`

You can also provide a secret value with `--value`:

```sh
coder secret create api-key \
  --value "$API_KEY" \
  --description "API key for workspace tools" \
  --env API_KEY
```

For sensitive values, prefer stdin because `--value` can expose the secret in
shell history or process arguments.

Stdin is read verbatim. If the source file ends with a trailing newline, Coder
stores that newline as part of the secret value. Use `echo -n` when you do not
want to store a trailing newline:

```sh
echo -n "$API_KEY" | coder secret create api-key --env API_KEY
```

## Update a secret

Use `coder secret update` to update a secret value, description, environment
variable target, or file target. At least one of `--value`, `--description`,
`--env`, or `--file` must be specified.

```sh
# Update a secret value.
echo -n "$NEW_API_KEY" | coder secret update api-key

# Change the environment variable target.
coder secret update api-key --env NEW_API_KEY

# Clear the file injection target while keeping the secret.
coder secret update api-key --file ""
```

## List and delete secrets

List, show, and delete your secrets with the `coder secret` CLI:

```sh
# List all of your secrets.
coder secret list

# Show a single secret by name.
coder secret list api-key

# Delete a secret you no longer need.
coder secret delete api-key
```

Deleting a secret removes it from Coder and stops Coder from injecting it during
future workspace starts. Deleting a secret does not remove the value from
running processes or delete files that were already written in existing
workspaces.

The list and show commands return secret metadata only. They never return the
secret value.

For full command details, see [`coder secret`](../reference/cli/secret.md) and
the [Secrets API reference](../reference/api/secrets.md).

---

# Administration

Source: https://coder.com/docs/admin

# Administration

![Admin settings general page](../images/admin/admin-settings-general.png)

These guides contain information on managing the Coder control plane and
[authoring templates](./templates/index.md).

First time viewers looking to set up control plane access can start with the
[configuration guide](./setup/index.md). If you're a team lead looking to design
environments for your developers, check out our
[templates guides](./templates/index.md). If you are a developer using Coder, we
recommend the [user guides](../user-guides/index.md).

For automation and scripting workflows, see our [CLI](../reference/cli/index.md)
and [API](../reference/api/index.md) docs.

For any information not strictly contained in these sections, check out our
[Tutorials](../tutorials/index.md) and [FAQs](../tutorials/faqs.md).

## What is an image, template, dev container, or workspace

### Image

- A [base image](./templates/managing-templates/image-management.md) contains
  OS-level packages and utilities that the Coder workspace is built on. It can
  be an [example image](https://github.com/coder/images), custom image in your
  registry, or one from [Docker Hub](https://hub.docker.com/search). It is
  defined in each template.
- Managed by: Externally to Coder.

### Template

- [Templates](./templates/index.md) include infrastructure-level dependencies
  for the workspace. For example, a template can include Kubernetes
  PersistentVolumeClaims, Docker containers, or EC2 VMs.
- Managed by: Template administrators from within the Coder deployment.

### Startup scripts

- Agent startup scripts apply to all users of a template. This is an
  intentionally flexible area that template authors have at their disposal to
  manage the "last mile" of workspace creation.
- Managed by: Coder template administrators.

### Workspace

- A [workspace](../user-guides/workspace-management.md) is the environment that
  a developer works in. Developers on a team each work from their own workspace
  and can use [multiple IDEs](../user-guides/workspace-access/index.md).
- Managed by: Developers

### Development containers (dev containers)

- A
  [Development Container](./integrations/devcontainers/index.md)
  is an open-source specification for defining development environments (called
  dev containers). It is generally stored in VCS alongside associated source
  code. It can reference an existing base image, or a custom Dockerfile that
  will be built on-demand.
- Managed by: Dev Teams

### Dotfiles / personalization

- Users may have their own specific preferences relating to shell prompt, custom
  keybindings, color schemes, and more. Users can leverage Coder's
  [dotfiles support](../user-guides/workspace-dotfiles.md) or create their own
  script to personalize their workspace. Be aware that users with root
  permissions in their workspace can override almost all of the previous
  configuration.
- Managed by: Individual Users

<children></children>

---

# Setup

Source: https://coder.com/docs/admin/setup

# Configure Control Plane Access

Coder server's primary configuration is done via environment variables. For a
full list of the options, run `coder server --help` or see our
[CLI documentation](../../reference/cli/server.md).

## Access URL

`CODER_ACCESS_URL` is required if you are not using the tunnel. Set this to the
external URL that users and workspaces use to connect to Coder (e.g.
<https://coder.example.com>). This should not be localhost.

Access URL should be an external IP address or domain with DNS records pointing to Coder.

### Tunnel

If an access URL is not specified, Coder will create a publicly accessible URL
to reverse proxy your deployment for simple setup.

## Address

You can change which port(s) Coder listens on.

```shell
# Listen on port 80
export CODER_HTTP_ADDRESS=0.0.0.0:80

# Enable TLS and listen on port 443)
export CODER_TLS_ENABLE=true
export CODER_TLS_ADDRESS=0.0.0.0:443

## Redirect from HTTP to HTTPS
export CODER_REDIRECT_TO_ACCESS_URL=true

# Start the Coder server
coder server
```

## Wildcard access URL

> [!TIP]
> Learn more about the [importance and benefits of wildcard access URLs](../networking/wildcard-access-url.md)

`CODER_WILDCARD_ACCESS_URL` is necessary for
[port forwarding](../networking/port-forwarding.md#dashboard) via the dashboard
or running [coder_apps](../templates/index.md) on an absolute path. Set this to
a wildcard subdomain that resolves to Coder (e.g. `*.coder.example.com`).

> [!NOTE]
> We do not recommend using a top-level-domain for Coder wildcard access
> (for example `*.workspaces`), even on private networks with split-DNS. Some
> browsers consider these "public" domains and will refuse Coder's cookies,
> which are vital to the proper operation of this feature.

If you are providing TLS certificates directly to the Coder server, either

1. Use a single certificate and key for both the root and wildcard domains.
1. Configure multiple certificates and keys via
   [`coder.tls.secretNames`](https://github.com/coder/coder/blob/main/helm/coder/values.yaml)
   in the Helm Chart, or
   [`--tls-cert-file`](../../reference/cli/server.md#--tls-cert-file) and
   [`--tls-key-file`](../../reference/cli/server.md#--tls-key-file) command line
   options (these both take a comma separated list of files; list certificates
   and their respective keys in the same order).

After you enable the wildcard access URL, you should [disable path-based apps](../../tutorials/best-practices/security-best-practices.md#disable-path-based-apps) for security.

## TLS & Reverse Proxy

The Coder server can directly use TLS certificates with `CODER_TLS_ENABLE` and
accompanying configuration flags. However, Coder can also run behind a
reverse-proxy to terminate TLS certificates from LetsEncrypt.

- [Apache](../../tutorials/reverse-proxy-apache.md)
- [Caddy](../../tutorials/reverse-proxy-caddy.md)
- [NGINX](../../tutorials/reverse-proxy-nginx.md)

### Kubernetes TLS configuration

Below are the steps to configure Coder to terminate TLS when running on
Kubernetes. You must have the certificate `.key` and `.crt` files in your
working directory prior to step 1.

1. Create the TLS secret in your Kubernetes cluster

   ```shell
   kubectl create secret tls coder-tls -n <coder-namespace> --key="tls.key" --cert="tls.crt"
   ```

   You can use a single certificate for the both the access URL and wildcard access URL. The certificate CN must match the wildcard domain, such as `*.example.coder.com`.

1. Reference the TLS secret in your Coder Helm chart values

   ```yaml
   coder:
     tls:
         secretName:
         - coder-tls

     # Alternatively, if you use an Ingress controller to terminate TLS,
     # set the following values:
     ingress:
         enable: true
         secretName: coder-tls
         wildcardSecretName: coder-tls
   ```

## PostgreSQL Database

Coder uses a PostgreSQL database to store users, workspace metadata, and other
deployment information. Use `CODER_PG_CONNECTION_URL` to set the database that
Coder connects to. If unset, PostgreSQL binaries will be downloaded from Maven
(<https://repo1.maven.org/maven2>) and store all data in the config root.

> [!NOTE]
> Postgres 13 is the minimum supported version.

If you are using the built-in PostgreSQL deployment and need to use `psql` (aka
the PostgreSQL interactive terminal), output the connection URL with the
following command:

```console
$ coder server postgres-builtin-url
psql "postgres://coder@localhost:49627/coder?sslmode=disable&password=feU...yI1"
```

### Migrating from the built-in database to an external database

To migrate from the built-in database to an external database, follow these
steps:

1. Stop your Coder deployment.
1. Run `coder server postgres-builtin-serve` in a background terminal.
1. Run `coder server postgres-builtin-url` and copy its output command.
1. Run `pg_dump <built-in-connection-string> > coder.sql` to dump the internal
   database to a file.
1. Restore that content to an external database with
   `psql <external-connection-string> < coder.sql`.
1. Start your Coder deployment with
   `CODER_PG_CONNECTION_URL=<external-connection-string>`.

## Configuring Coder behind a proxy

To configure Coder behind a corporate proxy, set the environment variables
`HTTP_PROXY` and `HTTPS_PROXY`. Be sure to restart the server. Lowercase values
(e.g. `http_proxy`) are also respected in this case.

## Continue your setup with external authentication

Coder supports external authentication via OAuth2.0. This allows enabling
integrations with Git providers, such as GitHub, GitLab, and Bitbucket.

External authentication can also be used to integrate with external services
like JFrog Artifactory and others.

Please refer to the [external authentication](../external-auth/index.md) section for
more information.

## Up Next

- [Setup and manage templates](../templates/index.md)
- [Setup external provisioners](../provisioners/index.md)

---

# Appearance

Source: https://coder.com/docs/admin/setup/appearance

# Appearance

> [!NOTE]
> Customizing Coder's appearance is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Customize the look of your Coder deployment to meet your enterprise
requirements.

You can access the Appearance settings by navigating to
`Deployment > Appearance`.

![application name and logo url](../../images/admin/setup/appearance/application-name-logo-url.png)

## Application Name

Specify a custom application name to be displayed on the login page. The default
is Coder.

## Logo URL

Specify a custom URL for your enterprise's logo to be displayed on the sign in
page and in the top left corner of the dashboard. The default is the Coder logo.

## Announcement Banners

![announcement banner](../../images/admin/setup/appearance/announcement_banner_settings.png)

Announcement Banners let admins post important messages to all site users. Only
Site Owners may set the announcement banners.

Example: Use multiple announcement banners for concurrent deployment-wide
updates, such as maintenance or new feature rollout.

![Multiple announcements](../../images/admin/setup/appearance/multiple-banners.PNG)

Example: Adhere to government network classification requirements and notify
users of which network their Coder deployment is on.

![service banner secret](../../images/admin/setup/appearance/service-banner-secret.png)

## OIDC Login Button Customization

[Use environment variables to customize](../users/oidc-auth/index.md#oidc-login-customization)
the text and icon on the OIDC button on the Sign In page.

## Support Links

Support links let admins adjust the user dropdown menu to include links
referring to internal company resources. The menu section replaces the original
menu positions: documentation, report a bug to GitHub, or join the Discord
server.

![support links](../../images/admin/setup/appearance/support-links.png)

### Icons

The link icons are optional, and can be set to any url or
[builtin icon](../templates/extending-templates/icons.md#bundled-icons),
additionally `bug`, `chat`, `docs`, and `star` are available as special icons.

### Location

The `location` property is optional and determines where the support link will
be displayed:

- `navbar` - displays the link as a button in the top navigation bar
- `dropdown` - displays the link in the user dropdown menu (default)

If the `location` property is not specified, the link will be displayed in the
user dropdown menu.

### Configuration

#### Kubernetes

To configure support links in your Coder Kubernetes deployment, update your Helm
chart values as follows:

```yaml
coder:
  env:
    - name: CODER_SUPPORT_LINKS
      value: >
        [{"name": "Hello GitHub", "target": "https://github.com/coder/coder",
        "icon": "bug"},
         {"name": "Hello Slack", "target":
        "https://codercom.slack.com/archives/C014JH42DBJ", "icon":
        "/icon/slack.svg"},
         {"name": "Hello Discord", "target": "https://discord.gg/coder", "icon":
        "/icon/discord.svg", "location": "navbar"},
         {"name": "Hello Foobar", "target": "https://foo.com/bar", "icon":
        "/emojis/1f3e1.png"}]
```

#### System package

if running as a system service, set an environment variable
`CODER_SUPPORT_LINKS` in `/etc/coder.d/coder.env` as follows,

```env
CODER_SUPPORT_LINKS='[{"name": "Hello GitHub", "target": "https://github.com/coder/coder", "icon": "bug"}, {"name": "Hello Slack", "target": "https://codercom.slack.com/archives/C014JH42DBJ", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/slack.svg"}, {"name": "Hello Discord", "target": "https://discord.gg/coder", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/discord.svg", "location": "navbar"}, {"name": "Hello Foobar", "target": "https://discord.gg/coder", "icon": "/emojis/1f3e1.png"}]'
```

For CLI, use,

```shell
export CODER_SUPPORT_LINKS='[{"name": "Hello GitHub", "target": "https://github.com/coder/coder", "icon": "bug"}, {"name": "Hello Slack", "target": "https://codercom.slack.com/archives/C014JH42DBJ", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/slack.svg"}, {"name": "Hello Discord", "target": "https://discord.gg/coder", "icon": "https://raw.githubusercontent.com/coder/coder/main/site/static/icon/discord.svg", "location": "navbar"}, {"name": "Hello Foobar", "target": "https://discord.gg/coder", "icon": "/emojis/1f3e1.png"}]'
coder-server
```

---

# Telemetry

Source: https://coder.com/docs/admin/setup/telemetry

# Telemetry

> [!NOTE]
> TL;DR: disable telemetry by setting <code>CODER_TELEMETRY_ENABLE=false</code>.

Coder collects telemetry from all installations by default. We believe our users
should have the right to know what we collect, why we collect it, and how we use
the data.

## What we collect

You can find a full list of the data we collect in our source code
[here](https://github.com/coder/coder/blob/main/coderd/telemetry/telemetry.go).
In particular, look at the struct types such as `Template` or `Workspace`.

As a rule, we **do not collect** the following types of information:

- Any data that could make your installation less secure
- Any data that could identify individual users, except the administrator.

For example, we do not collect parameters, environment variables, or user email
addresses. We do collect the administrator email.

## Why we collect

Telemetry helps us understand which features are most valuable, what use cases
to focus on, and which bugs to fix first.

Most cloud-based software products collect far more data than we do. They often
offer little transparency and configurability. It's hard to imagine our favorite
SaaS products existing without their creators having a detailed understanding of
user interactions. We want to wield some of that product development power to
build self-hosted, open-source software.

## Security

In the event we discover a critical security issue with Coder, we will use
telemetry to identify affected installations and notify their administrators.

## Toggling

You can turn telemetry on or off using either the
`CODER_TELEMETRY_ENABLE=[true|false]` environment variable or the
`--telemetry=[true|false]` command-line flag.

---

# Data Retention

Source: https://coder.com/docs/admin/setup/data-retention

# Data Retention

Coder supports configurable retention policies that automatically purge old
Audit Logs, Connection Logs, Workspace Agent Logs, API keys, and AI Gateway
records. These policies help manage database growth by removing records older
than a specified duration.

## Overview

Large deployments can accumulate significant amounts of data over time.
Retention policies help you:

- **Reduce database size**: Automatically remove old records to free disk space.
- **Improve performance**: Smaller tables mean faster queries and backups.
- **Meet compliance requirements**: Configure retention periods that align with
  your organization's data retention policies.

> [!NOTE]
> Retention policies are disabled by default (set to `0`) to preserve existing
> behavior. The exceptions are API keys and workspace agent logs, which default
> to 7 days.

## Configuration

You can configure retention policies using CLI flags, environment variables, or
a YAML configuration file.

### Settings

| Setting              | CLI Flag                           | Environment Variable                   | Default        | Description                             |
|----------------------|------------------------------------|----------------------------------------|----------------|-----------------------------------------|
| Audit Logs           | `--audit-logs-retention`           | `CODER_AUDIT_LOGS_RETENTION`           | `0` (disabled) | How long to retain Audit Log entries    |
| Connection Logs      | `--connection-logs-retention`      | `CODER_CONNECTION_LOGS_RETENTION`      | `0` (disabled) | How long to retain Connection Logs      |
| API Keys             | `--api-keys-retention`             | `CODER_API_KEYS_RETENTION`             | `7d`           | How long to retain expired API keys     |
| Workspace Agent Logs | `--workspace-agent-logs-retention` | `CODER_WORKSPACE_AGENT_LOGS_RETENTION` | `7d`           | How long to retain workspace agent logs |
| AI Gateway           | `--aibridge-retention`             | `CODER_AIBRIDGE_RETENTION`             | `60d`          | How long to retain AI Gateway records   |

> [!NOTE]
> AI Gateway retention is configured separately from other retention settings.
> See [AI Gateway Setup](../../ai-coder/ai-gateway/setup.md#data-retention) for
> detailed configuration options.

### Duration Format

Retention durations support days (`d`) and weeks (`w`) in addition to standard
Go duration units (`h`, `m`, `s`):

- `7d` - 7 days
- `2w` - 2 weeks
- `30d` - 30 days
- `90d` - 90 days
- `365d` - 1 year

### CLI Example

```bash
coder server \
  --audit-logs-retention=365d \
  --connection-logs-retention=90d \
  --api-keys-retention=7d \
  --workspace-agent-logs-retention=7d \
  --aibridge-retention=60d
```

### Environment Variables Example

```bash
export CODER_AUDIT_LOGS_RETENTION=365d
export CODER_CONNECTION_LOGS_RETENTION=90d
export CODER_API_KEYS_RETENTION=7d
export CODER_WORKSPACE_AGENT_LOGS_RETENTION=7d
export CODER_AIBRIDGE_RETENTION=60d
```

### YAML Configuration Example

```yaml
retention:
  audit_logs: 365d
  connection_logs: 90d
  api_keys: 7d
  workspace_agent_logs: 7d

aibridge:
  retention: 60d
```

## How Retention Works

### Background Purge Process

Coder runs a background process that periodically deletes old records. The
purge process:

1. Runs approximately every 10 minutes.
2. Processes records in batches to avoid database lock contention.
3. Deletes records older than the configured retention period.
4. Logs the number of deleted records for monitoring.

### Effective Retention

Each retention setting controls its data type independently:

- When set to a non-zero duration, records older than that duration are deleted.
- When set to `0`, retention is disabled and data is kept indefinitely.

### API Keys Special Behavior

API key retention only affects **expired** keys. A key is deleted only when:

1. The key has expired (past its `expires_at` timestamp).
2. The key has been expired for longer than the retention period.

Setting `--api-keys-retention=7d` deletes keys that expired more than 7 days
ago. Active keys are never deleted by the retention policy.

Keeping expired keys for a short period allows Coder to return a more helpful
error message when users attempt to use an expired key.

### Workspace Agent Logs Behavior

Workspace agent logs are deleted based on when the agent last connected, not the
age of the logs themselves. **Logs from the latest build of each workspace are
always retained** regardless of when the agent last connected. This ensures you
can always debug issues with active workspaces.

For non-latest builds, logs are deleted if the agent hasn't connected within the
retention period. Setting `--workspace-agent-logs-retention=7d` deletes logs for
agents that haven't connected in 7 days (excluding those from the latest build).

### AI Gateway Data Behavior

AI Gateway retention applies to interception records and all related data,
including token usage, prompts, and tool invocations. The default of 60 days
provides a reasonable balance between storage costs and the ability to analyze
usage patterns.

For details on what data is retained, see the
[AI Gateway Data Retention](../../ai-coder/ai-gateway/setup.md#data-retention)
documentation.

## Best Practices

### Recommended Starting Configuration

For most deployments, we recommend:

```yaml
retention:
  audit_logs: 365d
  connection_logs: 90d
  api_keys: 7d
  workspace_agent_logs: 7d

aibridge:
  retention: 60d
```

### Compliance Considerations

> [!WARNING]
> Audit Logs provide critical security and compliance information. Purging
> Audit Logs may impact your organization's ability to investigate security
> incidents or meet compliance requirements. Consult your security and
> compliance teams before configuring Audit Log retention.

Common compliance frameworks have varying retention requirements:

- **SOC 2**: Typically requires 1 year of audit logs.
- **HIPAA**: Requires 6 years for certain records.
- **PCI DSS**: Requires 1 year of audit logs, with 3 months immediately
  available.
- **GDPR**: Requires data minimization but does not specify maximum retention.

### External Log Aggregation

If you use an external log aggregation system (Splunk, Datadog, etc.), you can
configure shorter retention periods in Coder since logs are preserved
externally. See
[Capturing/Exporting Audit Logs](../security/audit-logs.md#capturingexporting-audit-logs)
for details on exporting logs.

### Database Maintenance

After enabling retention policies, you may want to run a `VACUUM` operation on
your PostgreSQL database to reclaim disk space. See
[Maintenance Procedures](../security/audit-logs.md#maintenance-procedures-for-the-audit-logs-table)
for guidance.

## Keeping Data Indefinitely

To keep data indefinitely for any data type, set its retention value to `0`:

```yaml
retention:
  audit_logs: 0s           # Keep audit logs forever
  connection_logs: 0s      # Keep connection logs forever
  api_keys: 0s             # Keep expired API keys forever
  workspace_agent_logs: 0s # Keep workspace agent logs forever

aibridge:
  retention: 0s            # Keep AI Gateway records forever
```

## Monitoring

The purge process logs deletion counts at the `DEBUG` level. To monitor
retention activity, enable debug logging or search your logs for entries
containing the table name (e.g., `audit_logs`, `connection_logs`, `api_keys`).

## Related Documentation

- [Audit Logs](../security/audit-logs.md): Learn about Audit Logs and manual
  purge procedures.
- [Connection Logs](../monitoring/connection-logs.md): Learn about Connection
  Logs and monitoring.
- [AI Gateway](../../ai-coder/ai-gateway/index.md): Learn about AI Gateway for
  centralized LLM and MCP proxy management.
- [AI Gateway Setup](../../ai-coder/ai-gateway/setup.md#data-retention): Configure
  AI Gateway data retention.
- [AI Gateway Monitoring](../../ai-coder/ai-gateway/monitoring.md): Monitor AI
  Gateway usage and metrics.

---

# Infrastructure

Source: https://coder.com/docs/admin/infrastructure

# Infrastructure

Learn how to spin up & manage Coder infrastructure.

## Architecture

Coder is a self-hosted platform that runs on your own servers. For large
deployments, we recommend running the control plane on Kubernetes. Workspaces
can be run as VMs or Kubernetes pods. The control plane (`coderd`) runs in a
single region. However, workspace proxies, provisioners, and workspaces can run
across regions or even cloud providers for the optimal developer experience.

Learn more about Coder's
[architecture, concepts, and dependencies](./architecture.md).

## Reference Architectures

We publish [reference architectures](./validated-architectures/index.md) that
include best practices around Coder configuration, infrastructure sizing,
autoscaling, and operational readiness for different deployment sizes (e.g.
`Up to 2000 users`).

## Scale Tests

Use our [scale test utility](./scale-utility.md) that can be run on your Coder
deployment to simulate user activity and measure performance.

## Monitoring

See our dedicated [Monitoring](../monitoring/index.md) section for details
around monitoring your Coder deployment via a bundled Grafana dashboard, health
check, and/or within your own observability stack via Prometheus metrics.

---

# Architecture

Source: https://coder.com/docs/admin/infrastructure/architecture

# Architecture

The Coder deployment model is flexible and offers various components that
platform administrators can deploy and scale depending on their use case. This
page describes possible deployments, challenges, and risks associated with them.

<div class="tabs">

## Community Edition

![Architecture Diagram](../../images/architecture-diagram.png)

## Premium

![Single Region Architecture Diagram](../../images/architecture-single-region.png)

## Multi-Region Premium

![Multi Region Architecture Diagram](../../images/architecture-multi-region.png)

</div>

## Primary components

### coderd

_coderd_ is the service created by running `coder server`. It is a thin API that
connects workspaces, provisioners and users. _coderd_ stores its state in
Postgres and is the only service that communicates with Postgres.

It offers:

- Dashboard (UI)
- HTTP API
- Dev URLs (HTTP reverse proxy to workspaces)
- Workspace Web Applications (e.g for easy access to `code-server`)
- Agent registration

### provisionerd

_provisionerd_ is the execution context for infrastructure modifying providers.
At the moment, the only provider is Terraform (running `terraform`).

By default, the Coder server runs multiple provisioner daemons.
[External provisioners](../provisioners/index.md) can be added for security or
scalability purposes.

### Workspaces

At the highest level, a workspace is a set of cloud resources. These resources
can be VMs, Kubernetes clusters, storage buckets, or whatever else Terraform
lets you dream up.

The resources that run the agent are described as _computational resources_,
while those that don't are called _peripheral resources_.

Each resource may also be _persistent_ or _ephemeral_ depending on whether
they're destroyed on workspace stop.

### Agents

An agent is the Coder service that runs within a user's remote workspace. It
provides a consistent interface for coderd and clients to communicate with
workspaces regardless of operating system, architecture, or cloud.

It offers the following services along with much more:

- SSH
- Port forwarding
- Liveness checks
- `startup_script` automation

Templates are responsible for
[creating and running agents](../templates/extending-templates/index.md#workspace-agents)
within workspaces.

## Service Bundling

While _coderd_ and Postgres can be orchestrated independently, our default
installation paths bundle them all together into one system service. It's
perfectly fine to run a production deployment this way, but there are certain
situations that necessitate decomposition:

- Reducing global client latency (distribute coderd and centralize database)
- Achieving greater availability and efficiency (horizontally scale individual
  services)

## Data Layer

### PostgreSQL (Recommended)

While `coderd` runs a bundled version of PostgreSQL, we recommend running an
external PostgreSQL 13+ database for production deployments.

A managed PostgreSQL database, with daily backups, is recommended:

- For AWS: Amazon RDS for PostgreSQL (preferably using
  [RDS IAM authentication](../../reference/cli/server.md#--postgres-auth)).
- For Azure: Azure Database for PostgreSQL
- Flexible Server For GCP: Cloud SQL for PostgreSQL

Learn more about database requirements:
[Database Health](../monitoring/health-check.md#database)

### Git Providers (Recommended)

Users will likely need to pull source code and other artifacts from a git
provider. The Coder control plane and workspaces will need network connectivity
to the git provider.

- [GitHub Enterprise](../external-auth/index.md#github-enterprise)
- [GitLab](../external-auth/index.md#gitlab-self-managed)
- [BitBucket](../external-auth/index.md#bitbucket-server)
- [Other Providers](../external-auth/index.md#self-managed-git-providers)

### Artifact Manager (Optional)

Workspaces and templates can pull artifacts from an artifact manager, such as
JFrog Artifactory. This can be configured on the infrastructure level, or in
some cases within Coder:

- Tutorial: [JFrog Artifactory and Coder](../integrations/jfrog-artifactory.md)

### Container Registry (Optional)

If you prefer not to pull container images for the control plane (`coderd`,
`provisionerd`) and workspaces from public container registry (Docker Hub,
GitHub Container Registry) you can run your own container registry with Coder.

To shorten the provisioning time, it is recommended to deploy registry mirrors
in the same region as the workspace nodes.

## Governance Layer

The governance layer provides centralized oversight and policy enforcement for
AI-powered development within Coder workspaces.

### AI Gateway

AI Gateway is a centralized gateway that sits between coding agents and LLM providers such
as OpenAI and Anthropic. Users authenticate through Coder instead of managing separate
provider API keys. All prompts, token usage, and tool invocations are recorded
for compliance and cost tracking.

Learn more: [AI Gateway](../../ai-coder/ai-gateway)

### Agent Firewall

Agent Firewall is a process-level firewall that restricts and audits network
access for AI agents running in workspaces. It enforces allowlist-based policies
controlling which domains, HTTP methods, and URL paths agents can reach, while
streaming audit logs to the Coder control plane for centralized monitoring.

Learn more: [Agent Firewall](../../ai-coder/agent-firewall/index.md)

---

# Validated Architectures

Source: https://coder.com/docs/admin/infrastructure/validated-architectures

# Coder Validated Architecture

Many customers operate Coder in complex organizational environments, consisting
of multiple business units, agencies, and/or subsidiaries. This can lead to
numerous Coder deployments, due to discrepancies in regulatory compliance, data
sovereignty, and level of funding across groups. The Coder Validated
Architecture (CVA) prescribes a Kubernetes-based deployment approach, enabling
your organization to deploy a stable Coder instance that is easier to maintain
and troubleshoot.

The following sections will detail the components of the Coder Validated
Architecture, provide guidance on how to configure and deploy these components,
and offer insights into how to maintain and troubleshoot your Coder environment.

- [General concepts](#general-concepts)
- [Kubernetes Infrastructure](#kubernetes-infrastructure)
- [PostgreSQL Database](#postgresql-database)
- [Operational readiness](#operational-readiness)

## Who is this document for?

This guide targets the following personas. It assumes a basic understanding of
cloud/on-premise computing, containerization, and the Coder platform.

| Role                      | Description                                                                    |
|---------------------------|--------------------------------------------------------------------------------|
| Platform Engineers        | Responsible for deploying, operating the Coder deployment and infrastructure   |
| Enterprise Architects     | Responsible for architecting Coder deployments to meet enterprise requirements |
| Managed Service Providers | Entities that deploy and run Coder software as a service for customers         |

## CVA Guidance

| CVA provides:                                  | CVA does not provide:                                                                    |
|------------------------------------------------|------------------------------------------------------------------------------------------|
| Single and multi-region K8s deployment options | Prescribing OS, or cloud vs. on-premise                                                  |
| Reference architectures for up to 3,000 users  | An approval of your architecture; the CVA solely provides recommendations and guidelines |
| Best practices for building a Coder deployment | Recommendations for every possible deployment scenario                                   |

For higher level design principles and architectural best practices, see Coder's
[Well-Architected Framework](https://coder.com/blog/coder-well-architected-framework).

## General concepts

This section outlines core concepts and terminology essential for understanding
Coder's architecture and deployment strategies.

### Administrator

An administrator is a user role within the Coder platform with elevated
privileges. Admins have access to administrative functions such as user
management, template definitions, insights, and deployment configuration.

### Coder control plane

Coder's control plane, also known as _coderd_, is the main service recommended
for deployment with multiple replicas to ensure high availability. It provides
an API for managing workspaces and templates, and serves the dashboard UI. In
addition, each _coderd_ replica hosts 3 Terraform [provisioners](#provisioner)
by default.

### User

A [user](../../users/index.md) is an individual who utilizes the Coder platform
to develop, test, and deploy applications using workspaces. Users can select
available templates to provision workspaces. They interact with Coder using the
web interface, the CLI tool, or directly calling API methods.

### Workspace

A [workspace](../../../user-guides/workspace-management.md) refers to an
isolated development environment where users can write, build, and run code.
Workspaces are fully configurable and can be tailored to specific project
requirements, providing developers with a consistent and efficient development
environment. Workspaces can be autostarted and autostopped, enabling efficient
resource management.

Users can connect to workspaces using SSH or via workspace applications like
`code-server`, facilitating collaboration and remote access. Additionally,
workspaces can be parameterized, allowing users to customize settings and
configurations based on their unique needs. Workspaces are instantiated using
Coder templates and deployed on resources created by provisioners.

### Template

A [template](../../../admin/templates/index.md) in Coder is a predefined
configuration for creating workspaces. Templates streamline the process of
workspace creation by providing pre-configured settings, tooling, and
dependencies. They are built by template administrators on top of Terraform,
allowing for efficient management of infrastructure resources. Additionally,
templates can utilize Coder modules to leverage existing features shared with
other templates, enhancing flexibility and consistency across deployments.
Templates describe provisioning rules for infrastructure resources offered by
Terraform providers.

### Workspace Proxy

A [workspace proxy](../../../admin/networking/workspace-proxies.md) serves as a
relay connection option for developers connecting to their workspace over SSH, a
workspace app, or through port forwarding. It helps reduce network latency for
geo-distributed teams by minimizing the distance network traffic needs to
travel. Notably, workspace proxies do not handle dashboard connections or API
calls.

### Provisioner

Provisioners in Coder execute Terraform during workspace and template builds.
While the platform includes built-in provisioner daemons by default, there are
advantages to employing external provisioners. These external daemons provide
secure build environments and reduce server load, improving performance and
scalability. Each provisioner can handle a single concurrent workspace build,
allowing for efficient resource allocation and workload management.

### Registry

The [Coder Registry](https://registry.coder.com) is a platform where you can
find starter templates and _Modules_ for various cloud services and platforms.

Templates help create self-service development environments using
Terraform-defined infrastructure, while _Modules_ simplify template creation by
providing common features like workspace applications, third-party integrations,
or helper scripts.

Please note that the Registry is a hosted service and isn't available for
offline use.

## Kubernetes Infrastructure

Kubernetes is the recommended, and supported platform for deploying Coder in the
enterprise. It is the hosting platform of choice for a large majority of Coder's
Fortune 500 customers, and it is the platform in which we build and test against
here at Coder.

### General recommendations

In general, it is recommended to deploy Coder into its own respective cluster,
separate from production applications. Keep in mind that Coder runs development
workloads, so the cluster should be deployed as such, without production-level
configurations.

### Compute

Deploy your Kubernetes cluster with two node groups, one for Coder's control
plane, and another for user workspaces (if you intend on leveraging K8s for
end-user compute).

#### Control plane nodes

The Coder control plane node group must be static, to prevent scale down events
from dropping pods, and thus dropping user connections to the dashboard UI and
their workspaces.

Coder's Helm Chart supports
[defining nodeSelectors, affinities, and tolerations](https://github.com/coder/coder/blob/e96652ebbcdd7554977594286b32015115c3f5b6/helm/coder/values.yaml#L221-L249)
to schedule the control plane pods on the appropriate node group.

#### Workspace nodes

Coder workspaces can be deployed either as Pods or Deployments in Kubernetes.
See our
[example Kubernetes workspace template](https://github.com/coder/coder/tree/main/examples/templates/kubernetes).
Configure the workspace node group to be auto-scaling, to dynamically allocate
compute as users start/stop workspaces at the beginning and end of their day.
Set nodeSelectors, affinities, and tolerations in Coder templates to assign
workspaces to the given node group:

```tf
resource "kubernetes_deployment" "coder" {
  spec {
    template {
      metadata {
        labels = {
          app = "coder-workspace"
        }
      }

      spec {
        affinity {
          pod_anti_affinity {
            preferred_during_scheduling_ignored_during_execution {
              weight = 1
              pod_affinity_term {
                label_selector {
                  match_expressions {
                    key      = "app.kubernetes.io/instance"
                    operator = "In"
                    values   = ["coder-workspace"]
                  }
                }
                topology_key = # add your node group label here
              }
            }
          }
        }

        tolerations {
          # Add your tolerations here
        }

        node_selector {
          # Add your node selectors here
        }

        container {
          image = "coder-workspace:latest"
          name  = "dev"
        }
      }
    }
  }
}
```

#### Node sizing

For sizing recommendations, see the below reference architectures:

- [Up to 1,000 users](1k-users.md)

- [Up to 2,000 users](2k-users.md)

- [Up to 3,000 users](3k-users.md)

- [Up to 10,000 users](10k-users.md)

### AWS Instance Types

For production AWS deployments, we recommend using non-burstable instance types,
such as `m5` or `c5`, instead of burstable instances, such as `t3`.
Burstable instances can experience significant performance degradation once
CPU credits are exhausted, leading to poor user experience under sustained load.

| Component         | Recommended Instance Type | Reason                                                   |
|-------------------|---------------------------|----------------------------------------------------------|
| coderd nodes      | `m5`                      | Balanced compute and memory for API and UI serving.      |
| Provisioner nodes | `c5`                      | Compute-optimized performance for faster builds.         |
| Workspace nodes   | `m5`                      | Balanced performance for general development workloads.  |
| Database nodes    | `db.m5`                   | Consistent database performance for reliable operations. |

### Networking

It is likely your enterprise deploys Kubernetes clusters with various networking
restrictions. With this in mind, Coder requires the following connectivity:

- Egress from workspace compute to the Coder control plane pods
- Egress from control plane pods to Coder's PostgreSQL database
- Egress from control plane pods to git and package repositories
- Ingress from user devices to the control plane Load Balancer or Ingress
  controller

We recommend configuring your network policies in accordance with the above.
Note that Coder workspaces do not require any ports to be open.

### Storage

If running Coder workspaces as Kubernetes Pods or Deployments, you will need to
assign persistent storage. We recommend leveraging a
[supported Container Storage Interface (CSI) driver](https://kubernetes-csi.github.io/docs/drivers.html)
in your cluster, with Dynamic Provisioning and read/write, to provide on-demand
storage to end-user workspaces.

The following Kubernetes volume types have been validated by Coder internally,
and/or by our customers:

- [PersistentVolumeClaim](https://kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim)
- [NFS](https://kubernetes.io/docs/concepts/storage/volumes/#nfs)
- [subPath](https://kubernetes.io/docs/concepts/storage/volumes/#using-subpath)
- [cephfs](https://kubernetes.io/docs/concepts/storage/volumes/#cephfs)

Our
[example Kubernetes workspace template](https://github.com/coder/coder/blob/5b9a65e5c137232351381fc337d9784bc9aeecfc/examples/templates/kubernetes/main.tf#L191-L219)
provisions a PersistentVolumeClaim block storage device, attached to the
Deployment.

It is not recommended to mount volumes from the host node(s) into workspaces,
for security and reliability purposes. The below volume types are _not_
recommended for use with Coder:

- [Local](https://kubernetes.io/docs/concepts/storage/volumes/#local)
- [hostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)

Not that Coder's control plane filesystem is ephemeral, so no persistent storage
is required.

## PostgreSQL database

Coder requires access to an external PostgreSQL database to store user data,
workspace state, template files, and more. Depending on the scale of the
user-base, workspace activity, and High Availability requirements, the amount of
CPU and memory resources required by Coder's database may differ.

### Disaster recovery

Prepare internal scripts for dumping and restoring your database. We recommend
scheduling regular database backups, especially before upgrading Coder to a new
release. Coder does not support downgrades without initially restoring the
database to the prior version.

### Performance efficiency

We highly recommend deploying the PostgreSQL instance in the same region (and if
possible, same availability zone) as the Coder server to optimize for low
latency connections. We recommend keeping latency under 10ms between the Coder
server and database.

When determining scaling requirements, take into account the following
considerations:

- `2 vCPU x 8 GB RAM x 512 GB storage`: A baseline for database requirements for
  Coder deployment with less than 1000 users, and low activity level (30% active
  users). This capacity should be sufficient to support 100 external
  provisioners.
- Storage size depends on user activity, workspace builds, log verbosity,
  overhead on database encryption, etc.
- Allocate two additional CPU core to the database instance for every 1000
  active users.
- Enable High Availability mode for database engine for large scale deployments.

#### Recommended instance types by cloud provider

For production deployments, we recommend using dedicated compute instances rather than burstable instances (like AWS t-family) which provide inconsistent CPU performance. Below are recommended instance types for each major cloud provider:

##### AWS (RDS/Aurora PostgreSQL)

- **Small deployments (<1000 users)**: `db.m6i.large` (2 vCPU, 8 GB RAM) or `db.r6i.large` (2 vCPU, 16 GB RAM)
- **Medium deployments (1000-2000 users)**: `db.m6i.xlarge` (4 vCPU, 16 GB RAM) or `db.r6i.xlarge` (4 vCPU, 32 GB RAM)
- **Large deployments (2000+ users)**: `db.m6i.2xlarge` (8 vCPU, 32 GB RAM) or `db.r6i.2xlarge` (8 vCPU, 64 GB RAM)

[Comparison](https://instances.vantage.sh/rds?memory_expr=%3E%3D0&vcpus_expr=%3E%3D0&memory_per_vcpu_expr=%3E%3D0&gpu_memory_expr=%3E%3D0&gpus_expr=%3E%3D0&maxips_expr=%3E%3D0&storage_expr=%3E%3D0&filter=db.r6i.large%7Cdb.m6i.large%7Cdb.m6i.xlarge%7Cdb.r6i.xlarge%7Cdb.r6i.2xlarge%7Cdb.m6i.2xlarge&region=us-east-1&pricing_unit=instance&cost_duration=hourly&reserved_term=yrTerm1Standard.noUpfront&compare_on=true)

##### Azure (Azure Database for PostgreSQL)

- **Small deployments (<1000 users)**: `Standard_D2s_v5` (2 vCPU, 8 GB RAM) or `Standard_E2s_v5` (2 vCPU, 16 GB RAM)
- **Medium deployments (1000-2000 users)**: `Standard_D4s_v5` (4 vCPU, 16 GB RAM) or `Standard_E4s_v5` (4 vCPU, 32 GB RAM)
- **Large deployments (2000+ users)**: `Standard_D8s_v5` (8 vCPU, 32 GB RAM) or `Standard_E8s_v5` (8 vCPU, 64 GB RAM)

[Comparison](https://instances.vantage.sh/azure?memory_expr=%3E%3D0&vcpus_expr=%3E%3D0&memory_per_vcpu_expr=%3E%3D0&gpu_memory_expr=%3E%3D0&gpus_expr=%3E%3D0&maxips_expr=%3E%3D0&storage_expr=%3E%3D0&filter=d2s-v5%7Ce2s-v5%7Cd4s-v5%7Ce4s-v5%7Ce8s-v5%7Cd8s-v5&region=us-east&pricing_unit=instance&cost_duration=hourly&reserved_term=yrTerm1Standard.allUpfront&compare_on=true)

##### Google Cloud (Cloud SQL for PostgreSQL)

- **Small deployments (<1000 users)**: `db-perf-optimized-N-2` (2 vCPU, 16 GB RAM)
- **Medium deployments (1000-2000 users)**: `db-perf-optimized-N-4` (4 vCPU, 32 GB RAM)
- **Large deployments (2000+ users)**: `db-perf-optimized-N-8` (8 vCPU, 64 GB RAM)

[Comparison](https://cloud.google.com/sql/docs/postgres/machine-series-overview#n2)

##### Storage recommendations

For optimal database performance, use the following storage types:

- **AWS RDS/Aurora**: Use `gp3` (General Purpose SSD) volumes with at least 3,000 IOPS for production workloads. For high-performance requirements, consider `io1` or `io2` volumes with provisioned IOPS.

- **Azure Database for PostgreSQL**: Use Premium SSD (P-series) with appropriate IOPS and throughput provisioning. Standard SSD can be used for development/test environments.

- **Google Cloud SQL**: Use SSD persistent disks for production workloads. Standard (HDD) persistent disks are suitable only for development or low-performance requirements.

If you enable
[database encryption](../../../admin/security/database-encryption.md) in Coder,
consider allocating an additional CPU core to every `coderd` replica.

#### Resource utilization guidelines

Below are general recommendations for sizing your PostgreSQL instance:

- Increase number of vCPU if CPU utilization or database latency is high.
- Allocate extra memory if database performance is poor, CPU utilization is low,
  and memory utilization is high.
- Utilize faster disk options (higher IOPS) such as SSDs or NVMe drives for
  optimal performance enhancement and possibly reduce database load.

## Operational readiness

Operational readiness in Coder is about ensuring that everything is set up
correctly before launching a platform into production. It involves making sure
that the service is reliable, secure, and easily scales accordingly to user-base
needs. Operational readiness is crucial because it helps prevent issues that
could affect workspace users experience once the platform is live.

### Helm Chart Configuration

1. Reference our
   [Helm chart values file](https://github.com/coder/coder/blob/main/helm/coder/values.yaml)
   and identify the required values for deployment.
1. Create a `values.yaml` and add it to your version control system.
1. Determine the necessary environment variables. Here is the
   [full list of supported server environment variables](../../../reference/cli/server.md).
1. Follow our documented
   [steps for installing Coder via Helm](../../../install/kubernetes.md).

### Template configuration

1. Establish dedicated accounts for users with the _Template Administrator_
   role.
1. Maintain Coder templates using
   [version control](../../templates/managing-templates/change-management.md).
1. Consider implementing a GitOps workflow to automatically push new template
   versions into Coder from git. For example, on GitHub, you can use the
   [Setup Coder](https://github.com/marketplace/actions/setup-coder) action.
1. Evaluate enabling
   [automatic template updates](../../templates/managing-templates/index.md#template-update-policies)
   upon workspace startup.

### Observability

1. Enable the Prometheus endpoint (environment variable:
   `CODER_PROMETHEUS_ENABLE`).
1. Deploy the
   [Coder Observability bundle](https://github.com/coder/observability) to
   leverage pre-configured dashboards, alerts, and runbooks for monitoring
   Coder. This includes integrations between Prometheus, Grafana, Loki, and
   Alertmanager.
1. Review the [Prometheus response](../../integrations/prometheus.md) and set up
   alarms on selected metrics.

### User support

1. Incorporate [support links](../../setup/appearance.md#support-links) into
   internal documentation accessible from the user context menu. Ensure that
   hyperlinks are valid and lead to up-to-date materials.
1. Encourage the use of `coder support bundle` to allow workspace users to
   generate and provide network-related diagnostic data.

---

# Up to 1,000 Users

Source: https://coder.com/docs/admin/infrastructure/validated-architectures/1k-users

# Reference Architecture: up to 1,000 users

The 1,000 users architecture is designed to cover a wide range of workflows.
Examples of subjects that might utilize this architecture include medium-sized
tech startups, educational units, or small to mid-sized enterprises.

The recommendations on this page apply to deployments with up to the following limits. If your needs
exceed any of these limits, consider increasing deployment resources or moving to the [next-higher
architectural tier](./2k-users.md).

| Users | Concurrent Running Workspaces | Concurrent Builds |
|-------|-------------------------------|-------------------|
| 1000  | 600                           | 60                |

## Hardware recommendations

### Coderd

| vCPU | Memory | Replicas |
|------|--------|----------|
| 2    | 8 GB   | 3        |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `2000m`
  - Set Memory request and limit to `8Gi`
- Coderd does not typically benefit from high performance disks like SSDs (unless you are co-locating provisioners).
- For small deployments (ca. 100 users, 10 concurrent workspace builds), it is
  acceptable to deploy provisioners on `coderd` replicas.
- Coderd instances should be deployed in the same region as the database.

### Provisioners

| vCPU | Memory | Replicas |
|------|--------|----------|
| 1    | 1 GB   | 60       |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `1000m`
  - Set Memory request and limit to `1Gi`
- If deploying on virtual machines, stack up to 30 provisioners per machine with a commensurate amount of memory and CPU.
- Provisioners benefit from high performance disks like SSDs.
- For small deployments (ca. 100 users, 10 concurrent workspace builds), it is
  acceptable to deploy provisioners on `coderd` nodes.
- If deploying workspaces to multiple clouds or multiple Kubernetes clusters, divide the provisioner replicas among the
  clouds or clusters according to expected usage.

### Database

| vCPU | Memory | Replicas |
|------|--------|----------|
| 8    | 30 GB  | 1        |

**Notes**:

- "General purpose" virtual machines, such as the M8-series in AWS work well.
- Deploy in the same region as `coderd`

### Workspaces

The following resource requirements are for the Coder Workspace Agent, which runs alongside your end users work, and as
such should be interpreted as the _bare minimum_ requirements for a Coder workspace. Size your workspaces to fit the use
case your users will be undertaking. If in doubt, chose sizes based on the development environments your users are
migrating from onto Coder.

| vCPU | Memory |
|------|--------|
| 0.1  | 128 MB |

## Footnotes for AWS instance types

- For production deployments, we recommend using non-burstable instance types,
  such as `m5` or `c5`, instead of burstable instances, such as `t3`.
  Burstable instances can experience significant performance degradation once
  CPU credits are exhausted, leading to poor user experience under sustained load.

---

# Up to 2,000 Users

Source: https://coder.com/docs/admin/infrastructure/validated-architectures/2k-users

# Reference Architecture: up to 2,000 users

In the 2,000 users architecture, there is a moderate increase in traffic,
suggesting a growing user base or expanding operations. This setup is
well-suited for mid-sized companies experiencing growth or for universities
seeking to accommodate their expanding user populations.

The recommendations on this page apply to deployments with up to the following limits. If your needs
exceed any of these limits, consider increasing deployment resources or moving to the [next-higher
architectural tier](./3k-users.md).

| Users | Concurrent Running Workspaces | Concurrent Builds |
|-------|-------------------------------|-------------------|
| 2000  | 1200                          | 120               |

**Observability**: Deploy monitoring solutions to gather Prometheus metrics and
visualize them with Grafana to gain detailed insights into infrastructure and
application behavior. This allows operators to respond quickly to incidents and
continuously improve the reliability and performance of the platform.

## Hardware recommendations

### Coderd

| vCPU | Memory | Replicas |
|------|--------|----------|
| 4    | 12 GB  | 3        |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `4000m`
  - Set Memory request and limit to `12Gi`
- Coderd does not typically benefit from high performance disks like SSDs (unless you are co-locating provisioners).
- Coderd instances should be deployed in the same region as the database.

### Workspace Proxies

If you choose to deploy workspaces in multiple geographic regions, provision
[Workspace Proxies](../../networking/workspace-proxies.md) in each region.

| vCPU | Memory | Replicas |
|------|--------|----------|
| 4    | 12 GB  | 3        |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `4000m`
  - Set Memory request and limit to `12Gi`
- Workspace Proxies do not typically benefit from high performance disks like SSDs.

### Provisioners

| vCPU | Memory | Replicas |
|------|--------|----------|
| 1    | 1 GB   | 120      |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `1000m`
  - Set Memory request and limit to `1Gi`
- If deploying on virtual machines, stack up to 30 provisioners per machine with a commensurate amount of memory and CPU.
- Provisioners benefit from high performance disks like SSDs.
- [Do not run provisioners on Coderd nodes](../../provisioners/index.md#disable-built-in-provisioners) at this scale.
- If deploying workspaces to multiple clouds or multiple Kubernetes clusters, divide the provisioner replicas among the
  clouds or clusters according to expected usage.

### Database

| vCPU | Memory | Replicas |
|------|--------|----------|
| 16   | 60 GB  | 1        |

**Notes**:

- "General purpose" virtual machines, such as the M8-series in AWS work well.
- Deploy in the same region as `coderd`

### Workspaces

The following resource requirements are for the Coder Workspace Agent, which runs alongside your end users work, and as
such should be interpreted as the _bare minimum_ requirements for a Coder workspace. Size your workspaces to fit the use
case your users will be undertaking. If in doubt, chose sizes based on the development environments your users are
migrating from onto Coder.

| vCPU | Memory |
|------|--------|
| 0.1  | 128 MB |

## Footnotes for AWS instance types

- For production deployments, we recommend using non-burstable instance types,
  such as `m5` or `c5`, instead of burstable instances, such as `t3`.
  Burstable instances can experience significant performance degradation once
  CPU credits are exhausted, leading to poor user experience under sustained load.

---

# Up to 3,000 Users

Source: https://coder.com/docs/admin/infrastructure/validated-architectures/3k-users

# Reference Architecture: up to 3,000 users

The 3,000 users architecture targets large-scale enterprises, possibly with
on-premises network and cloud deployments.

The recommendations on this page apply to deployments with up to the following limits. If your needs
exceed any of these limits, consider increasing deployment resources or moving to the [next-higher
architectural tier](./10k-users.md).

| Users | Concurrent Running Workspaces | Concurrent Builds |
|-------|-------------------------------|-------------------|
| 3000  | 1800                          | 180               |

**Observability**: Deploy monitoring solutions to gather Prometheus metrics and
visualize them with Grafana to gain detailed insights into infrastructure and
application behavior. This allows operators to respond quickly to incidents and
continuously improve the reliability and performance of the platform.

## Hardware recommendations

### Coderd

| vCPU | Memory | Replicas |
|------|--------|----------|
| 4    | 12 GB  | 4        |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `4000m`
  - Set Memory request and limit to `12Gi`
- Coderd does not typically benefit from high performance disks like SSDs (unless you are co-locating provisioners).
- Coderd instances should be deployed in the same region as the database.

### Workspace Proxies

If you choose to deploy workspaces in multiple geographic regions, provision
[Workspace Proxies](../../networking/workspace-proxies.md) in each region.

| vCPU | Memory | Replicas |
|------|--------|----------|
| 4    | 12 GB  | 4        |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `4000m`
  - Set Memory request and limit to `12Gi`
- Workspace Proxies do not typically benefit from high performance disks like SSDs.

### Provisioners

| vCPU | Memory | Replicas |
|------|--------|----------|
| 1    | 1 GB   | 180      |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `1000m`
  - Set Memory request and limit to `1Gi`
- If deploying on virtual machines, stack up to 30 provisioners per machine with a commensurate amount of memory and CPU.
- Provisioners benefit from high performance disks like SSDs.
- [Do not run provisioners on Coderd nodes](../../provisioners/index.md#disable-built-in-provisioners) at this scale.
- If deploying workspaces to multiple clouds or multiple Kubernetes clusters, divide the provisioner replicas among the
  clouds or clusters according to expected usage.

### Database

| vCPU | Memory | Replicas |
|------|--------|----------|
| 32   | 120 GB | 1        |

**Notes**:

- "General purpose" virtual machines, such as the M8-series in AWS work well.
- Deploy in the same region as `coderd`

### Workspaces

The following resource requirements are for the Coder Workspace Agent, which runs alongside your end users work, and as
such should be interpreted as the _bare minimum_ requirements for a Coder workspace. Size your workspaces to fit the use
case your users will be undertaking. If in doubt, chose sizes based on the development environments your users are
migrating from onto Coder.

| vCPU | Memory |
|------|--------|
| 0.1  | 128 MB |

## Footnotes for AWS instance types

- For production deployments, we recommend using non-burstable instance types,
  such as `m5` or `c5`, instead of burstable instances, such as `t3`.
  Burstable instances can experience significant performance degradation once
  CPU credits are exhausted, leading to poor user experience under sustained load.

---

# Up to 10,000 Users

Source: https://coder.com/docs/admin/infrastructure/validated-architectures/10k-users

# Reference Architecture: up to 10,000 users

The 10,000 users architecture targets enterprises with an extremely large global workforce of technical professionals or
applications requiring lots of simultaneous workspaces (for example, Agentic AI).

The recommendations on this page apply to deployments with up to the following limits. If your needs
exceed any of these limits, consider increasing deployment resources.

| Users | Concurrent Running Workspaces | Concurrent Builds |
|-------|-------------------------------|-------------------|
| 10000 | 6000                          | 600               |

**Observability**: Deploy monitoring solutions to gather Prometheus metrics and
visualize them with Grafana to gain detailed insights into infrastructure and
application behavior. This allows operators to respond quickly to incidents and
continuously improve the reliability and performance of the platform.

## Hardware recommendations

### Coderd

| vCPU | Memory | Replicas |
|------|--------|----------|
| 4    | 12 GB  | 10       |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `4000m`
  - Set Memory request and limit to `12Gi`
- Coderd does not typically benefit from high performance disks like SSDs (unless you are co-locating provisioners).
- Coderd instances should be deployed in the same region as the database.

### Workspace Proxies

If you choose to deploy workspaces in multiple geographic regions, provision
[Workspace Proxies](../../networking/workspace-proxies.md) in each region.

| vCPU | Memory | Replicas |
|------|--------|----------|
| 4    | 12 GB  | 10       |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `4000m`
  - Set Memory request and limit to `12Gi`
- Workspace Proxies do not typically benefit from high performance disks like SSDs.

### Provisioners

| vCPU | Memory | Replicas |
|------|--------|----------|
| 1    | 1 GB   | 600      |

**Notes**:

- "General purpose" virtual machines, such as N4-series in GCP or M8-series in AWS work well.
- If deploying on Kubernetes:
  - Set CPU request and limit to `1000m`
  - Set Memory request and limit to `1Gi`
- If deploying on virtual machines, stack up to 30 provisioners per machine with a commensurate amount of memory and CPU.
- Provisioners benefit from high performance disks like SSDs.
- [Do not run provisioners on Coderd nodes](../../provisioners/index.md#disable-built-in-provisioners) at this scale.
- If deploying workspaces to multiple clouds or multiple Kubernetes clusters, divide the provisioner replicas among the
  clouds or clusters according to expected usage.

### Database

| vCPU | Memory | Replicas |
|------|--------|----------|
| 64   | 240 GB | 1        |

**Notes**:

- "General purpose" virtual machines, such as the M8-series in AWS work well.
- Deploy in the same region as `coderd`

### Workspaces

The following resource requirements are for the Coder Workspace Agent, which runs alongside your end users work, and as
such should be interpreted as the _bare minimum_ requirements for a Coder workspace. Size your workspaces to fit the use
case your users will be undertaking. If in doubt, chose sizes based on the development environments your users are
migrating from onto Coder.

| vCPU | Memory |
|------|--------|
| 0.1  | 128 MB |

## Footnotes for AWS instance types

- For production deployments, we recommend using non-burstable instance types,
  such as `m5` or `c5`, instead of burstable instances, such as `t3`.
  Burstable instances can experience significant performance degradation once
  CPU credits are exhausted, leading to poor user experience under sustained load.

---

# Scale Testing

Source: https://coder.com/docs/admin/infrastructure/scale-testing

# Scale Testing

Scaling Coder involves planning and testing to ensure it can handle more load
without compromising service. This process encompasses infrastructure setup,
traffic projections, and aggressive testing to identify and mitigate potential
bottlenecks.

A dedicated Kubernetes cluster for Coder is recommended to configure, host, and
manage Coder workloads. Kubernetes provides container orchestration
capabilities, allowing Coder to efficiently deploy, scale, and manage workspaces
across a distributed infrastructure. This ensures high availability, fault
tolerance, and scalability for Coder deployments. Coder is deployed on this
cluster using the
[Helm chart](../../install/kubernetes.md#4-install-coder-with-helm).

For more information about scaling, see our [Coder scaling best practices](../../tutorials/best-practices/scale-coder.md).

## Methodology

Our scale tests include the following stages:

1. Prepare environment: create expected users and provision workspaces.

1. SSH connections: establish user connections with agents, verifying their
   ability to echo back received content.

1. Web Terminal: verify the PTY connection used for communication with Web
   Terminal.

1. Workspace application traffic: assess the handling of user connections with
   specific workspace apps, confirming their capability to echo back received
   content effectively.

1. Dashboard evaluation: verify the responsiveness and stability of Coder
   dashboards under varying load conditions. This is achieved by simulating user
   interactions using instances of headless Chromium browsers.

1. Cleanup: delete workspaces and users created in step 1.

## Infrastructure and setup requirements

The scale tests runner can distribute the workload to overlap single scenarios
based on the workflow configuration:

|                      | T0 | T1 | T2 | T3 | T4 | T5 | T6 |
|----------------------|----|----|----|----|----|----|----|
| SSH connections      | X  | X  | X  | X  |    |    |    |
| Web Terminal (PTY)   |    | X  | X  | X  | X  |    |    |
| Workspace apps       |    |    | X  | X  | X  | X  |    |
| Dashboard (headless) |    |    |    | X  | X  | X  | X  |

This pattern closely reflects how our customers naturally use the system. SSH
connections are heavily utilized because they're the primary communication
channel for IDEs with VS Code and JetBrains plugins.

The basic setup of scale tests environment involves:

1. Scale tests runner (32 vCPU, 128 GB RAM)
1. Coder: 2 replicas (4 vCPU, 16 GB RAM)
1. Database: 1 instance (2 vCPU, 32 GB RAM)
1. Provisioner: 50 instances (0.5 vCPU, 512 MB RAM)

The test is deemed successful if:

- Users did not experience interruptions in their
workflows,
- `coderd` did not crash or require restarts, and
- No other internal errors were observed.

## Traffic Projections

In our scale tests, we simulate activity from 2000 users, 2000 workspaces, and
2000 agents, with two items of workspace agent metadata being sent every 10
seconds. Here are the resulting metrics:

Coder:

- Median CPU usage for _coderd_: 3 vCPU, peaking at 3.7 vCPU while all tests are
  running concurrently.
- Median API request rate: 350 RPS during dashboard tests, 250 RPS during Web
  Terminal and workspace apps tests.
- 2000 agent API connections with latency: p90 at 60 ms, p95 at 220 ms.
- on average 2400 Web Socket connections during dashboard tests.

Provisionerd:

- Median CPU usage is 0.35 vCPU during workspace provisioning.

Database:

- Median CPU utilization is 80%, with a significant portion dedicated to writing
  workspace agent metadata.
- Memory utilization averages at 40%.
- `write_ops_count` between 6.7 and 8.4 operations per second.

## Available reference architectures

- [Up to 1,000 users](./validated-architectures/1k-users.md)

- [Up to 2,000 users](./validated-architectures/2k-users.md)

- [Up to 3,000 users](./validated-architectures/3k-users.md)
-
- [Up to 10,000 users](./validated-architectures/10k-users.md)

## Hardware recommendation

### Control plane: coderd

To ensure stability and reliability of the Coder control plane, it's essential
to focus on node sizing, resource limits, and the number of replicas. We
recommend referencing public cloud providers such as AWS, GCP, and Azure for
guidance on optimal configurations. A reasonable approach involves using scaling
formulas based on factors like CPU, memory, and the number of users.

While the minimum requirements specify 1 CPU core and 2 GB of memory per
`coderd` replica, we recommend that you allocate additional resources depending
on the workload size to ensure deployment stability.

#### CPU and memory usage

Enabling
[agent stats collection](../../reference/cli/server.md#--prometheus-collect-agent-stats)
(optional) may increase memory consumption.

Enabling direct connections between users and workspace agents (apps or SSH
traffic) can help prevent an increase in CPU usage. It is recommended to keep
[this option enabled](../../reference/cli/index.md#--disable-direct-connections)
unless there are compelling reasons to disable it.

Inactive users do not consume Coder resources.

#### Scaling formula

When determining scaling requirements, consider the following factors:

- `1 vCPU x 2 GB memory` for every 250 users: A reasonable formula to determine
  resource allocation based on the number of users and their expected usage
  patterns.
- API latency/response time: Monitor API latency and response times to ensure
  optimal performance under varying loads.
- Average number of HTTP requests: Track the average number of HTTP requests to
  gauge system usage and identify potential bottlenecks. The number of proxied
  connections: For a very high number of proxied connections, more memory is
  required.

#### HTTP API latency

For a reliable Coder deployment dealing with medium to high loads, it's
important that API calls for workspace/template queries and workspace build
operations respond within 300 ms. However, API template insights calls, which
involve browsing workspace agent stats and user activity data, may require more
time. Moreover, Coder API exposes WebSocket long-lived connections for Web
Terminal (bidirectional), and Workspace events/logs (unidirectional).

If the Coder deployment expects traffic from developers spread across the globe,
be aware that customer-facing latency might be higher because of the distance
between users and the load balancer. Fortunately, the latency can be improved
with a deployment of Coder
[workspace proxies](../networking/workspace-proxies.md).

#### Node Autoscaling

We recommend disabling the autoscaling for `coderd` nodes. Autoscaling can cause
interruptions for user connections, see
[Autoscaling](./scale-utility.md#autoscaling) for more details.

### Control plane: Workspace Proxies

When scaling [workspace proxies](../networking/workspace-proxies.md), follow the
same guidelines as for `coderd` above:

- `1 vCPU x 2 GB memory` for every 250 users.
- Disable autoscaling.

### Control plane: provisionerd

Each external provisioner can run a single concurrent workspace build. For
example, running 10 provisioner containers will allow 10 users to start
workspaces at the same time.

By default, the Coder server runs 3 built-in provisioner daemons, but the
_Premium_ Coder release allows for running external provisioners to separate the
load caused by workspace provisioning on the `coderd` nodes.

#### Scaling formula

When determining scaling requirements, consider the following factors:

- `1 vCPU x 1 GB memory x 2 concurrent workspace build`: A formula to determine
  resource allocation based on the number of concurrent workspace builds, and
  standard complexity of a Terraform template. _Rule of thumb_: the more
  provisioners are free/available, the more concurrent workspace builds can be
  performed.

#### Node Autoscaling

Autoscaling provisioners is not an easy problem to solve unless it can be
predicted when a number of concurrent workspace builds increases.

We recommend disabling autoscaling and adjusting the number of provisioners to
developer needs based on the workspace build queuing time.

### Data plane: Workspaces

To determine workspace resource limits and keep the best developer experience
for workspace users, administrators must be aware of a few assumptions.

- Workspace pods run on the same Kubernetes cluster, but possibly in a different
  namespace or on a separate set of nodes.
- Workspace limits (per workspace user):
  - Evaluate the workspace utilization pattern. For instance, web application
    development does not require high CPU capacity at all times, but will spike
    during builds or testing.
  - Evaluate minimal limits for single workspace. Include in the calculation
    requirements for Coder agent running in an idle workspace - 0.1 vCPU and 256
    MB. For instance, developers can choose between 0.5-8 vCPUs, and 1-16 GB
    memory.

#### Scaling formula

When determining scaling requirements, consider the following factors:

- `1 vCPU x 2 GB memory x 1 workspace`: A formula to determine resource
  allocation based on the minimal requirements for an idle workspace with a
  running Coder agent and occasional CPU and memory bursts for building
  projects.

#### Node Autoscaling

Workspace nodes can be set to operate in autoscaling mode to mitigate the risk
of prolonged high resource utilization.

One approach is to scale up workspace nodes when total CPU usage or memory
consumption reaches 80%. Another option is to scale based on metrics such as the
number of workspaces or active users. It's important to note that as new users
onboard, the autoscaling configuration should account for ongoing workspaces.

Scaling down workspace nodes to zero is not recommended, as it will result in
longer wait times for workspace provisioning by users. However, this may be
necessary for workspaces with special resource requirements (e.g. GPUs) that
incur significant cost overheads.

---

# Scaling Utilities

Source: https://coder.com/docs/admin/infrastructure/scale-utility

# Scale Tests and Utilities

We scale-test Coder with a built-in utility that can
be used in your environment for insights into how Coder scales with your
infrastructure. For scale-testing Kubernetes clusters we recommend that you install
and use the dedicated Coder template,
[scaletest-runner](https://github.com/coder/coder/tree/main/scaletest/templates/scaletest-runner).

Learn more about [Coder’s architecture](./architecture.md) and our
[scale-testing methodology](./scale-testing.md).

For more information about scaling, see our [Coder scaling best practices](../../tutorials/best-practices/scale-coder.md).

## Recent scale tests

The information in this doc is for reference purposes only, and is not intended
to be used as guidelines for infrastructure sizing.

Review the [Reference Architectures](./validated-architectures/index.md#node-sizing) for
hardware sizing recommendations.

| Environment      | Coder CPU | Coder RAM | Coder Replicas | Database          | Users | Concurrent builds | Concurrent connections (Terminal/SSH) | Coder Version | Last tested  |
|------------------|-----------|-----------|----------------|-------------------|-------|-------------------|---------------------------------------|---------------|--------------|
| Kubernetes (GKE) | 3 cores   | 12 GB     | 1              | db-f1-micro       | 200   | 3                 | 200 simulated                         | `v0.24.1`     | Jun 26, 2023 |
| Kubernetes (GKE) | 4 cores   | 8 GB      | 1              | db-custom-1-3840  | 1500  | 20                | 1,500 simulated                       | `v0.24.1`     | Jun 27, 2023 |
| Kubernetes (GKE) | 2 cores   | 4 GB      | 1              | db-custom-1-3840  | 500   | 20                | 500 simulated                         | `v0.27.2`     | Jul 27, 2023 |
| Kubernetes (GKE) | 2 cores   | 8 GB      | 2              | db-custom-2-7680  | 1000  | 20                | 1000 simulated                        | `v2.2.1`      | Oct 9, 2023  |
| Kubernetes (GKE) | 4 cores   | 16 GB     | 2              | db-custom-8-30720 | 2000  | 50                | 2000 simulated                        | `v2.8.4`      | Feb 28, 2024 |
| Kubernetes (GKE) | 2 cores   | 4 GB      | 2              | db-custom-2-7680  | 1000  | 50                | 1000 simulated                        | `v2.10.2`     | Apr 26, 2024 |

> [!NOTE]
> A simulated connection reads and writes random data at 40KB/s per connection.

## Scale testing utility

Since Coder's performance is highly dependent on the templates and workflows you
support, you may wish to use our internal scale testing utility against your own
environments.

> [!IMPORTANT]
> This utility is experimental.
>
> It is not subject to any compatibility guarantees and may cause interruptions
> for your users.
> To avoid potential outages and orphaned resources, we recommend that you run
> scale tests on a secondary "staging" environment or a dedicated
> Kubernetes playground cluster.
>
> Run it against a production environment at your own risk.

### Create workspaces

The following command will provision a number of Coder workspaces using the
specified template and extra parameters:

```shell
coder exp scaletest create-workspaces \
        --retry 5 \
        --count "${SCALETEST_PARAM_NUM_WORKSPACES}" \
        --template "${SCALETEST_PARAM_TEMPLATE}" \
        --concurrency "${SCALETEST_PARAM_CREATE_CONCURRENCY}" \
        --timeout 5h \
        --job-timeout 5h \
        --no-cleanup \
        --output json:"${SCALETEST_RESULTS_DIR}/create-workspaces.json"
```

The command does the following:

1. Create `${SCALETEST_PARAM_NUM_WORKSPACES}` workspaces concurrently
   (concurrency level: `${SCALETEST_PARAM_CREATE_CONCURRENCY}`) using the
   template `${SCALETEST_PARAM_TEMPLATE}`.
1. Leave workspaces running to use in next steps (`--no-cleanup` option).
1. Store provisioning results in JSON format.
1. If you don't want the creation process to be interrupted by any errors, use
   the `--retry 5` flag.

For more built-in `scaletest` options, use the `--help` flag:

```shell
coder exp scaletest create-workspaces --help
```

### Traffic Generation

Given an existing set of workspaces created previously with `create-workspaces`,
the following command will generate traffic similar to that of Coder's Web
Terminal against those workspaces.

```shell
# Produce load at about 1000MB/s (25MB/40ms).
coder exp scaletest workspace-traffic \
    --template "${SCALETEST_PARAM_GREEDY_AGENT_TEMPLATE}" \
    --bytes-per-tick $((1024 * 1024 * 25)) \
    --tick-interval 40ms \
    --timeout "$((delay))s" \
    --job-timeout "$((delay))s" \
    --scaletest-prometheus-address 0.0.0.0:21113 \
    --target-workspaces "0:100" \
    --trace=false \
  --output json:"${SCALETEST_RESULTS_DIR}/traffic-${type}-greedy-agent.json"
```

Traffic generation can be parametrized:

1. Send `bytes-per-tick` every `tick-interval`.
1. Enable tracing for performance debugging.
1. Target a range of workspaces with `--target-workspaces 0:100`.
1. For dashboard traffic: Target a range of users with `--target-users 0:100`.
1. Store provisioning results in JSON format.
1. Expose a dedicated Prometheus address (`--scaletest-prometheus-address`) for
   scaletest-specific metrics.

The `workspace-traffic` supports also other modes - SSH traffic, workspace app:

1. For SSH traffic: Use `--ssh` flag to generate SSH traffic instead of Web
   Terminal.
1. For workspace app traffic: Use `--app [wsdi|wsec|wsra]` flag to select app
   behavior.

   - `wsdi`: WebSocket discard
   - `wsec`: WebSocket echo
   - `wsra`: WebSocket read

### Cleanup

The scaletest utility will attempt to clean up all workspaces it creates. If you
wish to clean up all workspaces, you can run the following command:

```shell
coder exp scaletest cleanup \
    --cleanup-job-timeout 2h \
    --cleanup-timeout 15min
```

This will delete all workspaces and users with the prefix `scaletest-`.

## Scale testing template

Consider using a dedicated
[scaletest-runner](https://github.com/coder/coder/tree/main/scaletest/templates/scaletest-runner)
template alongside the CLI utility for testing large-scale Kubernetes clusters.

The template deploys a main workspace with scripts used to orchestrate Coder,
creating workspaces, generating workspace traffic, or load-testing workspace
apps.

### Parameters

The _scaletest-runner_ offers the following configuration options:

- Workspace size selection: minimal/small/medium/large (_default_: minimal,
  which contains just enough resources for a Coder agent to run without
  additional workloads)
- Number of workspaces
- Wait duration between scenarios or staggered approach

The template exposes parameters to control the traffic dimensions for SSH
connections, workspace apps, and dashboard tests:

- Traffic duration of the load test scenario
- Traffic percentage of targeted workspaces
- Bytes per tick and tick interval
- _For workspace apps_: modes (echo, read random data, or write and discard)

Scale testing concurrency can be controlled with the following parameters:

- Enable parallel scenarios - interleave different traffic patterns (SSH,
  workspace apps, dashboard traffic, etc.)
- Workspace creation concurrency level (_default_: 10)
- Job concurrency level - generate workspace traffic using multiple jobs
  (_default_: 0)
- Cleanup concurrency level

### Kubernetes cluster

It is recommended to learn how to operate the _scaletest-runner_ before running
it against the staging cluster (or production at your own risk). Coder provides
different
[workspace configurations](https://github.com/coder/coder/tree/main/scaletest/templates)
that operators can deploy depending on the traffic projections.

There are a few cluster options available:

| Workspace size | vCPU | Memory | Persisted storage | Details                                               |
|----------------|------|--------|-------------------|-------------------------------------------------------|
| minimal        | 1    | 2 Gi   | None              |                                                       |
| small          | 1    | 1 Gi   | None              |                                                       |
| medium         | 2    | 2 Gi   | None              | Medium-sized cluster offers the greedy agent variant. |
| large          | 4    | 4 Gi   | None              |                                                       |

Note: Review the selected cluster template and edit the node affinity to match
your setup.

#### Greedy agent

The greedy agent variant is a template modification that makes the Coder agent
transmit large metadata (size: 4K) while reporting stats. The transmission of
large chunks puts extra overhead on coderd instances and agents when handling
and storing the data.

Use this template variant to verify limits of the cluster performance.

### Observability

During scale tests, operators can monitor progress using a Grafana dashboard.
Coder offers a comprehensive overview
[dashboard](https://github.com/coder/coder/blob/main/scaletest/scaletest_dashboard.json)
that can seamlessly integrate into the internal Grafana deployment.

This dashboard provides insights into various aspects, including:

- Utilization of resources within the Coder control plane (CPU, memory, pods)
- Database performance metrics (CPU, memory, I/O, connections, queries)
- Coderd API performance (requests, latency, error rate)
- Resource consumption within Coder workspaces (CPU, memory, network usage)
- Internal metrics related to provisioner jobs

Note: Database metrics are disabled by default and can be enabled by setting the
environment variable `CODER_PROMETHEUS_COLLECT_DB_METRICS` to `true`.

It is highly recommended to deploy a solution for centralized log collection and
aggregation. The presence of error logs may indicate an underscaled deployment
of Coder, necessitating action from operators.

## Autoscaling

We generally do not recommend using an autoscaler that modifies the number of
coderd replicas. In particular, scale down events can cause interruptions for a
large number of users.

Coderd is different from a simple request-response HTTP service in that it
services long-lived connections whenever it proxies HTTP applications like IDEs
or terminals that rely on websockets, or when it relays tunneled connections to
workspaces. Loss of a coderd replica will drop these long-lived connections and
interrupt users. For example, if you have 4 coderd replicas behind a load
balancer, and an autoscaler decides to reduce it to 3, roughly 25% of the
connections will drop. An even larger proportion of users could be affected if
they use applications that use more than one websocket.

The severity of the interruption varies by application. Coder's web terminal,
for example, will reconnect to the same session and continue. So, this should
not be interpreted as saying coderd replicas should never be taken down for any
reason.

We recommend you plan to run enough coderd replicas to comfortably meet your
weekly high-water-mark load, and monitor coderd peak CPU & memory utilization
over the long term, reevaluating periodically. When scaling down (or performing
upgrades), schedule these outside normal working hours to minimize user
interruptions.

### A note for Kubernetes users

When running on Kubernetes on cloud infrastructure (i.e. not bare metal), many
operators choose to employ a _cluster_ autoscaler that adds and removes
Kubernetes _nodes_ according to load. Coder can coexist with such cluster
autoscalers, but we recommend you take steps to prevent the autoscaler from
evicting coderd pods, as an eviction will cause the same interruptions as
described above. For example, if you are using the
[Kubernetes cluster autoscaler](https://kubernetes.io/docs/reference/labels-annotations-taints/#cluster-autoscaler-kubernetes-io-safe-to-evict),
you may wish to set `cluster-autoscaler.kubernetes.io/safe-to-evict: "false"` as
an annotation on the coderd deployment.

## Troubleshooting

If a load test fails or if you are experiencing performance issues during
day-to-day use, you can leverage Coder's
[Prometheus metrics](../integrations/prometheus.md) to identify bottlenecks
during scale tests. Additionally, you can use your existing cloud monitoring
stack to measure load, view server logs, etc.

---

# Scaling best practices

Source: https://coder.com/docs/tutorials/best-practices/scale-coder

# Scale Coder

This best practice guide helps you prepare a Coder deployment that you can
scale up to a high-scale deployment as use grows, and keep it operating smoothly with a
high number of active users and workspaces.

## Observability

Observability is one of the most important aspects to a scalable Coder deployment.
When you have visibility into performance and usage metrics, you can make informed
decisions about what changes you should make.

[Monitor your Coder deployment](../../admin/monitoring/index.md) with log output
and metrics to identify potential bottlenecks before they negatively affect the
end-user experience and measure the effects of modifications you make to your
deployment.

- Log output
  - Capture log output from from Coder Server instances and external provisioner daemons
  and store them in a searchable log store like Loki, CloudWatch logs, or other tools.
  - Retain logs for a minimum of thirty days, ideally ninety days.
  This allows you investigate when anomalous behaviors began.

- Metrics
  - Capture infrastructure metrics like CPU, memory, open files, and network I/O for all
  Coder Server, external provisioner daemon, workspace proxy, and PostgreSQL instances.
  - Capture Coder Server and External Provisioner daemons metrics
  [via Prometheus](#how-to-capture-coder-server-metrics-with-prometheus).

Retain metric time series for at least six months. This allows you to see
performance trends relative to user growth.

For a more comprehensive overview, integrate metrics with an observability
dashboard like [Grafana](../../admin/monitoring/index.md).

### Observability key metrics

Configure alerting based on these metrics to ensure you surface problems before
they affect the end-user experience.

- CPU and Memory Utilization
  - Monitor the utilization as a fraction of the available resources on the instance.

     Utilization will vary with use throughout the course of a day, week, and longer timelines.
     Monitor trends and pay special attention to the daily and weekly peak utilization.
     Use long-term trends to plan infrastructure upgrades.

- Tail latency of Coder Server API requests
  - High tail latency can indicate Coder Server or the PostgreSQL database is underprovisioned
  for the load.
  - Use the `coderd_api_request_latencies_seconds` metric.

- Tail latency of database queries
  - High tail latency can indicate the PostgreSQL database is low in resources.
  - Use the `coderd_db_query_latencies_seconds` metric.

### How to capture Coder server metrics with Prometheus

Edit your Helm `values.yaml` to capture metrics from Coder Server and external provisioner daemons with
[Prometheus](../../admin/integrations/prometheus.md):

1. Enable Prometheus metrics:

   ```yaml
   CODER_PROMETHEUS_ENABLE=true
   ```

1. Enable database metrics:

   ```yaml
   CODER_PROMETHEUS_COLLECT_DB_METRICS=true
   ```

1. For a high scale deployment, configure agent stats to avoid large cardinality or disable them:

   - Configure agent stats:

     ```yaml
     CODER_PROMETHEUS_AGGREGATE_AGENT_STATS_BY=agent_name
     ```

   - Disable agent stats:

     ```yaml
     CODER_PROMETHEUS_COLLECT_AGENT_STATS=false
     ```

## Coder Server

### Locality

If increased availability of the Coder API is a concern, deploy at least three
instances of Coder Server. Spread the instances across nodes with anti-affinity rules in
Kubernetes or in different availability zones of the same geographic region.

Do not deploy in different geographic regions.

Coder Servers need to be able to communicate with one another directly with low
latency, under 10ms. Note that this is for the availability of the Coder API.
Workspaces are not fault tolerant unless they are explicitly built that way at
the template level.

Deploy Coder Server instances as geographically close to PostgreSQL as possible.
Low-latency communication (under 10ms) with Postgres is essential for Coder
Server's performance.

### Scaling

Coder Server can be scaled both vertically for bigger instances and horizontally
for more instances.

Aim to keep the number of Coder Server instances relatively small, preferably
under ten instances, and opt for vertical scale over horizontal scale after
meeting availability requirements.

Coder's
[validated architectures](../../admin/infrastructure/validated-architectures/index.md)
give specific sizing recommendations for various user scales. These are a useful
starting point, but very few deployments will remain stable at a predetermined
user level over the long term. We recommend monitoring and adjusting resources as needed.

We don't recommend that you autoscale the Coder Servers. Instead, scale the
deployment for peak weekly usage.

Although Coder Server persists no internal state, it operates as a proxy for end
users to their workspaces in two capacities:

1. As an HTTP proxy when they access workspace applications in their browser via
   the Coder Dashboard.

1. As a DERP proxy when establishing tunneled connections with CLI tools like
   `coder ssh`, `coder port-forward`, and others, and with desktop IDEs.

Stopping a Coder Server instance will (momentarily) disconnect any users
currently connecting through that instance. Adding a new instance is not
disruptive, but you should remove instances and perform upgrades during a
maintenance window to minimize disruption.

## Provisioner daemons

### Locality

We recommend that you run one or more
[provisioner daemon deployments external to Coder Server](../../admin/provisioners/index.md)
and disable provisioner daemons within your Coder Server.
This allows you to scale them independently of the Coder Server:

```yaml
CODER_PROVISIONER_DAEMONS=0
```

We recommend deploying provisioner daemons within the same cluster as the
workspaces they will provision or are hosted in.

- This gives them a low-latency connection to the APIs they will use to
  provision workspaces and can speed builds.

- It allows provisioner daemons to use in-cluster mechanisms (for example
  Kubernetes service account tokens, AWS IAM Roles, and others) to authenticate with
  the infrastructure APIs.

- If you deploy workspaces in multiple clusters, run multiple provisioner daemon
  deployments and use template tags to select the correct set of provisioner
  daemons.

- Provisioner daemons need to be able to connect to Coder Server, but this does not need
  to be a low-latency connection.

Provisioner daemons make no direct connections to the PostgreSQL database, so
there's no need for locality to the Postgres database.

### Scaling

Each provisioner daemon instance can handle a single workspace build job at a
time. Therefore, the maximum number of simultaneous builds your Coder deployment
can handle is equal to the number of provisioner daemon instances within a tagged
deployment.

If users experience unacceptably long queues for workspace builds to start,
consider increasing the number of provisioner daemon instances in the affected
cluster.

You might need to automatically scale the number of provisioner daemon instances
throughout the day to meet demand.

If you stop instances with `SIGHUP`, they will complete their current build job
and exit. `SIGINT` will cancel the current job, which will result in a failed build.
Ensure your autoscaler waits long enough for your build jobs to complete before
it kills the provisioner daemon process.

If you deploy in Kubernetes, we recommend a single provisioner daemon per pod.
On a virtual machine (VM), you can deploy multiple provisioner daemons, ensuring
each has a unique `CODER_CACHE_DIRECTORY` value.

Coder's
[validated architectures](../../admin/infrastructure/validated-architectures/index.md)
give specific sizing recommendations for various user scales. Since the
complexity of builds varies significantly depending on the workspace template,
consider this a starting point. Monitor queue times and build times and adjust
the number and size of your provisioner daemon instances.

## PostgreSQL

PostgreSQL is the primary persistence layer for all of Coder's deployment data.
We also use `LISTEN` and `NOTIFY` to coordinate between different instances of
Coder Server.

### Locality

Coder Server instances must have low-latency connections (under 10ms) to
PostgreSQL. If you use multiple PostgreSQL replicas in a clustered config, these
must also be low-latency with respect to one another.

### Scaling

Prefer scaling PostgreSQL vertically rather than horizontally for best
performance. Coder's
[validated architectures](../../admin/infrastructure/validated-architectures/index.md)
give specific sizing recommendations for various user scales.

### Connection pool tuning

Coder Server maintains a pool of connections to PostgreSQL. You can tune the
pool size with the following settings:

> [!NOTE]
> When adjusting these settings, please ensure that your PostgreSQL Server has `max_connections`
> set appropriately to accommodate all Coder Server replicas multiplied by the
> maximum number of open connections. We recommend configuring an additional 20%
> of connections to account for churn and other clients.
>
> Also note that increasing `max_connections` will result in potentially higher
> CPU and RAM usage, so you'll need to monitor accordingly.

- `--postgres-conn-max-open` (env: `CODER_PG_CONN_MAX_OPEN`): Maximum number of open
  connections. Default: 10.
- `--postgres-conn-max-idle` (env: `CODER_PG_CONN_MAX_IDLE`): Maximum number of idle
  connections kept in the pool. Default: "auto", which uses max open / 3.

When a connection is returned to the pool and the idle pool is already full, the
connection is closed immediately. This can cause connection establishment
overhead (churn) when load fluctuates. Monitor these metrics to understand your
connection pool behavior:

- **Capacity**: `go_sql_max_open_connections - go_sql_in_use_connections` shows
  how many connections are available for new requests. If this is 0, Coder
  Server performance will start to degrade. This just provides a point-in-time view
  of the connections, however.

  For a more systematic view, consider running
  `sum by (pod) (increase(go_sql_wait_duration_seconds_total[1m]))` to see how long
  each Coder replica spent waiting on the connection pool (i.e. no free connections);
  `sum by (pod) (increase(go_sql_wait_count_total[$__interval]))` shows how many
  connections were waited for.

  If either of these values seem unacceptably high, try tuning the above settings.
- **Churn**: `sum(rate(go_sql_max_idle_closed_total[$__rate_interval]))` shows
  how many connections are being closed because the idle pool is full.

If you see high churn, consider increasing `--pg-conn-max-idle` to keep more
connections ready for reuse. If you see capacity consistently near zero,
consider increasing `--pg-conn-max-open`.

## Workspace proxies

Workspace proxies proxy HTTP traffic from end users to workspaces for Coder apps
defined in the templates, and HTTP ports opened by the workspace. By default
they also include a DERP Proxy.

### Locality

We recommend each geographic cluster of workspaces have an associated deployment
of workspace proxies. This ensures that users always have a near-optimal proxy
path.

### Scaling

Workspace proxy load is determined by the amount of traffic they proxy.

Monitor CPU, memory, and network I/O utilization to decide when to resize
the number of proxy instances.

Scale for peak demand and scale down or upgrade during a maintenance window.

We do not recommend autoscaling the workspace proxies because many applications
use long-lived connections such as websockets, which would be disrupted by
stopping the proxy.

## Workspaces

Workspaces represent the vast majority of resources in most Coder deployments.
Because they are defined by templates, there is no one-size-fits-all advice for
scaling workspaces.

### Hard and soft cluster limits

All Infrastructure as a Service (IaaS) clusters have limits to what can be
simultaneously provisioned. These could be hard limits, based on the physical
size of the cluster, especially in the case of a private cloud, or soft limits,
based on configured limits in your public cloud account.

It is important to be aware of these limits and monitor Coder workspace resource
utilization against the limits, so that a new influx of users don't encounter
failed builds. Monitoring these is outside the scope of Coder, but we recommend
that you set up dashboards and alerts for each kind of limited resource.

As you approach soft limits, you can request limit increases to keep growing.

As you approach hard limits, consider deploying to additional cluster(s).

### Workspaces per node

Many development workloads are "spiky" in their CPU and memory requirements, for
example, they peak during build/test and then lower while editing code.
This leads to an opportunity to efficiently use compute resources by packing multiple
workspaces onto a single node. This can lead to better experience (more CPU and
memory available during brief bursts) and lower cost.

There are a number of things you should consider before you decide how many
workspaces you should allow per node:

- "Noisy neighbor" issues: Users share the node's CPU and memory resources and might
be susceptible to a user or process consuming shared resources.

- If the shared nodes are a provisioned resource, for example, Kubernetes nodes
  running on VMs in a public cloud, then it can sometimes be a challenge to
  effectively autoscale down.

  - For example, if half the workspaces are stopped overnight, and there are ten
    workspaces per node, it's unlikely that all ten workspaces on the node are
    among the stopped ones.

  - You can mitigate this by lowering the number of workspaces per node, or
    using autostop policies to stop more workspaces during off-peak hours.

- If you do overprovision workspaces onto nodes, keep them in a separate node
  pool and schedule Coder control plane (Coder Server, PostgreSQL, workspace
  proxies) components on a different node pool to avoid resource spikes
  affecting them.

Coder customers have had success with both:

- One workspace per AWS VM
- Lots of workspaces on Kubernetes nodes for efficiency

### Cost control

- Use quotas to discourage users from creating many workspaces they don't need
  simultaneously.

- Label workspace cloud resources by user, team, organization, or your own
  labelling conventions to track usage at different granularities.

- Use autostop requirements to bring off-peak utilization down.

## Networking

Set up your network so that most users can get direct, peer-to-peer connections
to their workspaces. This drastically reduces the load on Coder Server and
workspace proxy instances.

## Next steps

- [Scale Tests and Utilities](../../admin/infrastructure/scale-utility.md)
- [Scale Testing](../../admin/infrastructure/scale-testing.md)

---

# Users

Source: https://coder.com/docs/admin/users

# Users

By default, Coder is accessible via password authentication. For production
deployments, we recommend using an SSO authentication provider with multi-factor
authentication (MFA). It is your responsibility to ensure the auth provider
enforces MFA correctly.

## Configuring SSO

- [OpenID Connect](./oidc-auth/index.md) (e.g. Okta, KeyCloak, PingFederate, Azure AD)
- [GitHub](./github-auth.md) (or GitHub Enterprise)

## Groups

Multiple users can be organized into logical groups to control which templates
they can use. While groups can be manually created in Coder, we recommend
syncing them from your identity provider.

- [Learn more about Groups](./groups-roles.md)
- [Group & Role Sync](./idp-sync.md)

## Roles

Roles determine which actions users can take within the platform. Typically,
most developers in your organization have the `Member` role, allowing them to
create workspaces. Other roles have administrative capabilities such as
auditing, managing users, and managing templates.

- [Learn more about Roles](./groups-roles.md)
- [Group & Role Sync](./idp-sync.md)

## User status

Coder user accounts can have different status types: active, dormant, and
suspended.

### Active user

An _active_ user account in Coder is the default and desired state for all
users. When a user's account is marked as _active_, they have complete access to
the Coder platform and can utilize all of its features and functionalities
without any limitations. Active users can access workspaces, templates, and
interact with Coder using CLI.

### Dormant user

A user account is set to _dormant_ status when they have not yet logged in, or
have not logged into the Coder platform for the past 90 days. Once the user logs
in to the platform, the account status will switch to _active_.

Dormant accounts do not count towards the total number of licensed seats in a
Coder subscription, allowing organizations to optimize their license usage.

### Suspended user

When a user's account is marked as _suspended_ in Coder, it means that the
account has been temporarily deactivated, and the user is unable to access the
platform.

Only user administrators or owners have the necessary permissions to manage
suspended accounts and decide whether to lift the suspension and allow the user
back into the Coder environment. This level of control ensures that
administrators can enforce security measures and handle any compliance-related
issues promptly.

Similar to dormant users, suspended users do not count towards the total number
of licensed seats.

## Create a user

To create a user with the web UI:

1. Log in as a user admin.
2. Go to **Users** > **New user**.
3. In the window that opens, provide the **username**, **email**, and
   **password** for the user (they can opt to change their password after their
   initial login).
4. Click **Submit** to create the user.

The new user will appear in the **Users** list. Use the toggle to change their
**Roles** if desired.

To create a user via the Coder CLI, run:

```shell
coder users create
```

When prompted, provide the **username** and **email** for the new user.

You'll receive a response that includes the following; share the instructions
with the user so that they can log into Coder:

```console
Download the Coder command line for your operating system:
https://github.com/coder/coder/releases/latest

Run  coder login https://<accessURL>.coder.app  to authenticate.

Your email is:  email@exampleCo.com
Your password is:  <redacted>

Create a workspace   coder create !
```

## Suspend a user

User admins can suspend a user, removing the user's access to Coder.

To suspend a user via the web UI:

1. Go to **Users**.
2. Find the user you want to suspend, click the vertical ellipsis to the right,
   and click **Suspend**.
3. In the confirmation dialog, click **Suspend**.

To suspend a user via the CLI, run:

```shell
coder users suspend <username|user_id>
```

Confirm the user suspension by typing **yes** and pressing **enter**.

## Activate a suspended user

User admins can activate a suspended user, restoring their access to Coder.

To activate a user via the web UI:

1. Go to **Users**.
2. Find the user you want to activate, click the vertical ellipsis to the right,
   and click **Activate**.
3. In the confirmation dialog, click **Activate**.

To activate a user via the CLI, run:

```shell
coder users activate <username|user_id>
```

Confirm the user activation by typing **yes** and pressing **enter**.

## Reset a password

As of 2.17.0, users can reset their password independently on the login screen
by clicking "Forgot Password." This feature requires
[email notifications](../monitoring/notifications/index.md#smtp-email) to be
configured on the deployment.

To reset a user's password as an administrator via the web UI:

1. Go to **Users**.
2. Find the user whose password you want to reset, click the vertical ellipsis
   to the right, and select **Reset password**.
3. Coder displays a temporary password that you can send to the user; copy the
   password and click **Reset password**.

Coder will prompt the user to change their temporary password immediately after
logging in.

You can also reset a password via the CLI:

```shell
# run `coder reset-password <username> --help` for usage instructions
coder reset-password <username>
```

> [!NOTE]
> Resetting a user's password, e.g., the initial `owner` role-based user, only
> works when run on the host running the Coder control plane.

### Resetting a password on Kubernetes

```shell
kubectl exec -it deployment/coder -n coder -- /bin/bash

coder reset-password <username>
```

## User filtering

In the Coder UI, you can filter your users using pre-defined filters or by
utilizing the Coder's filter query. The examples provided below demonstrate how
to use the Coder's filter query:

- To find active users, use the filter `status:active`.
- To find admin users, use the filter `role:admin`.
- To find users who have not been active since July 2023:
  `status:active last_seen_before:"2023-07-01T00:00:00Z"`
- To find users who were created between January 1 and January 18, 2023:
  `created_before:"2023-01-18T00:00:00Z" created_after:"2023-01-01T23:59:59Z"`
- To find users who login using Github:
  `login_type:github`
- To find service accounts: `service_account:true`.

The following filters are supported:

- `status` - Indicates the status of the user. It can be either `active`,
  `dormant` or `suspended`.
- `role` - Represents the role of the user. You can refer to the
  [TemplateRole documentation](https://pkg.go.dev/github.com/coder/coder/v2/codersdk#TemplateRole)
  for a list of supported user roles.
- `last_seen_before` and `last_seen_after` - The last time a user has used the
  platform (e.g. logging in, any API requests, connecting to workspaces). Uses
  the RFC3339Nano format.
- `created_before` and `created_after` - The time a user was created. Uses the
  RFC3339Nano format.
- `login_type` - Represents the login type of the user. Refer to the [LoginType documentation](https://pkg.go.dev/github.com/coder/coder/v2/codersdk#LoginType) for a list of supported values
- `service_account` - Can be either `true` to only include service accounts or
  `false` to filter them out. If omitted, both service and regular accounts and
  are returned.

## Edit a user's profile

To edit a user's display name or username with the web UI:

1. Log in as a user admin.
2. Go to **Users**
3. Find the user whose details you would like to edit
4. Select **Edit** from the actions menu
5. Make any desired changes
6. Click **Save**

## Retrieve your list of Coder users

<div class="tabs">

You can use the Coder CLI or API to retrieve your list of users.

### CLI

Use `users list` to export the list of users to a CSV file:

```shell
coder users list > users.csv
```

Visit the [users list](../../reference/cli/users_list.md) documentation for more options.

### API

Use [get users](../../reference/api/users.md#get-users):

```shell
curl -X GET http://coder-server:8080/api/v2/users \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

To export the results to a CSV file, you can use [`jq`](https://jqlang.org/) to process the JSON response:

```shell
curl -X GET http://coder-server:8080/api/v2/users \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY' | \
  jq -r '.users | (map(keys) | add | unique) as $cols | $cols, (.[] | [.[$cols[]]] | @csv)' > users.csv
```

Visit the [get users](../../reference/api/users.md#get-users) documentation for more options.

</div>

---

# OIDC Authentication

Source: https://coder.com/docs/admin/users/oidc-auth

# OpenID Connect

The following steps through how to integrate any OpenID Connect provider (Okta,
Active Directory, etc.) to Coder.

## Step 1: Set Redirect URI with your OIDC provider

Your OIDC provider will ask you for the following parameter:

- **Redirect URI**: Set to `https://coder.domain.com/api/v2/users/oidc/callback`

## Step 2: Configure Coder with the OpenID Connect credentials

Set the following environment variables on your Coder deployment and restart Coder:

```env
CODER_OIDC_ISSUER_URL="https://issuer.corp.com"
CODER_OIDC_EMAIL_DOMAIN="your-domain-1,your-domain-2"
CODER_OIDC_CLIENT_ID="533...des"
CODER_OIDC_CLIENT_SECRET="G0CSP...7qSM"
```

## OIDC Claims

When a user logs in for the first time via OIDC, Coder will merge both the
claims from the ID token and the claims obtained from hitting the upstream
provider's `userinfo` endpoint, and use the resulting data as a basis for
creating a new user or looking up an existing user.

To troubleshoot claims, set `CODER_LOG_FILTER=".*got oidc claims.*"` and follow the logs while
signing in via OIDC as a new user. Coder will log the claim fields returned by
the upstream identity provider in a message containing the string
`got oidc claims`, as well as the user info returned.

> [!NOTE]
> If you need to ensure that Coder only uses information from the ID
> token and does not hit the UserInfo endpoint, you can set the configuration
> option `CODER_OIDC_IGNORE_USERINFO=true`.

### Email Addresses

By default, Coder will look for the OIDC claim named `email` and use that value
for the newly created user's email address.

If your upstream identity provider users a different claim, you can set
`CODER_OIDC_EMAIL_FIELD` to the desired claim.

> [!NOTE]
> If this field is not present, Coder will attempt to use the claim
> field configured for `username` as an email address. If this field is not a
> valid email address, OIDC logins will fail.

### Email Address Verification

Coder requires all OIDC email addresses to be verified by default. If the
`email_verified` claim is present in the token response from the identity
provider, Coder will validate that its value is `true`. If needed, you can
disable this behavior with the following setting:

```env
CODER_OIDC_IGNORE_EMAIL_VERIFIED=true
```

> [!NOTE]
> This will cause Coder to implicitly treat all OIDC emails as
> "verified", regardless of what the upstream identity provider says.

### Usernames

When a new user logs in via OIDC, Coder will by default use the value of the
claim field named `preferred_username` as the the username.

If your upstream identity provider uses a different claim, you can set
`CODER_OIDC_USERNAME_FIELD` to the desired claim.

> [!NOTE]
> If this claim is empty, the email address will be stripped of the
> domain, and become the username (e.g. `example@coder.com` becomes `example`).
> To avoid conflicts, Coder may also append a random word to the resulting
> username.

## OIDC Login Customization

If you'd like to change the OpenID Connect button text and/or icon, you can
configure them like so:

```env
CODER_OIDC_SIGN_IN_TEXT="Sign in with Gitea"
CODER_OIDC_ICON_URL=https://gitea.io/images/gitea.png
```

To change the icon and text above the OpenID Connect button, see application
name and logo url in [appearance](../../setup/appearance.md) settings.

## Configure Refresh Tokens

By default, OIDC access tokens typically expire after a short period.
This is typically after one hour, but varies by provider.

Without refresh tokens, users will be automatically logged out when their access token expires.

Follow [Configure OIDC Refresh Tokens](./refresh-tokens.md) for provider-specific steps.

The general steps to configure persistent user sessions are:

1. Configure your Coder OIDC settings:

   For most providers, add the `offline_access` scope:

   ```env
   CODER_OIDC_SCOPES=openid,profile,email,offline_access
   ```

   For Google, add auth URL parameters (`CODER_OIDC_AUTH_URL_PARAMS`) too:

   ```env
   CODER_OIDC_SCOPES=openid,profile,email
   CODER_OIDC_AUTH_URL_PARAMS='{"access_type": "offline", "prompt": "consent"}'
   ```

1. Configure your identity provider to issue refresh tokens.

1. After configuration, have users log out and back in once to obtain refresh tokens

> [!IMPORTANT]
> Misconfigured refresh tokens can lead to frequent user authentication prompts.

## Disable Built-in Authentication

To remove email and password login, set the following environment variable on
your Coder deployment:

```env
CODER_DISABLE_PASSWORD_AUTH=true
```

## SCIM

> [!IMPORTANT]
> SCIM is a Premium feature
> ([learn more](https://coder.com/pricing#compare-plans)).
>
> Coder's SCIM 2.0 implementation is not a fully certified or guaranteed
> implementation of the [SCIM 2.0 specification](https://datatracker.ietf.org/doc/html/rfc7644).
> It is intended to cover common user provisioning and deprovisioning flows
> with the major identity providers (Okta, Microsoft Entra ID, etc.). Specific
> attributes, endpoints, or behaviors required by your IdP may not be
> supported, and compatibility may change between releases. If you depend on
> a specific SCIM behavior, [contact us](https://coder.com/contact) before
> rolling it out broadly. See
> [coder/coder#15830](https://github.com/coder/coder/issues/15830) for
> tracked gaps and ongoing work.

Coder supports user provisioning and deprovisioning via SCIM 2.0 with header
authentication. Upon deactivation, users are
[suspended](../index.md#suspend-a-user) and are not deleted.
[Configure](../../setup/index.md) your SCIM application with an auth key and supply
it the Coder server.

```env
CODER_SCIM_AUTH_HEADER="your-api-key"
```

## TLS

If your OpenID Connect provider requires client TLS certificates for
authentication, you can configure them like so:

```env
CODER_TLS_CLIENT_CERT_FILE=/path/to/cert.pem
CODER_TLS_CLIENT_KEY_FILE=/path/to/key.pem
```

## Next steps

- [Group Sync](../idp-sync.md)
- [Groups & Roles](../groups-roles.md)
- [Configure OIDC Refresh Tokens](./refresh-tokens.md)

---

# Google

Source: https://coder.com/docs/admin/users/oidc-auth/google

# Google authentication (OIDC)

This guide shows how to configure Coder to authenticate users with Google using OpenID Connect (OIDC).

## Prerequisites

- A Google Cloud project with the OAuth consent screen configured
- Permission to create OAuth 2.0 Client IDs in Google Cloud

## Step 1: Create an OAuth client in Google Cloud

1. Open Google Cloud Console → APIs & Services → Credentials → Create Credentials → OAuth client ID.
2. Application type: Web application.
3. Authorized redirect URIs: add your Coder callback URL:
   - `https://coder.example.com/api/v2/users/oidc/callback`
4. Save and note the Client ID and Client secret.

## Step 2: Configure Coder OIDC for Google

Set the following environment variables on your Coder deployment and restart Coder:

```env
CODER_OIDC_ISSUER_URL=https://accounts.google.com
CODER_OIDC_CLIENT_ID=<client id>
CODER_OIDC_CLIENT_SECRET=<client secret>
# Restrict to one or more email domains (comma-separated)
CODER_OIDC_EMAIL_DOMAIN="example.com"
# Standard OIDC scopes for Google
CODER_OIDC_SCOPES=openid,profile,email
# Optional: customize the login button
CODER_OIDC_SIGN_IN_TEXT="Sign in with Google"
CODER_OIDC_ICON_URL=/icon/google.svg
```

> [!NOTE]
> The redirect URI must exactly match what you configured in Google Cloud.

## Enable refresh tokens (recommended)

Google uses auth URL parameters to issue refresh tokens. Configure:

```env
# Keep standard scopes
CODER_OIDC_SCOPES=openid,profile,email
# Add Google-specific auth URL params
CODER_OIDC_AUTH_URL_PARAMS='{"access_type": "offline", "prompt": "consent"}'
```

After changing settings, users must log out and back in once to obtain refresh tokens.

Learn more in [Configure OIDC refresh tokens](./refresh-tokens.md).

## Troubleshooting

- "invalid redirect_uri": ensure the redirect URI in Google Cloud matches `https://<your-coder-host>/api/v2/users/oidc/callback`.
- Domain restriction: if users from unexpected domains can log in, verify `CODER_OIDC_EMAIL_DOMAIN`.
- Claims: to inspect claims returned by Google, see guidance in the [OIDC overview](./index.md#oidc-claims).

## See also

- [OIDC overview](./index.md)
- [Configure OIDC refresh tokens](./refresh-tokens.md)

---

# Microsoft

Source: https://coder.com/docs/admin/users/oidc-auth/microsoft

# Microsoft Entra ID authentication (OIDC)

This guide shows how to configure Coder to authenticate users with Microsoft Entra ID using OpenID Connect (OIDC)

## Prerequisites

- A Microsoft Azure Entra ID Tenant
- Permission to create Applications in your Azure environment

## Step 1: Create an OAuth App Registration in Microsoft Azure

1. Open Microsoft Azure Portal (https://portal.azure.com) → Microsoft Entra ID → App Registrations → New Registration
2. Name: Name your application appropriately
3. Supported Account Types: Choose the appropriate radio button according to your needs. Most organizations will want to use the first one labeled "Accounts in this organizational directory only"
4. Click on "Register"
5. On the next screen, select: "Certificates and Secrets"
6. Click on "New Client Secret" and under description, enter an appropriate description. Then set an expiry and hit "Add" once it's created, copy the value and save it somewhere secure for the next step
7. Next, click on the tab labeled "Token Configuration", then click "Add optional claim" and select the "ID" radio button, and finally check "upn" and hit "add" at the bottom
8. Then, click on the button labeled "Add groups claim" and check "Security groups" and click "Save" at the bottom
9. Now, click on the tab labeled "Authentication" and click on "Add a platform", select "Web" and for the redirect URI enter your Coder callback URL, and then hit "Configure" at the bottom:
   - `https://coder.example.com/api/v2/users/oidc/callback`

## Step 2: Configure Coder OIDC for Microsoft Entra ID

Set the following environment variables on your Coder deployment and restart Coder:

```env
CODER_OIDC_ISSUER_URL=https://login.microsoftonline.com/{tenant-id}/v2.0 # Replace {tenant-id} with your Azure tenant ID
CODER_OIDC_CLIENT_ID=<client id, located in "Overview">
CODER_OIDC_CLIENT_SECRET=<client secret, saved from step 6>
# Restrict to one or more email domains (comma-separated)
CODER_OIDC_EMAIL_DOMAIN="example.com"
CODER_OIDC_EMAIL_FIELD="upn" # This is set because EntraID typically uses .onmicrosoft.com domains by default, this should pull the user's username@domain email.
CODER_OIDC_GROUP_FIELD="groups" # This is for group sync / IdP Sync, a premium feature.
# Optional: customize the login button
CODER_OIDC_SIGN_IN_TEXT="Sign in with Microsoft Entra ID"
CODER_OIDC_ICON_URL=/icon/microsoft.svg
```

> [!NOTE]
> The redirect URI must exactly match what you configured in Microsoft Azure Entra ID

## Enable refresh tokens (recommended)

```env
# Keep standard scopes
CODER_OIDC_SCOPES=openid,profile,email,offline_access
```

After changing settings, users must log out and back in once to obtain refresh tokens

Learn more in [Configure OIDC refresh tokens](./refresh-tokens.md).

## Troubleshooting

- "invalid redirect_uri": ensure the redirect URI in Azure Entra ID matches `https://<your-coder-host>/api/v2/users/oidc/callback`
- Domain restriction: if users from unexpected domains can log in, verify `CODER_OIDC_EMAIL_DOMAIN`
- Claims: to inspect claims returned by Microsoft, see guidance in the [OIDC overview](./index.md#oidc-claims)

## See also

- [OIDC overview](./index.md)
- [Configure OIDC refresh tokens](./refresh-tokens.md)

---

# Configure OIDC refresh tokens

Source: https://coder.com/docs/admin/users/oidc-auth/refresh-tokens

# Configure OIDC refresh tokens

OIDC refresh tokens allow your Coder deployment to maintain user sessions beyond the initial access token expiration.
Without properly configured refresh tokens, users will be automatically logged out when their access token expires.
This is typically after one hour, but varies by provider, and can disrupt the user's workflow.

> [!IMPORTANT]
> Misconfigured refresh tokens can lead to frequent user authentication prompts.
>
> After the admin enables refresh tokens, all existing users must log out and back in again to obtain a refresh token.

<div class="tabs">

<!-- markdownlint-disable MD001 -->

### Azure AD

Go to the Azure Portal > **Azure Active Directory** > **App registrations** > Your Coder app and make the following changes:

1. In the **Authentication** tab:

   - **Platform configuration** > Web
   - Ensure **Allow public client flows** is `No` (Coder is confidential)
   - **Implicit grant / hybrid flows** can stay unchecked

1. In the **API permissions** tab:

   - Add the built-in permission `offline_access` under **Microsoft Graph** > **Delegated permissions**
   - Keep `openid`, `profile`, and `email`

1. In the **Certificates & secrets** tab:

   - Verify a Client secret (or certificate) is valid.
     Coder uses it to redeem refresh tokens.

1. In your [Coder configuration](../../../reference/cli/server.md#--oidc-auth-url-params), request the same scopes:

   ```env
   CODER_OIDC_SCOPES=openid,profile,email,offline_access
   ```

1. Restart Coder and have users log out and back again for the changes to take effect.

   Alternatively, you can force a sign-out for all users with the
   [sign-out request process](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc#send-a-sign-out-request).

1. Azure issues rolling refresh tokens with a default absolute expiration of 90 days and inactivity expiration of 24 hours.

   You can adjust these settings under **Authentication methods** > **Token lifetime** (or use Conditional-Access policies in Entra ID).

You don't need to configure the 'Expose an API' section for refresh tokens to work.

Learn more in the [Microsoft Entra documentation](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc#enable-id-tokens).

### Google

To ensure Coder receives a refresh token when users authenticate with Google directly, set the `prompt` to `consent`
in the auth URL parameters (`CODER_OIDC_AUTH_URL_PARAMS`).
Without this, users will be logged out when their access token expires.

In your [Coder configuration](../../../reference/cli/server.md#--oidc-auth-url-params):

```env
CODER_OIDC_SCOPES=openid,profile,email
CODER_OIDC_AUTH_URL_PARAMS='{"access_type": "offline", "prompt": "consent"}'
```

### Keycloak

The `access_type` parameter has two possible values: `online` and `offline`.
By default, the value is set to `offline`.

This means that when a user authenticates using OIDC, the application requests offline access to the user's resources,
including the ability to refresh access tokens without requiring the user to reauthenticate.

Add the `offline_access` scope to enable refresh tokens in your
[Coder configuration](../../../reference/cli/server.md#--oidc-auth-url-params):

```env
CODER_OIDC_SCOPES=openid,profile,email,offline_access
CODER_OIDC_AUTH_URL_PARAMS='{"access_type":"offline"}'
```

### PingFederate

1. In PingFederate go to **Applications** > **OAuth Clients** > Your Coder client.

1. On the **Client** tab:

   - **Grant Types**: Enable `refresh_token`
   - **Allowed Scopes**: Add `offline_access` and keep `openid`, `profile`, and `email`

1. Optionally, in **Token Settings**

   - **Refresh Token Lifetime**: set a value that matches your security policy. Ping's default is 30 days.
   - **Idle Timeout**: ensure it's more than or equal to the lifetime of the access token so that refreshes don't fail prematurely.

1. Save your changes in PingFederate.

1. In your [Coder configuration](../../../reference/cli/server.md#--oidc-scopes), add the `offline_access` scope:

   ```env
   CODER_OIDC_SCOPES=openid,profile,email,offline_access
   ```

1. Restart your Coder deployment to apply these changes.

Users must log out and log in once to store their new refresh tokens.
After that, sessions should last until the Ping Federate refresh token expires.

Learn more in the [PingFederate documentation](https://docs.pingidentity.com/pingfederate/12.2/administrators_reference_guide/pf_configuring_oauth_clients.html).

</div>

## Confirm refresh token configuration

To verify refresh tokens are working correctly:

1. Check that your OIDC configuration includes the required refresh token parameters:

     - `offline_access` scope for most providers
     - `"access_type": "offline"` for Google

1. Verify provider-specific token configuration:

   <div class="tabs">

   ### Azure AD

   Use [jwt.ms](https://jwt.ms) to inspect the `id_token` and ensure the `rt_hash` claim is present.
   This shows that a refresh token was issued.

   ### Google

   If users are still being logged out periodically, check your client configuration in Google Cloud Console.

   ### Keycloak

   Review Keycloak sessions for the presence of refresh tokens.

   ### Ping Federate

   - Verify the client sent `offline_access` in the `grantedScopes` portion of the ID token.
   - Confirm `refresh_token` appears in the `grant_types` list returned by `/pf-admin-api/v1/oauth/clients/{id}`.

   </div>

1. Verify users can stay logged in beyond the identity provider's access token expiration period (typically 1 hour).

1. Monitor Coder logs for `failed to renew OIDC token: token has expired` messages.
   There should not be any.

If all verification steps pass successfully, your refresh token configuration is working properly.

## Troubleshooting OIDC Refresh Tokens

### Users are logged out too frequently

**Symptoms**:

- Users experience session timeouts and must re-authenticate.
- Session timeouts typically occur after the access token expiration period (varies by provider, commonly 1 hour).

**Causes**:

- Missing required refresh token configuration:
  - `offline_access` scope for most providers
  - `"access_type": "offline"` for Google
- Provider not correctly configured to issue refresh tokens.
- User has not logged in since refresh token configuration was added.

**Solution**:

- For most providers, add `offline_access` to your `CODER_OIDC_SCOPES` configuration.
  - `"access_type": "offline"` for Google
- Configure your identity provider according to the provider-specific instructions above.
- Have users log out and log in again to obtain refresh tokens.
  Look for entries containing `failed to renew OIDC token` which might indicate specific provider issues.

### Refresh tokens don't work after configuration change

**Symptoms**:

- Session timeouts continue despite refresh token configuration and users re-authenticating.
- Some users experience frequent logouts.

**Cause**:

- Existing user sessions don't have refresh tokens stored.
- Configuration may be incomplete.

**Solution**:

- Users must log out and log in again to get refresh tokens stored in the database.
- Verify you've correctly configured your provider as described in the configuration steps above.
- Check Coder logs for specific error messages related to token refresh.

Users might get logged out again before the new configuration takes effect completely.

---

# GitHub Authentication

Source: https://coder.com/docs/admin/users/github-auth

# GitHub

By default, new Coder deployments use a Coder-managed GitHub app to authenticate
users.
We provide it for convenience, allowing you to experiment with Coder
without setting up your own GitHub OAuth app.

If you authenticate with it, you grant Coder server read access to your GitHub
user email and other metadata listed during the authentication flow.

This access is necessary for the Coder server to complete the authentication
process.
To the best of our knowledge, Coder, the company, does not gain access
to this data by administering the GitHub app.

## Default Configuration

> [!IMPORTANT]
> Installation of the default GitHub app grants Coder (the company) access to your organization's GitHub data.
>
> For production environments, we strongly recommend that you
> [configure your own GitHub OAuth app](#step-1-configure-the-oauth-application-in-github)
> to ensure that your data is not shared with Coder (the company).

To use the default configuration:

1. [Install the GitHub app](https://github.com/apps/coder/installations/select_target)
   in any GitHub organization that you want to use with Coder.

   The default GitHub app requires [device flow](#device-flow) to authenticate.
   This is enabled by default when using the default GitHub app.
   If you disable device flow using `CODER_OAUTH2_GITHUB_DEVICE_FLOW=false`, it will be ignored.

1. By default, only the admin user can sign up.
   To allow additional users to sign up with GitHub, add:

   ```shell
   CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS=true
   ```

1. (Optional) If you want to limit sign-ups to specific GitHub organizations, set:

   ```shell
   CODER_OAUTH2_GITHUB_ALLOWED_ORGS="your-org"
   ```

## Disable the Default GitHub App

You can disable the default GitHub app by [configuring your own app](#step-1-configure-the-oauth-application-in-github)
or by adding the following environment variable to your [Coder server configuration](../../reference/cli/server.md#options):

```shell
CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE=false
```

> [!NOTE]
> After you disable the default GitHub provider, the **Sign in with GitHub** button
> might still appear on your login page even though the authentication flow is disabled.
>
> To completely hide the GitHub sign-in button, you must disable the default provider
> and ensure you don't have a custom GitHub OAuth app configured.

## Step 1: Configure the OAuth application in GitHub

1. [Register a GitHub OAuth app](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/).

1. GitHub will ask you for the following Coder parameters:

   - **Homepage URL**: Set to your Coder deployment's
     [`CODER_ACCESS_URL`](../../reference/cli/server.md#--access-url) (e.g.
     `https://coder.domain.com`)
   - **User Authorization Callback URL**: Set to `https://coder.domain.com`

     If you want to allow multiple Coder deployments hosted on subdomains, such as
     `coder1.domain.com`, `coder2.domain.com`, to authenticate with the
     same GitHub OAuth app, then you can set **User Authorization Callback URL** to
     the `https://domain.com`

1. Take note of the Client ID and Client Secret generated by GitHub.
   You will use these values in the next step.

1. Coder needs permission to access user email addresses.

   Find the **Account Permissions** settings for your app and select **read-only** for **Email addresses**.

## Step 2: Configure Coder with the OAuth credentials

Go to your Coder host and run the following command to start up the Coder server:

```shell
coder server --oauth2-github-allow-signups=true --oauth2-github-allowed-orgs="your-org" --oauth2-github-client-id="8d1...e05" --oauth2-github-client-secret="57ebc9...02c24c"
```

> [!NOTE]
> For GitHub Enterprise support, specify the `--oauth2-github-enterprise-base-url` flag.

Alternatively, if you are running Coder as a system service, you can achieve the
same result as the command above by adding the following environment variables
to the `/etc/coder.d/coder.env` file:

```shell
CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS=true
CODER_OAUTH2_GITHUB_ALLOWED_ORGS="your-org"
CODER_OAUTH2_GITHUB_CLIENT_ID="8d1...e05"
CODER_OAUTH2_GITHUB_CLIENT_SECRET="57ebc9...02c24c"
```

> [!TIP]
> To allow everyone to sign up using GitHub, set:
>
> ```shell
> CODER_OAUTH2_GITHUB_ALLOW_EVERYONE=true
> ```

Once complete, run `sudo service coder restart` to reboot Coder.

If deploying Coder via Helm, you can set the above environment variables in the
`values.yaml` file as such:

```yaml
coder:
  env:
    - name: CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS
      value: "true"
    - name: CODER_OAUTH2_GITHUB_CLIENT_ID
      value: "533...des"
    - name: CODER_OAUTH2_GITHUB_CLIENT_SECRET
      value: "G0CSP...7qSM"
    # If setting allowed orgs, comment out CODER_OAUTH2_GITHUB_ALLOW_EVERYONE and its value
    - name: CODER_OAUTH2_GITHUB_ALLOWED_ORGS
      value: "your-org"
    # If allowing everyone, comment out CODER_OAUTH2_GITHUB_ALLOWED_ORGS and it's value
    #- name: CODER_OAUTH2_GITHUB_ALLOW_EVERYONE
    #  value: "true"
```

To upgrade Coder, run:

```shell
helm upgrade <release-name> coder-v2/coder -n <namespace> -f values.yaml
```

We recommend requiring and auditing MFA usage for all users in your GitHub organizations.
This can be enforced from the organization settings page in the **Authentication security** sidebar tab.

## Device Flow

Coder supports
[device flow](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#device-flow)
for GitHub OAuth.
This is enabled by default for the default GitHub app and cannot be disabled for that app.

For your own custom GitHub OAuth app, you can enable device flow by setting:

```shell
CODER_OAUTH2_GITHUB_DEVICE_FLOW=true
```

Device flow is optional for custom GitHub OAuth apps.
We generally recommend using the standard OAuth flow instead, as it is more convenient for end users.

> [!NOTE]
> If you're using the default GitHub app, device flow is always enabled regardless of
> the `CODER_OAUTH2_GITHUB_DEVICE_FLOW` setting.

---

# Password Authentication

Source: https://coder.com/docs/admin/users/password-auth

# Password Authentication

Coder has password authentication enabled by default. The account created during
setup is a username/password account.

## Disable password authentication

To disable password authentication, use the
[`CODER_DISABLE_PASSWORD_AUTH`](../../reference/cli/server.md#--disable-password-auth)
flag on the Coder server.

## Restore the `Owner` user

If you remove the admin user account (or forget the password), you can run the
[`coder server create-admin-user`](../../reference/cli/server_create-admin-user.md)command
on your server.

> [!IMPORTANT]
> You must run this command on the same machine running the Coder server.
> If you are running Coder on Kubernetes, this means using
> [kubectl exec](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_exec/)
> to exec into the pod.

## Reset a user's password

An admin must reset passwords on behalf of users. This can be done in the web UI
in the Users page or CLI:
[`coder reset-password`](../../reference/cli/reset-password.md)

---

# Headless Authentication

Source: https://coder.com/docs/admin/users/headless-auth

# Headless Authentication

> [!NOTE]
> Creating service accounts requires a [Premium license](https://coder.com/pricing).

Service accounts are headless user accounts that cannot use the web UI to log in
to Coder. This is useful for creating accounts for automated systems, such as
CI/CD pipelines or for users who only consume Coder via another client/API. Service accounts do not have passwords or associated email addresses.

You must have the User Admin role or above to create service accounts.

## Create a service account

<div class="tabs">

## CLI

Use the `--service-account` flag to create a dedicated service account:

```sh
coder users create \
  --username="coder-bot" \
  --service-account
```

## UI

Navigate to **Deployment** > **Users** > **Create user**, then select
**Service account** as the login type.

![Create a user via the UI](../../images/admin/users/headless-user.png)

</div>

## Authenticate as a service account

To make API or CLI requests on behalf of the headless user, learn how to
[generate API tokens on behalf of a user](./sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-another-user).

---

# Groups & Roles

Source: https://coder.com/docs/admin/users/groups-roles

# Groups and Roles

Groups and roles can be manually assigned in Coder. For production deployments,
these can also be [managed and synced by the identity provider](./idp-sync.md).

## Groups

Groups are logical segmentations of users in Coder and can be used to control
which templates developers can use. For example:

- Users within the `devops` group can access the `AWS-VM` template
- Users within the `data-science` group can access the `Jupyter-Kubernetes`
  template

## Roles

Roles determine which actions users can take within the platform.

|                                                                 | Auditor | User Admin | Template Admin | Owner |
|-----------------------------------------------------------------|---------|------------|----------------|-------|
| Add and remove Users                                            |         | ✅          |                | ✅     |
| Manage groups (premium)                                         |         | ✅          |                | ✅     |
| Change User roles                                               |         |            |                | ✅     |
| Manage **ALL** Templates                                        |         |            | ✅              | ✅     |
| View **ALL** Workspaces                                         |         |            | ✅              | ✅     |
| Update and delete **ALL** Workspaces                            |         |            |                | ✅     |
| Run [external provisioners](../provisioners/index.md)           |         |            | ✅              | ✅     |
| Execute and use **ALL** Workspaces                              |         |            |                | ✅     |
| View all user operation [Audit Logs](../security/audit-logs.md) | ✅       |            |                | ✅     |

A user may have one or more roles. All users have an implicit Member role that
may use personal workspaces.

## Custom Roles

> [!NOTE]
> Custom roles are a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Starting in v2.16.0, Premium Coder deployments can configure custom roles on the
[Organization](./organizations.md) level. You can create and assign custom roles
in the dashboard under **Organizations** -> **My Organization** -> **Roles**.

![Custom roles](../../images/admin/users/roles/custom-roles.PNG)

### Example roles

- The `Banking Compliance Auditor` custom role cannot create workspaces, but can
  read template source code and view audit logs
- The `Organization Lead` role can access user workspaces for troubleshooting
  purposes, but cannot edit templates
- The `Platform Member` role cannot edit or create workspaces as they are
  created via a third-party system

Custom roles can also be applied to
[headless user accounts](./headless-auth.md):

- A `Health Check` role can view deployment status but cannot create workspaces,
  manage templates, or view users
- A `CI` role can update manage templates but cannot create workspaces or view
  users

### Creating custom roles

Clicking "Create custom role" opens a UI to select the desired permissions for a
given persona.

![Creating a custom role](../../images/admin/users/roles/creating-custom-role.PNG)

From there, you can assign the custom role to any user in the organization under
the **Users** settings in the dashboard.

![Assigning a custom role](../../images/admin/users/roles/assigning-custom-role.PNG)

Note that these permissions only apply to the scope of an
[organization](./organizations.md), not across the deployment.

### Security notes

A malicious Template Admin could write a template that executes commands on the
host (or `coder server` container), which potentially escalates their privileges
or shuts down the Coder server. To avoid this, run
[external provisioners](../provisioners/index.md).

In low-trust environments, we do not recommend giving users direct access to
edit templates. Instead, use
[CI/CD pipelines to update templates](../templates/managing-templates/change-management.md)
with proper security scans and code reviews in place.

---

# IdP Sync

Source: https://coder.com/docs/admin/users/idp-sync

<!-- markdownlint-disable MD024 -->
# IdP Sync

> [!NOTE]
> IdP sync is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

IdP (Identity provider) sync allows you to use OpenID Connect (OIDC) to
synchronize Coder groups, roles, and organizations based on claims from your IdP.

## Prerequisites

### Confirm that OIDC provider sends claims

To confirm that your OIDC provider is sending claims, log in with OIDC and visit
the following URL with an `Owner` account:

```text
https://[coder.example.com]/api/v2/debug/[your-username]/debug-link
```

You should see a field in either `id_token_claims`, `user_info_claims` or
both followed by a list of the user's OIDC groups in the response.

This is the [claim](https://openid.net/specs/openid-connect-core-1_0.html#Claims)
sent by the OIDC provider.

Depending on the OIDC provider, this claim might be called something else.
Common names include `groups`, `memberOf`, and `roles`.

See the [troubleshooting section](#troubleshooting-grouproleorganization-sync)
for help troubleshooting common issues.

## Group Sync

If your OpenID Connect provider supports group claims, you can configure Coder
to synchronize groups in your auth provider to groups within Coder. To enable
group sync, ensure that the `groups` claim is being sent by your OpenID
provider. You might need to request an additional
[scope](../../reference/cli/server.md#--oidc-scopes) or additional configuration
on the OpenID provider side.

If group sync is enabled, the user's groups will be controlled by the OIDC
provider. This means manual group additions/removals will be overwritten on the
next user login.

For deployments with multiple [organizations](./organizations.md), configure
group sync for each organization.

<div class="tabs">

### Dashboard

1. Fetch the corresponding group IDs using the following endpoint:

   ```text
   https://[coder.example.com]/api/v2/groups
   ```

1. As an Owner or Organization Admin, go to **Admin settings**, select
   **Organizations**, then **IdP Sync**:

   ![IdP Sync - Group sync settings](../../images/admin/users/organizations/group-sync-empty.png)

1. Enter the **Group sync field** and an optional **Regex filter**, then select
   **Save**.

1. Select **Auto create missing groups** to automatically create groups
   returned by the OIDC provider if they do not exist in Coder.

1. Enter the **IdP group name** and **Coder group**, then **Add IdP group**.

### CLI

1. Confirm you have the [Coder CLI](../../install/index.md) installed and are
   logged in with a user who is an Owner or has an Organization Admin role.

1. To fetch the current group sync settings for an organization, run the
   following:

   ```sh
   coder organizations settings show group-sync \
     --org <org-name> \
     > group-sync.json
   ```

   The default for an organization looks like this:

   ```json
   {
       "field": "",
       "mapping": null,
       "regex_filter": null,
       "auto_create_missing_groups": false
   }
   ```

Below is an example that uses the `groups` claim and maps all groups prefixed by
`coder-` into Coder:

```json
{
    "field": "groups",
    "mapping": null,
    "regex_filter": "^coder-.*$",
    "auto_create_missing_groups": true
}
```

You must specify Coder group IDs instead of group names.
You can find the ID for a corresponding group by visiting
`https://coder.example.com/api/v2/groups`.

Here is another example which maps `coder-admins` from the identity provider to
two groups in Coder and `coder-users` from the identity provider to another
group:

```json
{
    "field": "groups",
    "mapping": {
        "coder-admins": [
            "2ba2a4ff-ddfb-4493-b7cd-1aec2fa4c830",
            "93371154-150f-4b12-b5f0-261bb1326bb4"
        ],
        "coder-users": ["2f4bde93-0179-4815-ba50-b757fb3d43dd"]
    },
    "regex_filter": null,
    "auto_create_missing_groups": false
}
```

To set these group sync settings, use the following command:

```sh
coder organizations settings set group-sync \
  --org <org-name> \
  < group-sync.json
```

Visit the Coder UI to confirm these changes:

![IdP Sync](../../images/admin/users/organizations/group-sync.png)

### Server Flags

> [!NOTE]
> Use server flags only with Coder deployments with a single organization.
> You can use the dashboard to configure group sync instead.

1. Configure the Coder server to read groups from the claim name with the
   [OIDC group field](../../reference/cli/server.md#--oidc-group-field) server
   flag:

   - Environment variable:

     ```sh
     CODER_OIDC_GROUP_FIELD=groups
     ```

   - As a flag:

     ```sh
     --oidc-group-field groups
     ```

1. On login, users will automatically be assigned to groups that have matching
   names in Coder and removed from groups that the user no longer belongs to.

1. For cases when an OIDC provider only returns group IDs or you want to have
   different group names in Coder than in your OIDC provider, you can configure
   mapping between the two with the
   [OIDC group mapping](../../reference/cli/server.md#--oidc-group-mapping) server
   flag:

   - Environment variable:

     ```sh
     CODER_OIDC_GROUP_MAPPING='{"myOIDCGroupID": "myCoderGroupName"}'
     ```

   - As a flag:

     ```sh
     --oidc-group-mapping '{"myOIDCGroupID": "myCoderGroupName"}'
     ```

   Below is an example mapping in the Coder Helm chart:

   ```yaml
   coder:
     env:
       - name: CODER_OIDC_GROUP_MAPPING
         value: >
           {"myOIDCGroupID": "myCoderGroupName"}
   ```

   From this example, users that belong to the `myOIDCGroupID` group in your
   OIDC provider will be added to the `myCoderGroupName` group in Coder.

</div>

### Group allowlist

You can limit which groups from your identity provider can log in to Coder with
[CODER_OIDC_ALLOWED_GROUPS](../../reference/cli/server.md#--oidc-allowed-groups).
Users who are not in a matching group will see the following error:

<Image height="412px" src="../../images/admin/group-allowlist.png" alt="Unauthorized group error" align="center" />

## Role Sync

If your OpenID Connect provider supports roles claims, you can configure Coder
to synchronize roles in your auth provider to roles within Coder.

For deployments with multiple [organizations](./organizations.md), configure
role sync at the organization level.

<div class="tabs">

### Dashboard

1. As an Owner or Organization Admin, go to **Admin settings**, select
   **Organizations**, then **IdP Sync**.

1. Select the **Role sync settings** tab:

   ![IdP Sync - Role sync settings](../../images/admin/users/organizations/role-sync-empty.png)

1. Enter the **Role sync field**, then select **Save**.

1. Enter the **IdP role name** and **Coder role**, then **Add IdP role**.

   To add a new custom role, select **Roles** from the sidebar, then
   **Create custom role**.

   Visit the [groups and roles documentation](./groups-roles.md) for more information.

### CLI

1. Confirm you have the [Coder CLI](../../install/index.md) installed and are
   logged in with a user who is an Owner or has an Organization Admin role.

1. To fetch the current group sync settings for an organization, run the
   following:

   ```sh
   coder organizations settings show role-sync \
     --org <org-name> \
     > role-sync.json
   ```

   The default for an organization looks like this:

   ```json
   {
       "field": "",
       "mapping": null
   }
   ```

Below is an example that uses the `roles` claim and maps `coder-admins` from the
IdP as an `Organization Admin` and also maps to a custom `provisioner-admin`
role:

```json
{
    "field": "roles",
    "mapping": {
        "coder-admins": ["organization-admin"],
        "infra-admins": ["provisioner-admin"]
    }
}
```

> [!NOTE]
> Be sure to use the `name` field for each role, not the display name.
> Use `coder organization roles show --org=<your-org>` to see roles for your organization.

To set these role sync settings, use the following command:

```sh
coder organizations settings set role-sync \
  --org <org-name> \
  < role-sync.json
```

Visit the Coder UI to confirm these changes:

![IdP Sync](../../images/admin/users/organizations/role-sync.png)

### Server Flags

> [!NOTE]
> Use server flags only with Coder deployments with a single organization.
> You can use the dashboard to configure role sync instead.

1. Configure the Coder server to read groups from the claim name with the
   [OIDC role field](../../reference/cli/server.md#--oidc-user-role-field)
   server flag:

1. Set the following in your Coder server [configuration](../setup/index.md).

   ```env
    # Depending on your identity provider configuration, you may need to explicitly request a "roles" scope
   CODER_OIDC_SCOPES=openid,profile,email,offline_access,roles

   # The following fields are required for role sync:
   CODER_OIDC_USER_ROLE_FIELD=roles
   CODER_OIDC_USER_ROLE_MAPPING='{"TemplateAuthor":["template-admin","user-admin"]}'
   ```

One role from your identity provider can be mapped to many roles in Coder. The
example above maps to two roles in Coder.

</div>

## Organization Sync

If your OpenID Connect provider supports groups/role claims, you can configure
Coder to synchronize claims in your auth provider to organizations within Coder.

Viewing and editing the organization settings requires deployment admin
permissions (UserAdmin or Owner).

Organization sync works across all organizations. On user login, the sync will
add and remove the user from organizations based on their IdP claims. After the
sync, the user's state should match that of the IdP.

You can initiate an organization sync through the Coder dashboard or CLI:

<div class="tabs">

### Dashboard

1. Fetch the corresponding organization IDs using the following endpoint:

   ```text
   https://[coder.example.com]/api/v2/organizations
   ```

1. As a Coder organization user admin or site-wide user admin, go to
   **Admin settings** > **Deployment** and select **IdP organization sync**.

1. In the **Organization sync field** text box, enter the organization claim,
   then select **Save**.

   Users are automatically added to the default organization.

   Do not disable **Assign Default Organization**. If you disable the default
   organization, the system will remove users who are already assigned to it.

1. Enter an IdP organization name and Coder organization(s), then select **Add
   IdP organization**:

   ![IdP organization sync](../../images/admin/users/organizations/idp-org-sync.png)

### CLI

Use the Coder CLI to show and adjust the settings.

These deployment-wide settings are stored in the database. After you change the
settings, a user's memberships will update when they log out and log back in.

1. Show the current settings:

   ```console
   coder organization settings show org-sync
   {
      "field": "organizations",
      "mapping": {
         "product": ["868e9b76-dc6e-46ab-be74-a891e9bd784b", "cbdcf774-9412-4118-8cd9-b3f502c84dfb"]
      },
      "organization_assign_default": true
   }
   ```

1. Update with the JSON payload. In this example, `settings.json` contains the
   payload:

   ```console
   coder organization settings set org-sync < settings.json
   {
      "field": "organizations",
      "mapping": {
         "product": [
            "868e5b23-dc6e-46ab-be74-a891e9bd784b",
            "cbdcf774-4123-4118-8cd9-b3f502c84dfb"
         ],
         "sales": [
            "d79144d9-b30a-555a-9af8-7dac83b2q4ec",
         ]
      },
      "organization_assign_default": true
   }
   ```

   Analyzing the JSON payload:

   | Field                       | Explanation                                                                                                                                                                                                                                                                             |
   |:----------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
   | field                       | If this field is the empty string `""`, then org-sync is disabled. </br> Org memberships must be manually configured through the UI or API.                                                                                                                                             |
   | mapping                     | Mapping takes a claim from the IdP, and associates it with 1 or more organizations by UUID. </br> No validation is done, so you can put UUID's of orgs that do not exist (a noop). The UI picker will allow selecting orgs from a drop down, and convert it to a UUID for you.          |
   | organization_assign_default | This setting exists for maintaining backwards compatibility with single org deployments, either through their upgrade, or in perpetuity. </br> If this is set to 'true', all users will always be assigned to the default organization regardless of the mappings and their IdP claims. |

</div>

## Troubleshooting group/role/organization sync

Some common issues when enabling group, role, or organization sync.

### General guidelines

If you are running into issues with a sync:

1. View your Coder server logs and enable
   [verbose mode](../../reference/cli/index.md#-v---verbose).

1. To reduce noise, you can filter for only logs related to group/role sync:

   ```sh
   CODER_LOG_FILTER=".*userauth.*|.*groups returned.*"
   ```

1. Restart the server after changing these configuration values.

1. Attempt to log in, preferably with a user who has the `Owner` role.

The logs for a successful sync look like this (human-readable):

```sh
[debu]  coderd.userauth: got oidc claims  request_id=49e86507-6842-4b0b-94d4-f245e62e49f3  source=id_token  claim_fields="[aio aud email exp groups iat idp iss name nbf oid preferred_username rh sub tid uti ver]"  blank=[]

[debu]  coderd.userauth: got oidc claims  request_id=49e86507-6842-4b0b-94d4-f245e62e49f3  source=userinfo  claim_fields="[email family_name given_name name picture sub]"  blank=[]

[debu]  coderd.userauth: got oidc claims  request_id=49e86507-6842-4b0b-94d4-f245e62e49f3  source=merged  claim_fields="[aio aud email exp family_name given_name groups iat idp iss name nbf oid picture preferred_username rh sub tid uti ver]"  blank=[]

[debu]  coderd: groups returned in oidc claims  request_id=49e86507-6842-4b0b-94d4-f245e62e49f3  email=ben@coder.com  username=ben  len=3  groups="[c8048e91-f5c3-47e5-9693-834de84034ad 66ad2cc3-a42f-4574-a281-40d1922e5b65 70b48175-107b-4ad8-b405-4d888a1c466f]"
```

To view the full claim, the Owner role can visit this endpoint on their Coder
deployment after logging in:

```sh
https://[coder.example.com]/api/v2/debug/[username]/debug-link
```

### User not being assigned / Group does not exist

If you want Coder to create groups that do not exist, you can set the following
environment variable.

If you enable this, your OIDC provider might be sending over many unnecessary
groups. Use filtering options on the OIDC provider to limit the groups sent over
to prevent creating excess groups.

```env
# as an environment variable
CODER_OIDC_GROUP_AUTO_CREATE=true
```

```shell
# as a flag
--oidc-group-auto-create=true
```

A basic regex filtering option on the Coder side is available. This is applied
**after** the group mapping (`CODER_OIDC_GROUP_MAPPING`), meaning if the group
is remapped, the remapped value is tested in the regex. This is useful if you
want to filter out groups that do not match a certain pattern. For example, if
you want to only allow groups that start with `my-group-` to be created, you can
set the following environment variable.

```env
# as an environment variable
CODER_OIDC_GROUP_REGEX_FILTER="^my-group-.*$"
```

```shell
# as a flag
--oidc-group-regex-filter="^my-group-.*$"
```

### Invalid Scope

If you see an error like the following, you may have an invalid scope.

```console
The application '<oidc_application>' asked for scope 'groups' that doesn't exist on the resource...
```

This can happen because the identity provider has a different name for the
scope. For example, Azure AD uses `GroupMember.Read.All` instead of `groups`.
You can find the correct scope name in the IdP's documentation. Some IdPs allow
configuring the name of this scope.

The solution is to update the value of `CODER_OIDC_SCOPES` to the correct value
for the identity provider.

### No `group` claim in the `got oidc claims` log

Steps to troubleshoot.

1. Ensure the user is a part of a group in the IdP. If the user has 0 groups, no
   `groups` claim will be sent.
2. Check if another claim appears to be the correct claim with a different name.
   A common name is `memberOf` instead of `groups`. If this is present, update
   `CODER_OIDC_GROUP_FIELD=memberOf`.
3. Make sure the number of groups being sent is under the limit of the IdP. Some
   IdPs will return an error, while others will just omit the `groups` claim. A
   common solution is to create a filter on the identity provider that returns
   less than the limit for your IdP.
   - [Azure AD limit is 200, and omits groups if exceeded.](https://learn.microsoft.com/en-us/azure/active-directory/hybrid/connect/how-to-connect-fed-group-claims#options-for-applications-to-consume-group-information)
   - [Okta limit is 100, and returns an error if exceeded.](https://developer.okta.com/docs/reference/api/oidc/#scope-dependent-claims-not-always-returned)

## Provider-Specific Guides

<div class="tabs">

### Active Directory Federation Services (ADFS)

> [!NOTE]
> Tested on ADFS 4.0, Windows Server 2019

1. In your Federation Server, create a new application group for Coder.
   Follow the steps as described in the [Windows Server documentation]
   (https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/development/msal/adfs-msal-web-app-web-api#app-registration-in-ad-fs).

   - **Server Application**: Note the Client ID.
   - **Configure Application Credentials**: Note the Client Secret.
   - **Configure Web API**: Set the Client ID as the relying party identifier.
   - **Application Permissions**: Allow access to the claims `openid`, `email`,
     `profile`, and `allatclaims`.

1. Visit your ADFS server's `/.well-known/openid-configuration` URL and note the
   value for `issuer`.

   This will look something like
   `https://adfs.corp/adfs/.well-known/openid-configuration`.

1. In Coder's configuration file (or Helm values as appropriate), set the
   following environment variables or their corresponding CLI arguments:

   - `CODER_OIDC_ISSUER_URL`: `issuer` value from the previous step.
   - `CODER_OIDC_CLIENT_ID`: Client ID from step 1.
   - `CODER_OIDC_CLIENT_SECRET`: Client Secret from step 1.
   - `CODER_OIDC_AUTH_URL_PARAMS`: set to

     ```json
     {"resource":"$CLIENT_ID"}
     ```

     Where `$CLIENT_ID` is the Client ID from step 1.
     Consult the Microsoft [AD FS OpenID Connect/OAuth flows and Application Scenarios documentation](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-openid-connect-oauth-flows-scenarios#:~:text=scope%E2%80%AFopenid.-,resource,-optional) for more information.

     This is required for the upstream OIDC provider to return the requested
     claims.

   - `CODER_OIDC_IGNORE_USERINFO`: Set to `true`.

1. Configure
   [Issuance Transform Rules](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-rule-to-send-ldap-attributes-as-claims)
   on your Federation Server to send the following claims:

   - `preferred_username`: You can use e.g. "Display Name" as required.
   - `email`: You can use e.g. the LDAP attribute "E-Mail-Addresses" as
     required.
   - `email_verified`: Create a custom claim rule:

     ```json
     => issue(Type = "email_verified", Value = "true")
     ```

   - (Optional) If using Group Sync, send the required groups in the configured
     groups claim field.
     Use [this answer from Stack Overflow](https://stackoverflow.com/a/55570286) for an example.

## Next Steps

- [Configure OIDC Refresh Tokens](./oidc-auth/refresh-tokens.md)
- [Organizations](./organizations.md)
- [Groups & Roles](./groups-roles.md)

---

# Organizations

Source: https://coder.com/docs/admin/users/organizations

# Organizations (Premium)

> [!NOTE]
> Organizations requires a
> [Premium license](https://coder.com/pricing#compare-plans). For more details,
> [contact your account team](https://coder.com/contact).

Organizations can be used to segment and isolate resources inside a Coder
deployment for different user groups or projects.

## Example

Here is an example of how one could use organizations to run a Coder deployment
with multiple platform teams, all with unique resources:

![Organizations Example](../../images/admin/users/organizations/diagram.png)

For more information about how to use organizations, visit the
[organizations best practices](../../tutorials/best-practices/organizations.md)
guide.

## The default organization

All Coder deployments start with one organization called `coder`. All new users
are added to this organization by default.

To edit the organization details, select **Admin settings** from the top bar, then
**Organizations**:

<Image height="255px" src="../../images/admin/users/organizations/admin-settings-orgs.png" alt="Organizations Menu" align="center" />

From there, you can manage the name, icon, description, users, and groups:

![Organization Settings](../../images/admin/users/organizations/default-organization-settings.png)

## Additional organizations

Any additional organizations have unique admins, users, templates, provisioners,
groups, and workspaces. Each organization must have at least one dedicated
[provisioner](../provisioners/index.md) since the built-in provisioners only apply to
the default organization.

You can configure [organization/role/group sync](./idp-sync.md) from your
identity provider to avoid manually assigning users to organizations.

## How to create an organization

### Prerequisites

- Coder v2.16+ deployment with Premium license and Organizations enabled
  ([contact your account team](https://coder.com/contact)) for more details.
- User with `Owner` role

### 1. Create the organization

To create a new organization:

1. Select **Admin settings** from the top bar, then **Organizations**.

1. Select the current organization to expand the organizations dropdown, then select **Create Organization**:

   <Image height="212px" src="../../images/admin/users/organizations/org-dropdown-create.png" alt="Organizations dropdown and Create Organization" align="center" />

1. Enter the details and select **Save** to continue:

   <Image height="579px" src="../../images/admin/users/organizations/new-organization.png" alt="New Organization" align="center" />

In this example, we'll create the `data-platform` org.

Next deploy a provisioner and template for this organization.

### 2. Deploy a provisioner

[Provisioners](../provisioners/index.md) are organization-scoped and are responsible
for executing Terraform/OpenTofu to provision the infrastructure for workspaces
and testing templates. Before creating templates, we must deploy at least one
provisioner as the built-in provisioners are scoped to the default organization.

1. Using Coder CLI, run the following command to create a key that will be used
   to authenticate the provisioner:

   ```shell
   coder provisioner keys create data-cluster-key --org data-platform
   Successfully created provisioner key data-cluster! Save this authentication token, it will not be shown again.

   < key omitted >
   ```

1. Start the provisioner with the key on your desired platform.

   In this example, start the provisioner using the Coder CLI on a host with
   Docker. For instructions on using other platforms like Kubernetes, see our
   [provisioner documentation](../provisioners/index.md).

   ```sh
   export CODER_URL=https://<your-coder-url>
   export CODER_PROVISIONER_DAEMON_KEY=<key>
   coder provisionerd start --org <org-name>
   ```

### 3. Create a template

Once you've started a provisioner, you can create a template. You'll notice the
**Create Template** screen now has an organization dropdown:

![Template Org Picker](../../images/admin/users/organizations/template-org-picker.png)

### 4. Add members

From **Admin settings**, select **Organizations**, then **Members** to add members to
your organization. Once added, members will be able to see the
organization-specific templates.

<Image height="365px" src="../../images/admin/users/organizations/organization-members.png" alt="Add members" align="center" />

### 5. Create a workspace

Now, users in the data platform organization will see the templates related to
their organization. Users can be in multiple organizations.

![Workspace List](../../images/admin/users/organizations/workspace-list.png)

## Next steps

- [Organizations - best practices](../../tutorials/best-practices/organizations.md)

---

# Quotas

Source: https://coder.com/docs/admin/users/quotas

# Quotas

Quotas are a mechanism for controlling spend by associating costs with workspace
templates and assigning budgets to users. Users that exceed their budget will be
blocked from launching more workspaces until they either delete their other
workspaces or get their budget extended.

For example: A template is configured with a cost of 5 credits per day, and the
user is granted 15 credits, which can be consumed by both started and stopped
workspaces. This budget limits the user to 3 concurrent workspaces.

Quotas are scoped to [Groups](./groups-roles.md) in Enterprise and
[organizations](./organizations.md) in Premium.

## Definitions

- **Credits** is the fundamental unit representing cost in the quota system.
  This integer can be arbitrary, or it can map to your preferred currency.
- **Budget** is the per-user, enforced, upper limit to credit spend.
- **Allowance** is a grant of credits to the budget.

## Establishing Costs

Templates describe their cost through the `daily_cost` attribute in
[`resource_metadata`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/metadata).
Since costs are associated with resources, an offline workspace may consume less
quota than an online workspace.

A common use case is separating costs for a persistent volume and ephemeral
compute:

```hcl
resource "docker_volume" "home_volume" {
  name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-root"
}

resource "coder_metadata" "home_volume" {
    resource_id = docker_volume.home_volume.id
    daily_cost  = 10
}

resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = "codercom/code-server:latest"
  ...
  volumes {
    container_path = "/home/coder/"
    volume_name    = docker_volume.home_volume.name
    read_only      = false
  }
}

resource "coder_metadata" "workspace" {
    count       = data.coder_workspace.me.start_count
    resource_id = docker_container.workspace.id
    daily_cost  = 20
}
```

When the workspace above is shut down, the `docker_container` and
`coder_metadata` both get deleted. This reduces the cost from 30 credits to 10
credits.

Resources without a `daily_cost` value are considered to cost 0. If the cost was
removed on the `docker_volume` above, the template would consume 0 credits when
it's offline. This technique is good for incentivizing users to shut down their
unused workspaces and freeing up compute in the cluster.

## Establishing Budgets

Each group has a configurable Quota Allowance. A user's budget is calculated as
the sum of their allowances.

![group-settings](../../images/admin/users/quotas/quota-groups.png)

For example:

| Group Name | Quota Allowance |
|------------|-----------------|
| Frontend   | 10              |
| Backend    | 20              |
| Data       | 30              |

<br/>

| Username | Groups            | Effective Budget |
|----------|-------------------|------------------|
| jill     | Frontend, Backend | 30               |
| jack     | Backend, Data     | 50               |
| sam      | Data              | 30               |
| alex     | Frontend          | 10               |

By default, groups are assumed to have a default allowance of 0.

## Quota Enforcement

Coder enforces Quota on workspace start and stop operations. The workspace build
process dynamically calculates costs, so quota violation fails builds as opposed
to failing the build-triggering operation. For example, the Workspace Create
Form will never get held up by quota enforcement.

![build-log](../../images/admin/quota-buildlog.png)

## Up next

- [Group Sync](./idp-sync.md)
- [Control plane configuration](../setup/index.md)

---

# Sessions & API Tokens

Source: https://coder.com/docs/admin/users/sessions-tokens

# API & Session Tokens

Users can generate tokens to make API requests on behalf of themselves.

## Short-Lived Tokens (Sessions)

The [Coder CLI](../../install/cli.md) and
[Backstage Plugin](https://github.com/coder/backstage-plugins) use short-lived
token to authenticate. To generate a short-lived session token on behalf of your
account, visit the following URL: `https://coder.example.com/cli-auth`

### Retrieve the current session token

If you're already logged in with the CLI, you can retrieve your current session
token for use in scripts and automation:

```sh
coder login token
```

This is useful for passing your session token to other tools:

```sh
export CODER_SESSION_TOKEN=$(coder login token)
```

### Session Durations

By default, sessions last 24 hours and are automatically refreshed. You can
configure
[`CODER_SESSION_DURATION`](../../reference/cli/server.md#--session-duration) to
change the duration and
[`CODER_DISABLE_SESSION_EXPIRY_REFRESH`](../../reference/cli/server.md#--disable-session-expiry-refresh)
to configure this behavior.

## Long-Lived Tokens (API Tokens)

Users can create long lived tokens. We refer to these as "API tokens" in the
product.

### Generate a long-lived API token on behalf of yourself

<div class="tabs">

#### UI

Visit your account settings in the top right of the dashboard or by navigating
to `https://coder.example.com/settings/account`

Navigate to the tokens page in the sidebar and create a new token:

![Create an API token](../../images/admin/users/create-token.png)

#### CLI

Use the following command:

```sh
coder tokens create --name=my-token --lifetime=720h
```

See the help docs for
[`coder tokens create`](../../reference/cli/tokens_create.md) for more info.

</div>

### Generate a long-lived API token on behalf of another user

You must have the `Owner` role to generate a token for another user.

As of Coder v2.17+, you can use the CLI or API to create long-lived tokens on
behalf of other users. Use the API for earlier versions of Coder.

<div class="tabs">

#### CLI

```sh
coder tokens create --name my-token --user <username>
```

See the full CLI reference for
[`coder tokens create`](../../reference/cli/tokens_create.md)

#### API

Use our API reference for more information on how to
[create token API key](../../reference/api/users.md#create-token-api-key)

</div>

### Set max token length

You can use the
[`CODER_MAX_TOKEN_LIFETIME`](https://coder.com/docs/reference/cli/server#--max-token-lifetime)
server flag to set the maximum duration for long-lived tokens in your
deployment.

### Remove or expire a token

You can remove a token using the CLI or the API. By default, `coder tokens remove`
expires the token, (soft-delete):

```console
coder tokens remove <name|id>
```

Expired tokens can no longer be used for authentication and are hidden from
token listings by default. To include expired tokens, use the
`--include-expired` flag:

```console
coder tokens list --include-expired
```

To hard-delete a token, use the `--delete` flag:

```console
coder tokens remove --delete <name|id>
```

## API Key Scopes

API key scopes allow you to limit the permissions of a token to specific operations. By default, tokens are created with the `all` scope, granting full access to all actions the user can perform. For improved security, you can create tokens with limited scopes that restrict access to only the operations needed.

Scopes follow the format `resource:action`, where `resource` is the type of object (like `workspace`, `template`, or `user`) and `action` is the operation (like `read`, `create`, `update`, or `delete`). You can also use wildcards like `workspace:*` to grant all permissions for a specific resource type.

### Creating tokens with scopes

You can specify scopes when creating a token using the `--scope` flag:

```sh
# Create a token that can only read workspaces
coder tokens create --name "readonly-token" --scope "workspace:read"

# Create a token with multiple scopes
coder tokens create --name "limited-token" --scope "workspace:read" --scope "template:read"
```

Common scope examples include:

- `workspace:read` - View workspace information
- `workspace:*` - Full workspace access (create, read, update, delete)
- `template:read` - View template information
- `api_key:read` - View API keys (useful for automation)
- `application_connect` - Connect to workspace applications

For a complete list of available scopes, see the API reference documentation.

### Allow lists (advanced)

For additional security, you can combine scopes with allow lists to restrict tokens to specific resources. Allow lists let you limit a token to only interact with particular workspaces, templates, or other resources by their UUID:

```sh
# Create a token limited to a specific workspace
coder tokens create --name "workspace-token" \
  --scope "workspace:read" \
  --allow "workspace:a1b2c3d4-5678-90ab-cdef-1234567890ab"
```

**Important:** Allow lists are exclusive - the token can **only** perform actions on resources explicitly listed. In the example above, the token can only read the specified workspace and cannot access any other resources (templates, organizations, other workspaces, etc.). To maintain access to other resources, you must explicitly add them to the allow list:

```sh
# Token that can read one workspace AND access templates and user info
coder tokens create --name "limited-token" \
  --scope "workspace:read" --scope "template:*" --scope "user:read" \
  --allow "workspace:a1b2c3d4-5678-90ab-cdef-1234567890ab" \
  --allow "template:*" \
  --allow "user:*" \
  ... etc
```

---

# Templates

Source: https://coder.com/docs/admin/templates

# Template

Templates are written in
[Terraform](https://developer.hashicorp.com/terraform/intro) and define the
underlying infrastructure that all Coder workspaces run on.

![Starter templates](../../images/admin/templates/starter-templates.png)

<small>The "Starter Templates" page within the Coder dashboard.</small>

## Learn the concepts

While templates are written in standard Terraform, it's important to learn the
Coder-specific concepts behind templates. The best way to learn the concepts is
by
[creating a basic template from scratch](../../tutorials/template-from-scratch.md).
If you are unfamiliar with Terraform, see
[Hashicorp's Tutorials](https://developer.hashicorp.com/terraform/tutorials) for
common cloud providers.

## Starter templates

After learning the basics, use starter templates to import a template with
sensible defaults for popular platforms (e.g. AWS, Kubernetes, Docker, etc).
Docs:
[Create a template from a starter template](./creating-templates.md#from-a-starter-template).

## Extending templates

It's often necessary to extend the template to make it generally useful to end
users. Common modifications are:

- Your image(s) (e.g. a Docker image with languages and tools installed). Docs:
  [Image management](./managing-templates/image-management.md).
- Additional parameters (e.g. disk size, instance type, or region). Docs:
  [Template parameters](./extending-templates/parameters.md).
- Additional IDEs (e.g. JetBrains) or features (e.g. dotfiles, RDP). Docs:
  [Adding IDEs and features](./extending-templates/index.md).

Learn more about the various ways you can
[extend your templates](./extending-templates/index.md).

## Best Practices

We recommend starting with a universal template that can be used for basic
tasks. As your Coder deployment grows, you can create more templates to meet the
needs of different teams.

- [Image management](./managing-templates/image-management.md): Learn how to
  create and publish images for use within Coder workspaces & templates.
- [Dev Containers integration](../integrations/devcontainers/integration.md): Enable
  native dev containers support using `@devcontainers/cli` and Docker.
- [Envbuilder](../integrations/devcontainers/envbuilder/index.md): Alternative approach
  for environments without Docker access.
- [Template hardening](./extending-templates/resource-persistence.md#-bulletproofing):
  Configure your template to prevent certain resources from being destroyed
  (e.g. user disks).
- [Manage templates with Ci/Cd pipelines](./managing-templates/change-management.md):
  Learn how to source control your templates and use GitOps to ensure template
  changes are reviewed and tested.
- [Permissions and Policies](./template-permissions.md): Control who may access
  and modify your template.
- [External Workspaces](./managing-templates/external-workspaces.md): Learn how to connect your existing infrastructure to Coder workspaces.

<children></children>

---

# Creating Templates

Source: https://coder.com/docs/admin/templates/creating-templates

# Creating Templates

Users with the `Template Administrator` role or above can create templates
within Coder.

## From a starter template

In most cases, it is best to start with a starter template.

<div class="tabs">

### Web UI

After navigating to the Templates page in the Coder dashboard, choose
`Create Template > Choose a starter template`.

![Create a template](../../images/admin/templates/create-template.png)

From there, select a starter template for desired underlying infrastructure for
workspaces.

![Starter templates](../../images/admin/templates/starter-templates.png)

Give your template a name, description, and icon and press `Create template`.

![Name and icon](../../images/admin/templates/import-template.png)

If template creation fails, it's likely that Coder is not authorized to deploy infrastructure in the given location.
Learn how to configure [provisioner authentication](./extending-templates/provider-authentication.md).

### CLI

You can the [Coder CLI](../../install/cli.md) to manage templates for Coder.
After [logging in](../../reference/cli/login.md) to your deployment, create a
folder to store your templates:

```sh
# This snippet applies to macOS and Linux only
mkdir $HOME/coder-templates
cd $HOME/coder-templates
```

Use the [`templates init`](../../reference/cli/templates_init.md) command to
pull a starter template:

```sh
coder templates init
```

After pulling the template to your local machine (e.g. `aws-linux`), you can
rename it:

```sh
# This snippet applies to macOS and Linux only
mv aws-linux universal-template
cd universal-template
```

Next, push it to Coder with the
[`templates push`](../../reference/cli/templates_push.md) command:

```sh
coder templates push
```

If `template push` fails, it's likely that Coder is not authorized to deploy infrastructure in the given location.
Learn how to configure [provisioner authentication](../provisioners/index.md).

You can edit the metadata of the template such as the display name with the
[`templates edit`](../../reference/cli/templates_edit.md) command:

```sh
coder templates edit universal-template \
  --display-name "Universal Template" \
  --description "Virtual machine configured with Java, Python, Typescript, IntelliJ IDEA, and Ruby. Use this for starter projects. " \
  --icon "/emojis/2b50.png"
```

### CI/CD

Follow the [change management](./managing-templates/change-management.md) guide
to manage templates via GitOps.

</div>

## From an existing template

You can duplicate an existing template in your Coder deployment. This will copy
the template code and metadata, allowing you to make changes without affecting
the original template.

<div class="tabs">

### Web UI

After navigating to the page for a template, use the dropdown menu on the right
to `Duplicate`.

![Duplicate menu](../../images/admin/templates/duplicate-menu.png)

Give the new template a name, icon, and description.

![Duplicate page](../../images/admin/templates/duplicate-page.png)

Press `Create template`. After the build, you will be taken to the new template
page.

![New template](../../images/admin/templates/new-duplicate-template.png)

### CLI

First, ensure you are logged in to the control plane as a user with permissions
to read and write permissions.

```console
coder login
```

You can list the available templates with the following CLI invocation.

```console
coder templates list
```

After identified the template you'd like to work from, clone it into a directory
with a name you'd like to assign to the new modified template.

```console
coder templates pull <template-name> ./<new-template-name>
```

Then, you can make modifications to the existing template in this directory and
push them to the control plane using the `-d` flag to specify the directory.

```console
coder templates push <new-template-name> -d ./<new-template-name>
```

You will then see your new template in the dashboard.

</div>

## From scratch (advanced)

There may be cases where you want to create a template from scratch. You can use
[any Terraform provider](https://registry.terraform.io) with Coder to create
templates for additional clouds (e.g. Hetzner, Alibaba) or orchestrators
(VMware, Proxmox) that we do not provide example templates for.

Refer to the following resources:

- [Tutorial: Create a template from scratch](../../tutorials/template-from-scratch.md)
- [Extending templates](./extending-templates/index.md): Features and concepts
  around templates (agents, parameters, variables, etc)
- [Coder Registry](https://registry.coder.com/templates): Official and community
  templates for Coder
- [Coder Terraform Provider Reference](https://registry.terraform.io/providers/coder/coder)

### Next steps

- [Extending templates](./extending-templates/index.md)
- [Managing templates](./managing-templates/index.md)

---

# Managing Templates

Source: https://coder.com/docs/admin/templates/managing-templates

# Working with templates

You create and edit Coder templates as
[Terraform](../../../tutorials/quickstart.md) configuration files (`.tf`) and
any supporting files, like a README or configuration files for other services.

## Who creates templates?

The [Template Admin](../../../admin/users/groups-roles.md#roles) role (and
above) can create templates. End users, like developers, create workspaces from
them. Templates can also be [managed with git](./change-management.md), allowing
any developer to propose changes to a template.

You can give different users and groups access to templates with
[role-based access control](../template-permissions.md).

## Starter templates

We provide starter templates for common cloud providers, like AWS, and
orchestrators, like Kubernetes. From there, you can modify them to use your own
images, VPC, cloud credentials, and so on. Coder supports all Terraform
resources and properties, so fear not if your favorite cloud provider isn't
here!

![Starter templates](../../../images/start/starter-templates.png)

If you prefer to use Coder on the
[command line](../../../reference/cli/index.md), `coder templates init`.

Coder starter templates are also available on our
[GitHub repo](https://github.com/coder/coder/tree/main/examples/templates).

## Community Templates

As well as Coder's starter templates, you can see a list of community templates
by our users
[here](https://github.com/coder/coder/blob/main/examples/templates/community-templates.md).

## Editing templates

Our starter templates are meant to be modified for your use cases. You can edit
any template's files directly in the Coder dashboard.

![Editing a template](../../../images/templates/choosing-edit-template.gif)

If you'd prefer to use the CLI, use `coder templates pull`, edit the template
files, then `coder templates push`.

> [!TIP]
> Even if you are a Terraform expert, we suggest reading our
> [guided tour of a template](../../../tutorials/template-from-scratch.md).

## Updating templates

Coder tracks a template's versions, keeping all developer workspaces up-to-date.
When you publish a new version, developers are notified to get the latest
infrastructure, software, or security patches. Learn more about
[change management](./change-management.md).

![Updating a template](../../../images/templates/update.png)

### Template update policies

> [!NOTE]
> Template update policies are a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Licensed template admins may want workspaces to always remain on the latest
version of their parent template. To do so, enable **Template Update Policies**
in the template's general settings. All non-admin users of the template will be
forced to update their workspaces before starting them once the setting is
applied. Workspaces which leverage autostart or start-on-connect will be
automatically updated on the next startup.

![Template update policies](../../../images/templates/update-policies.png)

## Delete templates

You can delete a template using both the coder CLI and UI. Only
[template admins and owners](../../users/groups-roles.md#roles) can delete a
template, and the template must not have any running workspaces associated to
it.

In the UI, navigate to the template you want to delete, and select the dropdown
in the right-hand corner of the page to delete the template.

![delete-template](../../../images/delete-template.png)

Using the CLI, login to Coder and run the following command to delete a
template:

```shell
coder templates delete <template-name>
```

## Next steps

- [Image management](./image-management.md)
- [Dev Containers integration](../../integrations/devcontainers/integration.md) (recommended)
- [Envbuilder](../../integrations/devcontainers/envbuilder/index.md) (alternative for environments without Docker)
- [Change management](./change-management.md)

---

# Image Management

Source: https://coder.com/docs/admin/templates/managing-templates/image-management

# Image Management

While Coder provides example
[base container images](https://github.com/coder/enterprise-images) for
workspaces, it's often best to create custom images that matches the needs of
your users. This document serves a guide to operational maturity with some best
practices around managing workspaces images for Coder.

1. Create a minimal base image
2. Create golden image(s) with standard tooling
3. Allow developers to bring their own images and customizations with Dev
   Containers

An image is just one of the many properties defined within the template.
Templates can pull images from a public image registry (e.g. Docker Hub) or an
internal one, thanks to Terraform.

## Create a minimal base image

While you may not use this directly in Coder templates, it's useful to have a
minimal base image is a small image that contains only the necessary
dependencies to work in your network and work with Coder. Here are some things
to consider:

- `curl`, `wget`, or `busybox` is required to download and run
  [the agent](https://github.com/coder/coder/blob/main/provisionersdk/scripts/bootstrap_linux.sh)
- `git` is recommended so developers can clone repositories
- If the Coder server is using a certificate from an internal certificate
  authority (CA), you'll need to add or mount these into your image
- Other generic utilities that will be required by all users, such as `ssh`,
  `docker`, `bash`, `jq`, and/or internal tooling
- Consider creating (and starting the container with) a non-root user

See Coder's
[example base image](https://github.com/coder/enterprise-images/tree/main/images/minimal)
for reference.

## Create general-purpose golden image(s) with standard tooling

It's often practical to have a few golden images that contain standard tooling
for developers. These images should contain a number of languages (e.g. Python,
Java, TypeScript), IDEs (VS Code, JetBrains, PyCharm), and other tools (e.g.
`docker`). Unlike project-specific images (which are also important), general
purpose images are great for:

- **Scripting:** Developers may just want to hop in a Coder workspace to run
  basic scripts or queries.
- **Day 1 Onboarding:** New developers can quickly get started with a familiar
  environment without having to browse through (or create) an image
- **Basic Projects:** Developers can use these images for simple projects that
  don't require any specific tooling outside of the standard libraries. As the
  project gets more complex, its best to move to a project-specific image.
- **"Golden Path" Projects:** If your developer platform offers specific tech
  stacks and types of projects, the golden image can be a good starting point
  for those projects.

This is often referred to as a "sandbox" or "kitchen sink" image. Since large
multi-purpose container images can quickly become difficult to maintain, it's
important to keep the number of general-purpose images to a minimum (2-3 in
most cases) with a well-defined scope.

Examples:

- [Universal Dev Containers Image](https://github.com/devcontainers/images/tree/main/src/universal)

## Allow developers to bring their own images and customizations with Dev Containers

While golden images are great for general use cases, developers will often need
specific tooling for their projects. The [Dev Container](https://containers.dev)
specification allows developers to define their projects dependencies within a
`devcontainer.json` in their Git repository.

- [Configure a template for Dev Containers](../../integrations/devcontainers/integration.md) (recommended)
- [Learn about Envbuilder](../../integrations/devcontainers/envbuilder/index.md) (alternative for environments without Docker)

---

# Change Management

Source: https://coder.com/docs/admin/templates/managing-templates/change-management

# Template Change Management

We recommend source-controlling your templates as you would other any code, and
automating the creation of new versions in CI/CD pipelines.

These pipelines will require tokens for your deployment. To cap token lifetime
on creation,
[configure Coder server to set a shorter max token lifetime](../../../reference/cli/server.md#--max-token-lifetime).

## coderd Terraform Provider

The
[coderd Terraform provider](https://registry.terraform.io/providers/coder/coderd/latest)
can be used to push new template versions, either manually, or in CI/CD
pipelines. To run the provider in a CI/CD pipeline, and to prevent drift, you'll
need to store the Terraform state
[remotely](https://developer.hashicorp.com/terraform/language/backend).

```tf
terraform {
  required_providers {
    coderd = {
      source = "coder/coderd"
    }
  }
  backend "gcs" {
    bucket = "example-bucket"
    prefix = "terraform/state"
  }
}

provider "coderd" {
  // Can be populated from environment variables
  url   = "https://coder.example.com"
  token = "****"
}

// Get the commit SHA of the configuration's git repository
variable "TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA" {
  type = string
}

resource "coderd_template" "kubernetes" {
  name = "kubernetes"
  description = "Develop in Kubernetes!"
  versions = [{
    directory = ".coder/templates/kubernetes"
    active    = true
    # Version name is optional
    name = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA
    tf_vars = [{
      name  = "namespace"
      value = "default4"
    }]
  }]
  /* ... Additional template configuration */
}
```

For an example, see how we push our development image and template
[with GitHub actions](https://github.com/coder/coder/blob/main/.github/workflows/dogfood.yaml).

## Coder CLI

You can [install Coder](../../../install/cli.md) CLI to automate pushing new
template versions in CI/CD pipelines. For GitHub Actions, see our
[setup-coder](https://github.com/coder/setup-coder) action.

```console
# Install the Coder CLI
curl -L https://coder.com/install.sh | sh
# curl -L https://coder.com/install.sh | sh -s -- --version=0.x

# To create API tokens, use `coder tokens create`.
# If no `--lifetime` flag is passed during creation, the default token lifetime
# will be 30 days.
# These variables are consumed by Coder
export CODER_URL=https://coder.example.com
export CODER_SESSION_TOKEN=*****

# Template details
export CODER_TEMPLATE_NAME=kubernetes
export CODER_TEMPLATE_DIR=.coder/templates/kubernetes
export CODER_TEMPLATE_VERSION=$(git rev-parse --short HEAD)

# Push the new template version to Coder
coder templates push --yes $CODER_TEMPLATE_NAME \
    --directory $CODER_TEMPLATE_DIR \
    --name=$CODER_TEMPLATE_VERSION # Version name is optional
```

## Testing and Publishing Coder Templates in CI/CD

See our [testing templates](../../../tutorials/testing-templates.md) tutorial
for an example of how to test and publish Coder templates in a CI/CD pipeline.

### Next steps

- [Coder CLI Reference](../../../reference/cli/templates.md)
- [Coderd Terraform Provider Reference](https://registry.terraform.io/providers/coder/coderd/latest/docs)
- [Coderd API Reference](../../../reference/index.md)

---

# Envbuilder

Source: https://coder.com/docs/admin/templates/managing-templates/envbuilder

# Envbuilder

Envbuilder shifts environment definition from template administrators to
developers. Instead of baking tools into template images, developers define
their environments via `devcontainer.json` files in their repositories.

Envbuilder transforms the workspace image itself from a dev container
configuration, without requiring a Docker daemon.

For setup instructions, see
[Envbuilder documentation](../../integrations/devcontainers/envbuilder/index.md).

For an alternative that uses Docker inside workspaces, see
[Dev Containers Integration](../../integrations/devcontainers/integration.md).

---

# Template Dependencies

Source: https://coder.com/docs/admin/templates/managing-templates/dependencies

# Template Dependencies

When creating Coder templates, it is unlikely that you will just be using
built-in providers. Part of Terraform's flexibility stems from its rich plugin
ecosystem, and it makes sense to take advantage of this.

That having been said, here are some recommendations to follow, based on the
[Terraform documentation](https://developer.hashicorp.com/terraform/tutorials/configuration-language/provider-versioning).

Following these recommendations will:

- **Prevent unexpected changes:** Your templates will use the same versions of
  Terraform providers each build. This will prevent issues related to changes in
  providers.
- **Improve build performance:** Coder caches provider versions on each build.
  If the same provider version can be re-used on subsequent builds, Coder will
  simply re-use the cached version if it is available.
- **Improve build reliability:** As some providers are hundreds of megabytes in
  size, interruptions in connectivity to the Terraform registry during a
  workspace build can result in a failed build. If Coder is able to re-use a
  cached provider version, the likelihood of this is greatly reduced.

## Lock your provider and module versions

If you add a Terraform provider to `required_providers` without specifying a
version requirement, Terraform will always fetch the latest version on each
invocation:

```terraform
terraform {
  required_providers {
    coder = {
      source = "coder/coder"
    }
    frobnicate = {
      source = "acme/frobnicate"
    }
  }
}
```

Any new releases of the `coder` or `frobnicate` providers will be picked up upon
the next time a workspace is built using this template. This may include
breaking changes.

To prevent this, add a
[version constraint](https://developer.hashicorp.com/terraform/language/expressions/version-constraints)
to each provider in the `required_providers` block:

```terraform
terraform {
  required_providers {
    coder = {
      source = "coder/coder"
      version = ">= 0.2, < 0.3"
    }
    frobnicate = {
      source = "acme/frobnicate"
      version = "~> 1.0.0"
    }
  }
}
```

In the above example, the `coder/coder` provider will be limited to all versions
above or equal to `0.2.0` and below `0.3.0`, while the `acme/frobnicate`
provider will be limited to all versions matching `1.0.x`.

The above also applies to Terraform modules. In the below example, the module
`razzledazzle` is locked to version `1.2.3`.

```terraform
module "razzledazzle" {
  source  = "registry.example.com/modules/razzle/dazzle"
  version = "1.2.3"
  foo     = "bar"
}
```

## Use a Dependency Lock File

Terraform allows creating a
[dependency lock file](https://developer.hashicorp.com/terraform/language/files/dependency-lock)
to track which provider versions were selected previously. This allows you to
ensure that the next workspace build uses the same provider versions as with the
last build.

To create a new Terraform lock file, run the
[`terraform init` command](https://developer.hashicorp.com/terraform/cli/commands/init)
inside a folder containing the Terraform source code for a given template.

This will create a new file named `.terraform.lock.hcl` in the current
directory. When you next run
[`coder templates push`](../../../reference/cli/templates_push.md), the lock
file will be stored alongside with the other template source code.

> [!NOTE]
> Terraform best practices also recommend checking in your
> `.terraform.lock.hcl` into Git or other VCS.

The next time a workspace is built from that template, Coder will make sure to
use the same versions of those providers as specified in the lock file.

If, at some point in future, you need to update the providers and versions you
specified within the version constraints of the template, run

```console
terraform init -upgrade
```

This will check each provider, check the newest satisfiable version based on the
version constraints you specified, and update the `.terraform.lock.hcl` with
those new versions. When you next run `coder templates push`, again, the updated
lock file will be stored and used to determine the provider versions to use for
subsequent workspace builds.

---

# Workspace Scheduling

Source: https://coder.com/docs/admin/templates/managing-templates/schedule

# Workspace Scheduling

You can configure a template to control how workspaces are started and stopped.
You can also manage the lifecycle of failed or inactive workspaces.

![Schedule screen](../../../images/admin/templates/schedule/template-schedule-settings.png)

## Schedule

Template [admins](../../users/index.md) may define these default values:

- [**Default autostop**](../../../user-guides/workspace-scheduling.md#autostop):
  How long a workspace runs without user activity before Coder automatically
  stops it.
- [**Autostop requirement**](#autostop-requirement): Enforce mandatory workspace
  restarts to apply template updates regardless of user activity.
- **Activity bump**: The duration by which to extend a workspace's deadline when activity is detected (default: 1 hour). The workspace will be considered inactive when no sessions are detected (VSCode, JetBrains, Terminal, or SSH). For details on what counts as activity, see the [user guide on activity detection](../../../user-guides/workspace-scheduling.md#activity-detection).
- **Dormancy**: This allows automatic deletion of unused workspaces to reduce
  spend on idle resources.

## Allow users scheduling

For templates where a uniform autostop duration is not appropriate, admins may
allow users to define their own autostart and autostop schedules. Admins can
restrict the days of the week a workspace should automatically start to help
manage infrastructure costs.

## Failure cleanup

> [!NOTE]
> Failure cleanup is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Failure cleanup defines how long a workspace is permitted to remain in the
failed state prior to being automatically stopped. Failure cleanup is only
available for licensed customers.

## Dormancy threshold

> [!NOTE]
> Dormancy threshold is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Dormancy Threshold defines how long Coder allows a workspace to remain inactive
before being moved into a dormant state. A workspace's inactivity is determined
by the time elapsed since a user last accessed the workspace. A workspace in the
dormant state is not eligible for autostart and must be manually activated by
the user before being accessible. Coder stops workspaces during their transition
to the dormant state if they are detected to be running. Dormancy Threshold is
only available for licensed customers.

## Dormancy auto-deletion

> [!NOTE]
> Dormancy auto-deletion is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Dormancy Auto-Deletion allows a template admin to dictate how long a workspace
is permitted to remain dormant before it is automatically deleted. Dormancy
Auto-Deletion is only available for licensed customers.

## Autostop requirement

> [!NOTE]
> Autostop requirement is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Autostop requirement is a template setting that determines how often workspaces
using the template must automatically stop. Autostop requirement ignores any
active connections, and ensures that workspaces do not run in perpetuity when
connections are left open inadvertently.

Workspaces will apply the template autostop requirement on the given day in the
user's timezone and specified quiet hours (see below). This ensures that
workspaces will not be stopped during work hours.

The available options are "Days", which can be set to "Daily", "Saturday" or
"Sunday", and "Weeks", which can be set to any number from 1 to 16.

"Days" governs which days of the week workspaces must stop. If you select
"daily", workspaces must be automatically stopped every day at the start of the
user's defined quiet hours. When using "Saturday" or "Sunday", workspaces will
be automatically stopped on Saturday or Sunday in the user's timezone and quiet
hours.

"Weeks" determines how many weeks between required stops. It cannot be changed
from the default of 1 if you have selected "Daily" for "Days". When using a
value greater than 1, workspaces will be automatically stopped every N weeks on
the day specified by "Days" and the user's quiet hours. The autostop week is
synchronized for all workspaces on the same template.

Autostop requirement is disabled when the template is using the deprecated max
lifetime feature. Templates can choose to use a max lifetime or an autostop
requirement during the deprecation period, but only one can be used at a time.

## User quiet hours

> [!NOTE]
> User quiet hours are a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

User quiet hours can be configured in the user's schedule settings page.
Workspaces on templates with an autostop requirement will only be forcibly
stopped due to the policy at the start of the user's quiet hours.

![User schedule settings](../../../images/admin/templates/schedule/user-quiet-hours.png)

Admins can define the default quiet hours for all users with the
[CODER_QUIET_HOURS_DEFAULT_SCHEDULE](../../../reference/cli/server.md#--default-quiet-hours-schedule)
environment variable. The value should be a cron expression such as
`CRON_TZ=America/Chicago 30 2 * * *` which would set the default quiet hours to
2:30 AM in the America/Chicago timezone. The cron schedule can only have a
minute and hour component. The default schedule is UTC 00:00. It is recommended
to set the default quiet hours to a time when most users are not expected to be
using Coder.

Admins can force users to use the default quiet hours with the
[CODER_ALLOW_CUSTOM_QUIET_HOURS](../../../reference/cli/server.md#--allow-custom-quiet-hours)
environment variable. Users will still be able to see the page, but will be
unable to set a custom time or timezone. If users have already set a custom
quiet hours schedule, it will be ignored and the default will be used instead.

---

# External Workspaces

Source: https://coder.com/docs/admin/templates/managing-templates/external-workspaces

# External Workspaces

External workspaces allow you to seamlessly connect externally managed infrastructure as Coder workspaces. This enables you to integrate existing servers, on-premises systems, or any capable machine with the Coder environment, ensuring a smooth and efficient development workflow without requiring Coder to provision additional compute resources.

## Prerequisites

- Access to external compute resources that can run the Coder agent:
  - **Windows**: amd64 or arm64 architecture
  - **Linux**: amd64, arm64, or armv7 architecture
  - **macOS**: amd64 or arm64 architecture
  - **Examples**: VMs, bare-metal servers, Kubernetes nodes, or any machine meeting the above requirements.
- Networking access to your Coder deployment.
- A workspace template that includes a [`coder_external_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/external_agent) resource.

We provide an example template on how to set up external workspaces in the [Coder Registry](https://registry.coder.com/templates/coder-labs/externally-managed-workspace)

## Benefits

External workspaces offer flexibility and control in complex environments:

- **Incremental adoption of Coder**

  Integrate with existing infrastructure gradually without needing to migrate everything at once. This is particularly useful when gradually migrating workloads to Coder without refactoring current infrastructure.

- **Flexibility**

  Attach cloud, hybrid, or on-premises machines as developer workspaces. This enables connecting existing on-premises GPU servers for ML development or bringing manually provisioned VMs in restricted networks under Coder's workspace management.

- **Separation of concerns**

  Provision compute resources externally (using your existing IaC or manual processes) while managing workspace configuration (apps, scripts) with Terraform. This approach is ideal for running agents in CI pipelines to provision short-lived, externally managed workspaces for testing or build automation.

## Known limitations

- **Lifecycle control**

  Start/stop/restart actions in the Coder UI are disabled for external workspaces.
- **No automatic deprovisioning**

  Deleting an external workspace in Coder removes the agent token and record, but does not delete the underlying compute resource.
- **Manual agent management**

  Administrators are responsible for deploying and maintaining agents on external resources.
- **Limited UI indicators**

  External workspaces are marked in the UI, but underlying infrastructure health is not monitored by Coder.

## When to use it?

Use external workspaces if:

- You have compute resources provisioned outside of Coder’s Terraform flows.
- You want to connect specialized or legacy systems to your Coder deployment.
- You are migrating incrementally to Coder and need hybrid support.
- You need finer control over how and where agents run, while still benefiting from Coder’s workspace experience.

## How to use it?

You can create and manage external workspaces using either the **CLI** or the **UI**.

<div class="tabs">

## CLI

1. **Create an external workspace**

   ```bash
   coder external-workspaces create hello-world \
     --template=externally-managed-workspace -y
   ```

   - Validates that the template includes a `coder_external_agent` resource.
   - Once created, the workspace is registered in Coder but marked as requiring an external agent.

2. **List external workspaces**

   ```bash
   coder external-workspaces list
   ```

   Example output:

   ```bash
   WORKSPACE        TEMPLATE                     STATUS   HEALTHY  LAST BUILT  CURRENT VERSION  OUTDATED
   hello-world      externally-managed-workspace Started  true     15m         happy_mendel9    false
   ```

3. **Retrieve agent connection instructions**

   Use this command to query the script you must run on the external machine:

   ```bash
   coder external-workspaces agent-instructions hello-world
   ```

   Example:

   ```bash
   Please run the following command to attach external agent to the workspace hello-world:

   curl -fsSL "https://<DEPLOYMENT_URL>/api/v2/init-script/linux/amd64" | CODER_AGENT_TOKEN="<token>" sh
   ```

   You can also output JSON for automation:

   ```bash
   coder external-workspaces agent-instructions hello-world --output=json
   ```

   ```json
   {
     "workspace_name": "hello-world",
     "agent_name": "main",
     "auth_type": "token",
     "auth_token": "<token>",
     "init_script": "curl -fsSL \"https://<DEPLOYMENT_URL>/api/v2/init-script/linux/arm64\" | CODER_AGENT_TOKEN=\"<token>\" sh"
   }
   ```

## UI

1. Import the external workspace template (see prerequisites).
2. In the Coder UI, go to **Workspaces → New workspace** and select the imported template.
3. Once the workspace is created, Coder will display **connection details** with the command users need to run on the external machine to start the agent.
4. The workspace will appear in the dashboard, but with the following differences:
   - **Start**, **Stop**, and **Restart** actions are disabled.
   - Users are provided with instructions for launching the agent manually on the external machine.

![External Workspace View](../../../images/admin/templates/external-workspace.png)

</div>

---

# Extending Templates

Source: https://coder.com/docs/admin/templates/extending-templates

# Extending templates

There are a variety of Coder-native features to extend the configuration of your
development environments. Many of the following features are defined in your
templates using the
[Coder Terraform provider](https://registry.terraform.io/providers/coder/coder/latest/docs).
The provider docs will provide code examples for usage; alternatively, you can
view our
[example templates](https://github.com/coder/coder/tree/main/examples/templates)
to get started.

## Workspace agents

For users to connect to a workspace, the template must include a
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent).
The associated agent will facilitate
[workspace connections](../../../user-guides/workspace-access/index.md) via SSH,
port forwarding, and IDEs. The agent may also display real-time
[workspace metadata](./agent-metadata.md) like resource usage.

```tf
resource "coder_agent" "dev" {
  os   = "linux"
  arch = "amd64"
  dir  = "/workspace"
  display_apps {
    vscode = true
  }
}
```

You can also leverage [resource metadata](./resource-metadata.md) to display
static resource information from your template.

Templates must include some computational resource to start the agent. All
processes on the workspace are then spawned from the agent. It also provides all
information displayed in the dashboard's workspace view.

![A healthy workspace agent](../../../images/templates/healthy-workspace-agent.png)

Multiple agents may be used in a single template or even a single resource. Each
agent may have its own apps, startup script, and metadata. This can be used to
associate multiple containers or VMs with a workspace.

## Resource persistence

The resources you define in a template may be _ephemeral_ or _persistent_.
Persistent resources stay provisioned when workspaces are stopped, where as
ephemeral resources are destroyed and recreated on restart. All resources are
destroyed when a workspace is deleted.

You can read more about how resource behavior and workspace state in the [workspace lifecycle documentation](../../../user-guides/workspace-lifecycle.md).

Template resources follow the
[behavior of Terraform resources](https://developer.hashicorp.com/terraform/language/resources/behavior#how-terraform-applies-a-configuration)
and can be further configured  using the
[lifecycle argument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle).

A common configuration is a template whose only persistent resource is the home
directory. This allows the developer to retain their work while ensuring the
rest of their environment is consistently up-to-date on each workspace restart.

When a workspace is deleted, the Coder server essentially runs a
[terraform destroy](https://www.terraform.io/cli/commands/destroy) to remove all
resources associated with the workspace.

> [!TIP]
> Terraform's
> [prevent-destroy](https://www.terraform.io/language/meta-arguments/lifecycle#prevent_destroy)
> and
> [ignore-changes](https://www.terraform.io/language/meta-arguments/lifecycle#ignore_changes)
> meta-arguments can be used to prevent accidental data loss.

## Coder apps

Additional IDEs, documentation, or services can be associated to your workspace
using the
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
resource.

![Coder Apps in the dashboard](../../../images/admin/templates/coder-apps-ui.png)

Note that some apps are associated to the agent by default as
[`display_apps`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#nested-schema-for-display_apps)
and can be hidden directly in the
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent)
resource. You can arrange the display orientation of Coder apps in your template
using [resource ordering](./resource-ordering.md).

### Coder app examples

<div class="tabs">

You can use these examples to add new Coder apps:

## code-server

```hcl
resource "coder_app" "code-server" {
  agent_id     = coder_agent.main.id
  slug         = "code-server"
  display_name = "code-server"
  url          = "http://localhost:13337/?folder=/home/${local.username}"
  icon         = "/icon/code.svg"
  subdomain    = false
  share        = "owner"
}
```

## Filebrowser

```hcl
resource "coder_app" "filebrowser" {
  agent_id     = coder_agent.main.id
  display_name = "file browser"
  slug         = "filebrowser"
  url          = "http://localhost:13339"
  icon         = "/icon/database.svg"
  subdomain    = true
  share        = "owner"
}
```

## Zed

```hcl
resource "coder_app" "zed" {
    agent_id = coder_agent.main.id
    slug          = "slug"
    display_name  = "Zed"
    external = true
    url      = "zed://ssh/coder.${data.coder_workspace.me.name}"
    icon     = "/icon/zed.svg"
}
```

</div>

Check out our [module registry](https://registry.coder.com/modules) for
additional Coder apps from the team and our OSS community.

## Environment variables

Use the
[`coder_env`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/env)
resource to inject environment variables into workspace agents. Multiple
resources can target the same variable using
[merge strategies](./environment-variables.md) like `append` and `prepend`,
which is useful for building up `PATH`-style variables across modules.

See [Environment variables](./environment-variables.md) for details.

## Running scripts on workspace lifecycle

The
[`coder_script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script)
resource runs scripts during workspace lifecycle events like startup, stop, or
on a scheduled basis. It provides more control than the deprecated
`startup_script` field in `coder_agent`.

### When to use coder_script

- **Initialization tasks**: Install dependencies, clone repositories, configure
  services
- **Cleanup tasks**: Stop services gracefully on workspace stop
- **Scheduled maintenance**: Run periodic tasks via cron schedules
- **Blocking startup**: Wait for critical services before allowing user login

### Basic example

```tf
resource "coder_script" "install_dependencies" {
  agent_id           = coder_agent.main.id
  display_name       = "Install Dependencies"
  icon               = "/icon/package.svg"
  script             = <<-EOF
    #!/bin/sh
    set -e
    apt-get update
    apt-get install -y git curl
  EOF
  run_on_start       = true
  start_blocks_login = true
}
```

### Key features

- **Lifecycle control**: Run on start (`run_on_start`), stop (`run_on_stop`),
  or cron schedule (`cron`)
- **Login blocking**: Use `start_blocks_login = true` to ensure critical setup
  completes before user access
- **Timeouts**: Configure `timeout` for long-running scripts
- **Custom icons**: Display meaningful icons with the `icon` parameter
- **Log capture**: Script output is automatically captured and visible in the
  workspace UI

### Advanced patterns

Many [Coder modules](https://registry.coder.com/modules) use `coder_script`
internally. For example:

- [`git-clone`](https://registry.coder.com/modules/coder/git-clone): Clones
  repositories on startup
- [`dotfiles`](https://registry.coder.com/modules/coder/dotfiles): Applies user
  dotfiles
- [`code-server`](https://registry.coder.com/modules/coder/code-server):
  Installs and configures code-server (VS Code in the browser)

You can also reference external script files:

```tf
resource "coder_script" "init_docker" {
  agent_id     = coder_agent.main.id
  display_name = "Initialize Docker"
  script       = file("${path.module}/scripts/init-docker.sh")
  run_on_start = true
}
```

See the
[Coder Terraform provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script)
for complete reference.

<children></children>

---

# Agent Metadata

Source: https://coder.com/docs/admin/templates/extending-templates/agent-metadata

# Agent metadata

![agent-metadata](../../../images/admin/templates/agent-metadata-ui.png)

You can show live operational metrics to workspace users with agent metadata. It
is the dynamic complement of [resource metadata](./resource-metadata.md).

You specify agent metadata in the
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent).

## Examples

All of these examples use
[heredoc strings](https://developer.hashicorp.com/terraform/language/expressions/strings#heredoc-strings)
for the script declaration. With heredoc strings, you can script without messy
escape codes, just as if you were working in your terminal.

Some of the examples use the [`coder stat`](../../../reference/cli/stat.md)
command. This is useful for determining CPU and memory usage of the VM or
container that the workspace is running in, which is more accurate than resource
usage about the workspace's host.

Here's a standard set of metadata snippets for Linux agents:

```tf
resource "coder_agent" "main" {
  os             = "linux"
  ...
  metadata {
    display_name = "CPU Usage"
    key  = "cpu"
    # Uses the coder stat command to get container CPU usage.
    script = "coder stat cpu"
    interval = 1
    timeout = 1
  }

  metadata {
    display_name = "Memory Usage"
    key  = "mem"
    # Uses the coder stat command to get container memory usage in GiB.
    script = "coder stat mem --prefix Gi"
    interval = 1
    timeout = 1
  }

  metadata {
    display_name = "CPU Usage (Host)"
    key  = "cpu_host"
    # calculates CPU usage by summing the "us", "sy" and "id" columns of
    # top.
    script = <<EOT
    top -bn1 | awk 'FNR==3 {printf "%2.0f%%", $2+$3+$4}'
    EOT
    interval = 1
    timeout = 1
  }

    metadata {
    display_name = "Memory Usage (Host)"
    key  = "mem_host"
    script = <<EOT
    free | awk '/^Mem/ { printf("%.0f%%", $4/$2 * 100.0) }'
    EOT
    interval = 1
    timeout = 1
  }

  metadata {
    display_name = "Disk Usage"
    key  = "disk"
    script = "df -h | awk '$6 ~ /^\\/$/ { print $5 }'"
    interval = 1
    timeout = 1
  }

  metadata {
    display_name = "Load Average"
    key  = "load"
    script = <<EOT
        awk '{print $1,$2,$3}' /proc/loadavg
    EOT
    interval = 1
    timeout = 1
  }
}
```

## Useful utilities

You can also show agent metadata for information about the workspace's host.

[top](https://manpages.ubuntu.com/manpages/jammy/en/man1/top.1.html) is
available in most Linux distributions and provides virtual memory, CPU and IO
statistics. Running `top` produces output that looks like:

```text
%Cpu(s): 65.8 us,  4.4 sy,  0.0 ni, 29.3 id,  0.3 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :  16009.0 total,    493.7 free,   4624.8 used,  10890.5 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  11021.3 avail Mem
```

[vmstat](https://manpages.ubuntu.com/manpages/jammy/en/man8/vmstat.8.html) is
available in most Linux distributions and provides virtual memory, CPU and IO
statistics. Running `vmstat` produces output that looks like:

```text
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
0  0  19580 4781680 12133692 217646944    0    2     4    32    1    0  1  1 98  0  0
```

[dstat](https://manpages.ubuntu.com/manpages/jammy/man1/dstat.1.html) is
considerably more parseable than `vmstat` but often not included in base images.
It is easily installed by most package managers under the name `dstat`. The
output of running `dstat 1 1` looks like:

```text
--total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read  writ| recv  send|  in   out | int   csw
1   1  98   0   0|3422k   25M|   0     0 | 153k  904k| 123k  174k
```

## Managing the database load

Agent metadata can generate a significant write load and overwhelm your Coder
database if you're not careful. The approximate writes per second can be
calculated using the formula:

```text
(metadata_count * num_running_agents * 2) / metadata_avg_interval
```

For example, let's say you have

- 10 running agents
- each with 6 metadata snippets
- with an average interval of 4 seconds

You can expect `(10 * 6 * 2) / 4`, or 30 writes per second.

One of the writes is to the `UNLOGGED` `workspace_agent_metadata` table and the
other to the `NOTIFY` query that enables live stats streaming in the UI.

## Next Steps

- [Resource metadata](./resource-metadata.md)
- [Parameters](./parameters.md)

---

# Build Parameters

Source: https://coder.com/docs/admin/templates/extending-templates/parameters

# Parameters

A template can prompt the user for additional information when creating
workspaces with
[_parameters_](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter).

![Parameters in Create Workspace screen](../../../images/parameters.png)

The user can set parameters in the dashboard UI and CLI.

You'll likely want to hardcode certain template properties for workspaces, such
as security group. But you can let developers specify other properties with
parameters like instance size, geographical location, repository URL, etc.

This example lets a developer choose a Docker host for the workspace:

```tf
data "coder_parameter" "docker_host" {
  name        = "Region"
  description = "Which region would you like to deploy to?"
  icon        = "/emojis/1f30f.png"
  type        = "string"
  default     = "tcp://100.94.74.63:2375"

  option {
    name = "Pittsburgh, USA"
    value = "tcp://100.94.74.63:2375"
    icon = "/emojis/1f1fa-1f1f8.png"
  }

  option {
    name = "Helsinki, Finland"
    value = "tcp://100.117.102.81:2375"
    icon = "/emojis/1f1eb-1f1ee.png"
  }

  option {
    name = "Sydney, Australia"
    value = "tcp://100.127.2.1:2375"
    icon = "/emojis/1f1e6-1f1f9.png"
  }
}
```

From there, a template can refer to a parameter's value:

```tf
provider "docker" {
  host = data.coder_parameter.docker_host.value
}
```

## Types

A Coder parameter can have one of these types:

- `string`
- `bool`
- `number`
- `list(string)`

To specify a default value for a parameter with the `list(string)` type, use a
JSON array and the Terraform
[jsonencode](https://developer.hashicorp.com/terraform/language/functions/jsonencode)
function. For example:

```tf
data "coder_parameter" "security_groups" {
  name        = "Security groups"
  icon        = "/icon/aws.png"
  type        = "list(string)"
  description = "Select appropriate security groups."
  mutable     = true
  default = jsonencode([
    "Web Server Security Group",
    "Database Security Group",
    "Backend Security Group"
  ])
}
```

> [!NOTE]
> Overriding a `list(string)` on the CLI is tricky because:
>
> - `--parameter "parameter_name=parameter_value"` is parsed as CSV.
> - `parameter_value` is parsed as JSON.
>
> So, to properly specify a `list(string)` with the `--parameter` CLI argument,
> you will need to take care of both CSV quoting and shell quoting.
>
> For the above example, to override the default values of the `security_groups`
> parameter, you will need to pass the following argument to `coder create`:
>
> ```shell
> --parameter "\"security_groups=[\"\"DevOps Security Group\"\",\"\"Backend Security Group\"\"]\""
> ```
>
> Alternatively, you can use `--rich-parameter-file` to work around the above
> issues. This allows you to specify parameters as YAML. An equivalent parameter
> file for the above `--parameter` is provided below:
>
> ```yaml
> security_groups:
>   - DevOps Security Group
>   - Backend Security Group
> ```

## Options

A `string` parameter can provide a set of options to limit the user's choices:

```tf
data "coder_parameter" "docker_host" {
  name        = "Region"
  description = "Which region would you like to deploy to?"
  type        = "string"
  default     = "tcp://100.94.74.63:2375"

  option {
    name = "Pittsburgh, USA"
    value = "tcp://100.94.74.63:2375"
    icon = "/emojis/1f1fa-1f1f8.png"
  }

  option {
    name = "Helsinki, Finland"
    value = "tcp://100.117.102.81:2375"
    icon = "/emojis/1f1eb-1f1ee.png"
  }

  option {
    name = "Sydney, Australia"
    value = "tcp://100.127.2.1:2375"
    icon = "/emojis/1f1e6-1f1f9.png"
  }
}
```

### Incompatibility in Parameter Options for Workspace Builds

When creating Coder templates, authors have the flexibility to modify parameter
options associated with rich parameters. Such modifications can involve adding,
substituting, or removing a parameter option. It's important to note that making
these changes can lead to discrepancies in parameter values utilized by ongoing
workspace builds.

Consequently, workspace users will be prompted to select the new value from a
pop-up window or by using the command-line interface. While this additional
interactive step might seem like an interruption, it serves a crucial purpose.
It prevents workspace users from becoming trapped with outdated template
versions, ensuring they can smoothly update their workspace without any
hindrances.

Example:

- Bob creates a workspace using the `python-dev` template. This template has a
  parameter `image_tag`, and Bob selects `1.12`.
- Later, the template author Alice is notified of a critical vulnerability in a
  package installed in the `python-dev` template, which affects the image tag
  `1.12`.
- Alice remediates this vulnerability, and pushes an updated template version
  that replaces option `1.12` with `1.13` for the `image_tag` parameter. She
  then notifies all users of that template to update their workspace
  immediately.
- Bob saves their work, and selects the `Update` option in the UI. As their
  workspace uses the now-invalid option `1.12`, for the `image_tag` parameter,
  they are prompted to select a new value for `image_tag`.

## Required and optional parameters

A parameter is _required_ if it doesn't have the `default` property. The user
**must** provide a value to this parameter before creating a workspace:

```tf
data "coder_parameter" "account_name" {
  name        = "Account name"
  description = "Cloud account name"
  mutable     = true
}
```

If a parameter contains the `default` property, Coder will use this value if the
user does not specify any:

```tf
data "coder_parameter" "base_image" {
  name        = "Base image"
  description = "Base machine image to download"
  default     = "ubuntu:latest"
}
```

Admins can also set the `default` property to an empty value so that the
parameter field can remain empty:

```tf
data "coder_parameter" "dotfiles_url" {
  name        = "dotfiles URL"
  description = "Git repository with dotfiles"
  mutable     = true
  default     = ""
}
```

## Mutability

Immutable parameters can only be set in these situations:

- Creating a workspace for the first time.
- Updating a workspace to a new template version.
  This sets the initial value for required parameters.

The idea is to prevent users from modifying fragile or persistent workspace
resources like volumes, regions, and so on.

Example:

```tf
data "coder_parameter" "region" {
  name        = "Region"
  description = "Region where the workspace is hosted"
  mutable     = false
  default     = "us-east-1"
}
```

If a required parameter is empty or if the workspace creation page detects an incompatibility between selected
parameters, the **Create workspace** button is disabled until the issues are resolved.

## Ephemeral parameters

Ephemeral parameters are introduced to users in order to model specific
behaviors in a Coder workspace, such as reverting to a previous image, restoring
from a volume snapshot, or building a project without using cache. These
parameters are only settable when starting, updating, or restarting a workspace
and do not persist after the workspace is stopped.

Since these parameters are ephemeral in nature, subsequent builds proceed in the
standard manner:

```tf
data "coder_parameter" "force_rebuild" {
  name         = "force_rebuild"
  type         = "bool"
  description  = "Rebuild the Docker image rather than use the cached one."
  mutable      = true
  default      = false
  ephemeral    = true
}
```

## Validating parameters

Coder supports parameters with multiple validation modes: min, max,
monotonic numbers, and regular expressions.

### Number

You can limit a `number` parameter to `min` and `max` boundaries.

You can also specify its monotonicity as `increasing` or `decreasing` to verify
the current and new values. Use the `monotonic` attribute for resources that
can't be shrunk or grown without implications, like disk volume size.

```tf
data "coder_parameter" "instances" {
  name        = "Instances"
  type        = "number"
  description = "Number of compute instances"
  validation {
    min       = 1
    max       = 8
    monotonic = "increasing"
  }
}
```

It is possible to override the default `error` message for a `number` parameter,
along with its associated `min` and/or `max` properties. The following message
placeholders are available `{min}`, `{max}`, and `{value}`.

```tf
data "coder_parameter" "instances" {
  name        = "Instances"
  type        = "number"
  description = "Number of compute instances"
  validation {
    min       = 1
    max       = 4
    error     = "Sorry, we can't provision too many instances - maximum limit: {max}, wanted: {value}."
  }
}
```

> [!NOTE]
> As of
> [`terraform-provider-coder` v0.19.0](https://registry.terraform.io/providers/coder/coder/0.19.0/docs),
> `options` can be specified in `number` parameters; this also works with
> validations such as `monotonic`.

### String

You can validate a `string` parameter to match a regular expression. The `regex`
property requires a corresponding `error` property.

```tf
data "coder_parameter" "project_id" {
  name        = "Project ID"
  description = "Alpha-numeric project ID"
  validation {
    regex = "^[a-z0-9]+$"
    error = "Unfortunately, this isn't a valid project ID"
  }
}
```

## Workspace presets

Workspace presets allow you to configure commonly used combinations of parameters
into a single option, which makes it easier for developers to pick one that fits
their needs.

![Template with options in the preset dropdown](../../../images/admin/templates/extend-templates/template-preset-dropdown.png)

Use the
[`coder_workspace_preset`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_preset)
data source to define the preset parameters. After you save the template file,
the presets will be available for all new workspace deployments.

### Optional preset fields

In addition to the required `name` and `parameters` fields, you can enhance your
workspace presets with optional `description` and `icon` fields:

- **description**: A helpful text description that provides additional context
  about the preset. This helps users understand what the preset is for and when
  to use it.
- **icon**: A visual icon displayed alongside the preset name in the UI. Use
  emoji icons with the format `/emojis/{code}.png` (e.g.,
  `/emojis/1f1fa-1f1f8.png` for the US flag emoji 🇺🇸).

For a complete list of all available fields, see the
[Terraform provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_preset#schema).

<details><summary>Expand for an example</summary>

```tf
data "coder_workspace_preset" "goland-gpu" {
  name        = "GoLand with GPU"
  description = "Development workspace with GPU acceleration for GoLand IDE"
  icon        = "/emojis/1f680.png"
  parameters = {
    "machine_type"  = "n1-standard-1"
    "attach_gpu"    = "true"
    "gcp_region"    = "europe-west4-c"
    "jetbrains_ide" = "GO"
  }
}

data "coder_workspace_preset" "pittsburgh" {
  name        = "Pittsburgh"
  description = "Development workspace hosted in United States"
  icon        = "/emojis/1f1fa-1f1f8.png"
  parameters = {
    "region"       = "us-pittsburgh"
    "machine_type" = "n1-standard-2"
  }
}

data "coder_parameter" "machine_type" {
  name          = "machine_type"
  display_name  = "Machine Type"
  type          = "string"
  default       = "n1-standard-2"
}

data "coder_parameter" "attach_gpu" {
  name          = "attach_gpu"
  display_name  = "Attach GPU?"
  type          = "bool"
  default       = "false"
}

data "coder_parameter" "gcp_region" {
  name          = "gcp_region"
  display_name  = "GCP Region"
  type          = "string"
  default       = "us-central1-a"
}

data "coder_parameter" "jetbrains_ide" {
  name          = "jetbrains_ide"
  display_name  = "JetBrains IDE"
  type          = "string"
  default       = "IU"
}

data "coder_parameter" "region" {
  name          = "region"
  display_name  = "Region"
  type          = "string"
  default       = "us-east-1"
}
```

</details>

## Create Autofill

When the template doesn't specify default values, Coder may still autofill
parameters in one of two ways:

- Coder will look for URL query parameters with form `param.<name>=<value>`.

  This feature enables platform teams to create pre-filled template creation links.

- Coder can populate recently used parameter key-value pairs for the user.
  This feature helps reduce repetition when filling common parameters such as
  `dotfiles_url` or `region`.

  To enable this feature, you need to set the `auto-fill-parameters` experiment flag:

  ```shell
  coder server --experiments=auto-fill-parameters
  ```

  Or set the [environment variable](../../setup/index.md), `CODER_EXPERIMENTS=auto-fill-parameters`

## Dynamic Parameters

Coder v2.24.0 introduces [Dynamic Parameters](./dynamic-parameters.md) to extend the existing parameter system with
conditional form controls, enriched input types, and user identity awareness.
This feature allows template authors to create interactive workspace creation forms, meaning more environment
customization and fewer templates to maintain.

You can read more in the [Dynamic Parameters documentation](./dynamic-parameters.md) and try it out in the
[Parameters Playground](https://playground.coder.app/parameters).

---

# Dynamic Parameters

Source: https://coder.com/docs/admin/templates/extending-templates/dynamic-parameters

# Dynamic Parameters

Coder v2.24.0 introduces Dynamic Parameters to extend Coder [parameters](./parameters.md) with conditional form controls,
enriched input types, and user identity awareness.
This allows template authors to create interactive workspace creation forms with more environment customization,
and that means fewer templates to maintain.

![Dynamic Parameters in Action](../../../images/admin/templates/extend-templates/dyn-params/dynamic-parameters-in-action.gif)

All parameters are parsed from Terraform, so your workspace creation forms live in the same location as your provisioning code.
You can use all the native Terraform functions and conditionality to create a self-service tooling catalog for every template.

Administrators can use Dynamic Parameters to:

- Create parameters which respond to the inputs of others.
- Only show parameters when other input criteria are met.
- Only show select parameters to target Coder roles or groups.

You can try the Dynamic Parameter syntax and any of the code examples below in the
[Parameters Playground](https://playground.coder.app/parameters).
You should experiment with parameters in the playground before you upgrade live templates.

## When You Should Upgrade to Dynamic Parameters

While Dynamic parameters introduce a variety of new powerful tools, all functionality is backwards compatible with
existing coder templates.
When you opt-in to the new experience, no functional changes will be applied to your production parameters.

Some reasons Coder template admins should try Dynamic Parameters:

- You maintain or support many templates for teams with unique expectations or use cases.
- You want to selectively expose privileged workspace options to admins, power users, or personas.
- You want to make the workspace creation flow more ergonomic for developers.

Dynamic Parameters help you reduce template duplication by setting the conditions for which users should see specific parameters.
They reduce the potential complexity of user-facing configuration by allowing administrators to organize a long list of options into interactive, branching paths for workspace customization.
They allow you to set resource guardrails by referencing Coder identity in the `coder_workspace_owner` data source.

## How to enable Dynamic Parameters

In Coder v2.25.0 and later, Dynamic Parameters are automatically enabled for new templates. For Coder v2.24 and below, you can opt-in to Dynamic Parameters for individual existing templates via template settings.

1. Go to your template's settings and enable the **Enable dynamic parameters for workspace creation** option.

   ![Enable dynamic parameters for workspace creation](../../../images/admin/templates/extend-templates/dyn-params/dynamic-parameters-ga-settings.png)

1. Update your template to use version >=2.4.0 of the Coder provider with the following Terraform block.

   ```terraform
   terraform {
     required_providers {
       coder = {
         source = "coder/coder"
         version = ">=2.4.0"
       }
     }
   }
   ```

1. This enables Dynamic Parameters in the template.
   Add some [conditional parameters](#available-form-input-types).

   Note that these new features must be declared in your Terraform to start leveraging Dynamic Parameters.

1. Save and publish the template.

1. Users should see the updated workspace creation form.

Dynamic Parameters features are backwards compatible, so all existing templates may be upgraded in-place.
If you decide to revert to the legacy flow later, disable Dynamic Parameters in the template's settings.

## Features and Capabilities

Dynamic Parameters introduces three primary enhancements to the standard parameter system:

- **Conditional Parameters**

  - Parameters can respond to changes in other parameters
  - Show or hide parameters based on other selections
  - Modify validation rules conditionally
  - Create branching paths in workspace creation forms

- **Reference User Properties**

  - Read user data at build time from [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_owner)
  - Conditionally hide parameters based on user's role
  - Change parameter options based on user groups
  - Reference user name, groups, and roles in parameter text

- **Additional Form Inputs**

  - Searchable dropdown lists for easier selection
  - Multi-select options for choosing multiple items
  - Secret text inputs for sensitive information
  - Slider input for disk size, model temperature
  - Disabled parameters to display immutable data

> [!IMPORTANT]
> Dynamic Parameters does not support external data fetching via HTTP endpoints at workspace build time.
>
> External fetching would introduce unpredictability in workspace builds after publishing a template.
> Instead, we recommend that template administrators pull in any required data for a workspace build as a
> [locals](https://developer.hashicorp.com/terraform/tutorials/configuration-language/locals) or JSON file,
> then reference that data in Terraform.
>
> If you have a use case for external data fetching, please file an issue or create a discussion in the
> [Coder GitHub repository](https://github.com/coder/coder).

## Available Form Input Types

Dynamic Parameters supports a variety of form types to create rich, interactive user experiences.

![Old vs New Parameters](../../../images/admin/templates/extend-templates/dyn-params/dynamic-params-compare.png)

Different parameter types support different form types.
You can specify the form type using the
[`form_type`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter#form_type-1) attribute.

The **Options** column in the table below indicates whether the form type supports options (**Yes**) or doesn't support them (**No**).
When supported, you can specify options using one or more `option` blocks in your parameter definition,
where each option has a `name` (displayed to the user) and a `value` (used in your template logic).

| Form Type      | Parameter Types                            | Options | Notes                                                                                                                  |
|----------------|--------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------|
| `radio`        | `string`, `number`, `bool`, `list(string)` | Yes     | Radio buttons for selecting a single option with all choices visible at once. </br>The classic parameter option.       |
| `dropdown`     | `string`, `number`                         | Yes     | Choose a single option from a searchable dropdown list. </br>Default for `string` or `number` parameters with options. |
| `multi-select` | `list(string)`                             | Yes     | Select multiple items from a list with checkboxes.                                                                     |
| `tag-select`   | `list(string)`                             | No      | Default for `list(string)` parameters without options.                                                                 |
| `input`        | `string`, `number`                         | No      | Standard single-line text input field. </br>Default for `string/number` parameters without options.                    |
| `textarea`     | `string`                                   | No      | Multi-line text input field for longer content.                                                                        |
| `slider`       | `number`                                   | No      | Slider selection with min/max validation for numeric values.                                                           |
| `checkbox`     | `bool`                                     | No      | A single checkbox for boolean parameters. </br>Default for boolean parameters.                                         |

### Available Styling Options

The `coder_parameter` resource supports an additional `styling` attribute for special cosmetic changes that can be used
to further customize the workspace creation form.

This can be used for:

- Masking private inputs
- Marking inputs as read-only
- Setting placeholder text

Note that the `styling` attribute should not be used as a governance tool, since it only changes how the interactive
form is displayed.
Users can avoid restrictions like `disabled` if they create a workspace via the CLI.

This attribute accepts JSON like so:

```terraform
data "coder_parameter" "styled_parameter" {
  ...
  styling = jsonencode({
    disabled = true
  })
}
```

Not all styling attributes are supported by all form types, use the reference below for syntax:

| Styling Option | Compatible parameter types | Compatible form types | Notes                                                                               |
|----------------|----------------------------|-----------------------|-------------------------------------------------------------------------------------|
| `disabled`     | All parameter types        | All form types        | Disables the form control when `true`.                                              |
| `placeholder`  | `string`                   | `input`, `textarea`   | Sets placeholder text. </br>This is overwritten by user entry.                      |
| `mask_input`   | `string`, `number`         | `input`, `textarea`   | Masks inputs as asterisks (`*`). Used to cosmetically hide token or password entry. |

## Use Case Examples

### New Form Types

The following examples show some basic usage of the
[`form_type`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter#form_type-1)
attribute [explained above](#available-form-input-types).
These are used to change the input style of form controls in the create workspace form.

<div class="tabs">

### Dropdowns

Single-select parameters with options can use the `form_type="dropdown"` attribute for better organization.

[Try dropdown lists on the Parameter Playground](https://playground.coder.app/parameters/kgNBpjnz7x)

```terraform
locals {
  ides = [
    "VS Code",
    "JetBrains IntelliJ",
    "PyCharm",
    "GoLand",
    "WebStorm",
    "Vim",
    "Emacs",
    "Neovim"
  ]
}

data "coder_parameter" "ides_dropdown" {
  name = "ides_dropdown"
  display_name = "Select your IDEs"
  type = "string"

  form_type = "dropdown"

  dynamic "option" {
    for_each = local.ides
    content {
      name  = option.value
      value = option.value
    }
  }
}
```

### Text Area

The large text entry option can be used to enter long strings like AI prompts, scripts, or natural language.

[Try textarea parameters on the Parameter Playground](https://playground.coder.app/parameters/RCAHA1Oi1_)

```terraform

data "coder_parameter" "text_area" {
  name = "text_area"
  description  = "Enter multi-line text."
  mutable      = true
  display_name = "Textarea"

  form_type = "textarea"
  type      = "string"

  default = <<-EOT
    This is an example of multi-line text entry.

    The 'textarea' form_type is useful for
    - AI prompts
    - Scripts
    - Read-only info (try the 'disabled' styling option)
  EOT
}

```

### Multi-select

Multi-select parameters allow users to select one or many options from a single list of options.
For example, adding multiple IDEs with a single parameter.

[Try multi-select parameters on the Parameter Playground](https://playground.coder.app/parameters/XogX54JV_f)

```terraform
locals {
  ides = [
    "VS Code", "JetBrains IntelliJ",
    "GoLand", "WebStorm",
    "Vim", "Emacs",
    "Neovim", "PyCharm",
    "Databricks", "Jupyter Notebook",
  ]
}

data "coder_parameter" "ide_selector" {
  name = "ide_selector"
  description  = "Choose any IDEs for your workspace."
  mutable      = true
  display_name = "Select multiple IDEs"


  # Allows users to select multiple IDEs from the list.
  form_type = "multi-select"
  type      = "list(string)"


  dynamic "option" {
    for_each = local.ides
    content {
      name  = option.value
      value = option.value
    }
  }
}
```

### Radio

Radio buttons are used to select a single option with high visibility.
This is the original styling for list parameters.

[Try radio parameters on the Parameter Playground](https://playground.coder.app/parameters/3OMDp5ANZI).

```terraform
data "coder_parameter" "environment" {
  name         = "environment"
  display_name = "Environment"
  description  = "An example of environment listing with the radio form type."
  type         = "string"
  default      = "dev"

  form_type    = "radio"

  option {
    name  = "Development"
    value = "dev"
  }
  option {
    name  = "Experimental"
    value = "exp"
  }
  option {
    name  = "Staging"
    value = "staging"
  }
  option {
    name  = "Production"
    value = "prod"
  }
}
```

### Checkboxes

A single checkbox for boolean values.
This can be used for a TOS confirmation or to expose advanced options.

[Try checkbox parameters on the Parameters Playground](https://playground.coder.app/parameters/ycWuQJk2Py).

```terraform
data "coder_parameter" "enable_gpu" {
  name         = "enable_gpu"
  display_name = "Enable GPU"
  type         = "bool"
  form_type    = "checkbox" # This is the default for boolean parameters
  default      = false
}
```

### Slider

Sliders can be used for configuration on a linear scale, like resource allocation.
The `validation` block is used to constrain (or clamp) the minimum and maximum values for the parameter.

[Try slider parameters on the Parameters Playground](https://playground.coder.app/parameters/RsBNcWVvfm).

```terraform
data "coder_parameter" "cpu_cores" {
  name         = "cpu_cores"
  display_name = "CPU Cores"
  type         = "number"
  form_type    = "slider"
  default      = 2
  validation {
    min = 1
    max = 8
  }
}
```

### Masked Input

Masked input parameters can be used to visually hide secret values in the workspace creation form.
Note that this does not secure information on the backend and is purely cosmetic.

[Try private parameters on the Parameters Playground](https://playground.coder.app/parameters/wmiP7FM3Za).

Note: This text may not be properly hidden in the Playground.
The `mask_input` styling attribute is supported in v2.24.0 and later.

```terraform
data "coder_parameter" "private_api_key" {
  name         = "private_api_key"
  display_name = "Your super secret API key"
  type         = "string"

  form_type = "input" # | "textarea"

  # Will render as "**********"
  default = "privatekey"

  styling = jsonencode({
    mask_input = true
  })
}
```

</div>

### Conditional Parameters

Using native Terraform syntax and parameter attributes like `count`, we can allow some parameters to react to user inputs.

This means:

- Hiding parameters unless activated
- Conditionally setting default values
- Changing available options based on other parameter inputs

Use these in conjunction to build intuitive, reactive forms for workspace creation.

<div class="tabs">

### Hide/Show Options

Use Terraform conditionals and the `count` block to allow a checkbox to expose or hide a subsequent parameter.

[Try conditional parameters on the Parameter Playground](https://playground.coder.app/parameters/xmG5MKEGNM).

```terraform
data "coder_parameter" "show_cpu_cores" {
  name         = "show_cpu_cores"
  display_name = "Toggles next parameter"
  description  = "Select this checkbox to show the CPU cores parameter."
  type         = "bool"
  form_type    = "checkbox"
  default      = false
  order        = 1
}

data "coder_parameter" "cpu_cores" {
  # Only show this parameter if the previous box is selected.
  count = data.coder_parameter.show_cpu_cores.value ? 1 : 0

  name         = "cpu_cores"
  display_name = "CPU Cores"
  type         = "number"
  form_type    = "slider"
  default      = 2
  order        = 2
  validation {
    min = 1
    max = 8
  }
}
```

### Dynamic Defaults

Influence which option is selected by default for one parameter based on the selection of another.
This allows you to suggest an option dynamically without strict enforcement.

[Try dynamic defaults in the Parameter Playground](https://playground.coder.app/parameters/DEi-Bi6DVe).

```terraform
locals {
  ides = [
    "VS Code",
    "IntelliJ", "GoLand",
    "WebStorm", "PyCharm",
    "Databricks", "Jupyter Notebook",
  ]
  mlkit_ides = jsonencode(["Databricks", "PyCharm"])
  core_ides = jsonencode(["VS Code", "GoLand"])
}

data "coder_parameter" "git_repo" {
  name = "git_repo"
  display_name = "Git repo"
  description = "Select a git repo to work on."
  order = 1
  mutable = true
  type = "string"
  form_type = "dropdown"

  option {
    # A Go-heavy repository
    name = "coder/coder"
    value = "coder/coder"
  }

  option {
    # A python-heavy repository
    name = "coder/mlkit"
    value = "coder/mlkit"
  }
}

data "coder_parameter" "ide_selector" {
  # Conditionally expose this parameter
  count = try(data.coder_parameter.git_repo.value, "") != "" ? 1 : 0

  name = "ide_selector"
  description  = "Choose any IDEs for your workspace."
  order        = 2
  mutable      = true

  display_name = "Select IDEs"
  form_type = "multi-select"
  type      = "list(string)"
  default   = try(data.coder_parameter.git_repo.value, "") == "coder/mlkit" ? local.mlkit_ides : local.core_ides


  dynamic "option" {
    for_each = local.ides
    content {
      name  = option.value
      value = option.value
    }
  }
}
```

## Dynamic Validation

A parameter's validation block can leverage inputs from other parameters.

[Try dynamic validation in the Parameter Playground](https://playground.coder.app/parameters/sdbzXxagJ4).

```terraform
data "coder_parameter" "git_repo" {
  name = "git_repo"
  display_name = "Git repo"
  description = "Select a git repo to work on."
  order = 1
  mutable = true
  type = "string"
  form_type = "dropdown"

  option {
    # A Go-heavy repository
    name = "coder/coder"
    value = "coder/coder"
  }

  option {
    # A python-heavy repository
    name = "coder/mlkit"
    value = "coder/mlkit"
  }
}

data "coder_parameter" "cpu_cores" {
  # Only show this parameter if the previous box is selected.
  count = data.coder_parameter.show_cpu_cores.value ? 1 : 0

  name         = "cpu_cores"
  display_name = "CPU Cores"
  type         = "number"
  form_type    = "slider"
  order        = 2

  # Dynamically set default
  default      = try(data.coder_parameter.git_repo.value, "") == "coder/mlkit" ? 12 : 6

  validation {
    min = 1

    # Dynamically set max validation
    max = try(data.coder_parameter.git_repo.value, "") == "coder/mlkit" ? 16 : 8
  }
}
```

<!-- ## Daisy Chaining

You can daisy-chain the conditionals shown here to create a dynamically expanding form.
Note that parameters must be indexed when using the `count` attribute.

[Try daisy-chaining parameters in the Parameter Playground](https://playground.coder.app/parameters/jLUUhoDLIa).

```terraform

locals {
  ides = [
    "VS Code",
    "JetBrains IntelliJ",
    "GoLand",
    "WebStorm",
    "PyCharm",
    "Databricks",
    "Jupyter Notebook",
  ]

  is_ml_repo = data.coder_parameter.git_repo == "coder/mlkit"

  selected = jsondecode(data.coder_parameter.ide_selector[0].value)

  # selected = try(jsondecode(data.coder_parameter.ide_selector[0].value), [])
}

data "coder_parameter" "git_repo" {
  name = "git_repo"
  display_name = "Git repo"
  description = "Select a git repo to work on."
  order = 1
  mutable = true
  type = "string"
  form_type = "dropdown"

  option {
    name = "coder/coder"
    value = "coder/coder"
  }

  option {
    name = "coder/mlkit"
    value = "coder/mlkit"
  }
}

data "coder_parameter" "ide_selector" {
  # Only show this parameter if a git repo has been selected.
  count = try(data.coder_parameter.git_repo.value, "") != "" ? 1 : 0
  name = "ide_selector"
  description  = "Choose any IDEs for your workspace."
  mutable      = true
  display_name = "Select multiple IDEs"
  order = 1
  default = "[]"

  # Allows users to select multiple IDEs from the list.
  form_type = "multi-select"
  type      = "list(string)"

  dynamic "option" {
    for_each = local.ides
    content {
      name  = option.value
      value = option.value
    }
  }
}

data "coder_parameter" "cpu_cores" {
  # Only show this parameter if the IDEs have been selected.
  count = length(local.selected) > 0 ? 1 : 0

  name         = "cpu_cores"
  display_name = "CPU Cores"
  type         = "number"
  form_type    = "slider"
  default      = local.is_ml_repo ? 12 : 6
  order        = 2
  validation {
    min = 1
    max = local.is_ml_repo ? 16 : 8
  }
}
``` -->

</div>

## Identity-Aware Parameters (Premium)

Premium users can leverage our roles and groups to conditionally expose or change parameters based on user identity.
This is helpful for establishing governance policy directly in the workspace creation form,
rather than creating multiple templates to manage RBAC.

User identity is referenced in Terraform by reading the
[`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_owner) data source.

<div class="tabs">

### Role-aware Options

Template administrators often want to expose certain experimental or unstable options only to those with elevated roles.
You can now do this by setting `count` based on a user's group or role, referencing the
[`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_owner)
data source.

[Try out admin-only options in the Playground](https://playground.coder.app/parameters/5Gn9W3hYs7).

```terraform

locals {
  roles = [for r in data.coder_workspace_owner.me.rbac_roles: r.name]
  is_admin = contains(data.coder_workspace_owner.me.groups, "admin")
  has_admin_role = contains(local.roles, "owner")
}

data "coder_workspace_owner" "me" {}

data "coder_parameter" "advanced_settings" {
  # This parameter is only visible when the user is an administrator
  count = local.is_admin ? 1 : 0

  name         = "advanced_settings"
  display_name = "Add an arbitrary script"
  description  = "An advanced configuration option only available to admins."
  type         = "string"
  form_type    = "textarea"
  mutable      = true
  order        = 5

  styling = jsonencode({
    placeholder = <<-EOT
  #!/usr/bin/env bash
  while true; do
    echo "hello world"
    sleep 1
  done
  EOT
  })
}

```

### Group-aware Regions

You can expose regions depending on which group a user belongs to.
This way developers can't accidentally induce low-latency with world-spanning connections.

[Try user-aware regions in the parameter playground](https://playground.coder.app/parameters/tBD-mbZRGm)

```terraform

locals {
  eu_regions = [
    "eu-west-1 (Ireland)",
    "eu-central-1 (Frankfurt)",
    "eu-north-1 (Stockholm)",
    "eu-west-3 (Paris)",
    "eu-south-1 (Milan)"
  ]

  us_regions = [
    "us-east-1 (N. Virginia)",
    "us-west-1 (California)",
    "us-west-2 (Oregon)",
    "us-east-2 (Ohio)",
    "us-central-1 (Iowa)"
  ]

  eu_group_name = "eu-helsinki"
  is_eu_dev = contains(data.coder_workspace_owner.me.groups, local.eu_group_name)
  region_desc_tag = local.is_eu_dev ? "european" : "american"
}

data "coder_parameter" "region" {
  name         = "region"
  display_name = "Select a Region"
  description  = "Select from ${local.region_desc_tag} region options."
  type         = "string"
  form_type    = "dropdown"
  order        = 5
  default      = local.is_eu_dev ? local.eu_regions[0] : local.us_regions[0]

  dynamic "option" {
    for_each = local.is_eu_dev ? local.eu_regions : local.us_regions
    content {
      name        = option.value
      value       = option.value
      description = "Use ${option.value}"
    }
  }
}
```

### Groups As Namespaces

A slightly unorthodox way to leverage this is by filling the selections of a parameter from the user's groups.
Some users associate groups with namespaces, such as Kubernetes, then allow users to target that namespace with a parameter.

[Try groups as options in the Parameter Playground](https://playground.coder.app/parameters/lKbU53nYjl).

```terraform
locals {
  groups = data.coder_workspace_owner.me.groups
}

data "coder_workspace_owner" "me" {}

data "coder_parameter" "your_groups" {
  type         = "string"
  name         = "your_groups"
  display_name = "Your Coder Groups"
  description  = "Select your namespace..."
  default      = "target-${local.groups[0]}"
  mutable      = true
  form_type = "dropdown"

  dynamic "option" {
    # options populated directly from groups
    for_each = local.groups
    content {
      name  = option.value
      # Native terraform be used to decorate output
      value = "target-${option.value}"
    }
  }
}
```

</div>

## Troubleshooting

Dynamic Parameters is now in general availability. We're tracking a list of known issues [here in Github](https://github.com/coder/coder/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20label%3Aparameters) as we continue to polish and improve the workflow.
If you have any issues during upgrade, please file an issue in our
[GitHub repository](https://github.com/coder/coder/issues/new?labels=parameters) with the `parameters` label and include a
[Playground link](https://playground.coder.app/parameters) where applicable.
We appreciate the feedback and look forward to what the community creates with this system!

You can also [search or track the list of known issues](https://github.com/coder/coder/issues?q=is%3Aissue%20state%3Aopen%20label%3Aparameters).

You can share anything you build with Dynamic Parameters in our [Discord](https://coder.com/chat).

### Enabled Dynamic Parameters, but my template looks the same

Ensure that the following version requirements are met:

- `coder/coder`: >= [v2.25.0](https://github.com/coder/coder/releases/tag/v2.25.0)
- `coder/terraform-provider-coder`: >= [v2.5.3](https://github.com/coder/terraform-provider-coder/releases/tag/v2.5.3)

Enabling Dynamic Parameters on an existing template requires administrators to publish a new template version.
This will resolve the necessary template metadata to render the form.

### Reverting to classic parameters

To revert Dynamic Parameters on a template:

1. Prepare your template by removing any conditional logic or user data references in parameters.
1. As a template administrator or owner, go to your template's settings:

   **Templates** > **Your template** > **Settings**

1. Uncheck the **Enable dynamic parameters for workspace creation** option.
1. Create a new template version and publish to the active version.

### Template variables not showing up

Dynamic Parameters are GA as of [v2.25.0](https://github.com/coder/coder/releases/tag/v2.25.0). Template variables are fully supported in Dynamic Parameters.

If you are experiencing issues with template variables, try upgrading to the latest version. Otherwise, please file an issue in our Github.

### Can I use registry modules with Dynamic Parameters?

Yes, registry modules are supported with Dynamic Parameters.

Unless explicitly mentioned, no registry modules require Dynamic Parameters.
Later in 2025, more registry modules will be converted to Dynamic Parameters to improve their UX.

In the meantime, you can safely convert existing templates and build new parameters on top of the functionality provided in the registry.

### "Module not loaded" errors when using Dynamic Parameters

Dynamic Parameters require Terraform modules to be archived and stored in the database. Coder limits module archives to **20MB total** to prevent database bloat. If your template uses modules that exceed this limit, some modules will be unavailable for parameter declarations.

**Symptoms:**

You may see warnings in the provisioner logs:

```text
[API] 2026-01-29 22:00:22.691 [warn]  provisionerd-nixos-0.executor: some (or all) terraform modules were not archived, template will have reduced function  skipped_modules=large:git::https://github.com/coder/large-module.git
```

If encountered, reduce the size of the module by removing unnecessary files.

---

# Prebuilt workspaces

Source: https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces

# Prebuilt workspaces

Prebuilt workspaces (prebuilds) reduce workspace creation time with an automatically-maintained pool of
ready-to-use workspaces for specific parameter presets.

The template administrator defines the prebuilt workspace's parameters and number of instances to keep provisioned.
The desired number of workspaces are then provisioned transparently.
When a developer creates a new workspace that matches the definition, Coder assigns them an existing prebuilt workspace.
This significantly reduces wait times, especially for templates with complex provisioning or lengthy startup procedures.

Prebuilt workspaces are:

- Created and maintained automatically by Coder to match your specified preset configurations.
- Claimed transparently when developers create workspaces.
- Monitored and replaced automatically to maintain your desired pool size.
- Automatically scaled based on time-based schedules to optimize resource usage.

Prebuilt workspaces are a special type of workspace that don't follow the
[regular workspace scheduling features](../../../user-guides/workspace-scheduling.md) like autostart and autostop. Instead, they have their own reconciliation loop that handles prebuild-specific scheduling features such as TTL and prebuild scheduling.

## Relationship to workspace presets

Prebuilt workspaces are tightly integrated with [workspace presets](./parameters.md#workspace-presets):

1. Each prebuilt workspace is associated with a specific template preset.
1. The preset must define all required parameters needed to build the workspace.
1. The preset parameters define the base configuration and are immutable once a prebuilt workspace is provisioned.
1. Parameters that are not defined in the preset can still be customized by users when they claim a workspace.
1. If a user does not select a preset but provides parameters that match one or more presets, Coder will automatically select the most specific matching preset and assign a prebuilt workspace if one is available.

## Prerequisites

- [**Premium license**](../../licensing/index.md)
- **Compatible Terraform provider**: Use `coder/coder` Terraform provider `>= 2.4.1`.

## Enable prebuilt workspaces for template presets

In your template, add a `prebuilds` block within a `coder_workspace_preset` definition to identify the number of prebuilt
instances your Coder deployment should maintain, and optionally configure a `expiration_policy` block to set a TTL
(Time To Live) for unclaimed prebuilt workspaces to ensure stale resources are automatically cleaned up.

   ```hcl
   data "coder_workspace_preset" "goland" {
     name = "GoLand: Large"
     parameters = {
       jetbrains_ide = "GO"
       cpus          = 8
       memory        = 16
     }
     prebuilds {
       instances = 3   # Number of prebuilt workspaces to maintain
       expiration_policy {
          ttl = 86400  # Time (in seconds) after which unclaimed prebuilds are expired (86400 = 1 day)
      }
     }
   }
   ```

After you publish a new template version, Coder will automatically provision and maintain prebuilt workspaces through an
internal reconciliation loop (similar to Kubernetes) to ensure the defined `instances` count are running.

The `expiration_policy` block ensures that any prebuilt workspaces left unclaimed for more than `ttl` seconds is considered
expired and automatically cleaned up.

## Prebuilt workspace lifecycle

Prebuilt workspaces follow a specific lifecycle from creation through eligibility to claiming.

1. After you configure a preset with prebuilds and publish the template, Coder provisions the prebuilt workspace(s).

   1. Coder automatically creates the defined `instances` count of prebuilt workspaces.
   1. Each new prebuilt workspace is initially owned by an unprivileged system pseudo-user named `prebuilds`.
      - The `prebuilds` user belongs to the `Everyone` group (you can add it to additional groups if needed).
   1. Each prebuilt workspace receives a randomly generated name for identification.
   1. The workspace is provisioned like a regular workspace; only its ownership distinguishes it as a prebuilt workspace.

1. Prebuilt workspaces start up and become eligible to be claimed by a developer.

   Before a prebuilt workspace is available to users:

   1. The workspace is provisioned.
   1. The agent starts up and connects to coderd.
   1. The agent starts its bootstrap procedures and completes its startup scripts.
   1. The agent reports `ready` status.

      After the agent reports `ready`, the prebuilt workspace considered eligible to be claimed.

   Prebuilt workspaces that fail during provisioning are retried with a backoff to prevent transient failures.

1. When a developer creates a new workspace, the claiming process occurs:

   1. Developer selects a template and preset that has prebuilt workspaces configured.
   1. If an eligible prebuilt workspace exists, ownership transfers from the `prebuilds` user to the requesting user.
   1. The workspace name changes to the user's requested name.
   1. `terraform apply` is executed using the new ownership details, which may affect the [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace) and
      [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_owner)
      datasources (see [Preventing resource replacement](#preventing-resource-replacement) for further considerations).

   The claiming process is transparent to the developer — the workspace will just be ready faster than usual.

You can view available prebuilt workspaces in the **Workspaces** view in the Coder dashboard:

![A prebuilt workspace in the dashboard](../../../images/admin/templates/extend-templates/prebuilt/prebuilt-workspaces.png)
_Note the search term `owner:prebuilds`._

Unclaimed prebuilt workspaces can be interacted with in the same way as any other workspace.
However, if a Prebuilt workspace is stopped, the reconciliation loop will not destroy it.
This gives template admins the ability to park problematic prebuilt workspaces in a stopped state for further investigation.

### Expiration Policy

Prebuilt workspaces support expiration policies through the `ttl` setting inside the `expiration_policy` block.
This value defines the Time To Live (TTL) of a prebuilt workspace, i.e., the duration in seconds that an unclaimed
prebuilt workspace can remain before it is considered expired and eligible for cleanup.

Expired prebuilt workspaces are removed during the reconciliation loop to avoid stale environments and resource waste.
New prebuilt workspaces are only created to maintain the desired count if needed.

### Scheduling

Prebuilt workspaces support time-based scheduling to scale the number of instances up or down.
This allows you to reduce resource costs during off-hours while maintaining availability during peak usage times.

Configure scheduling by adding a `scheduling` block within your `prebuilds` configuration:

```tf
data "coder_workspace_preset" "goland" {
   name = "GoLand: Large"
   parameters {
     jetbrains_ide = "GO"
     cpus          = 8
     memory        = 16
   }

   prebuilds {
     instances = 0                  # default to 0 instances

     scheduling {
       timezone = "UTC"             # only a single timezone may be used for simplicity

       # scale to 3 instances during the work week
       schedule {
         cron = "* 8-18 * * 1-5"    # from 8AM-6:59PM, Mon-Fri, UTC
         instances = 3              # scale to 3 instances
       }

       # scale to 1 instance on Saturdays for urgent support queries
       schedule {
         cron = "* 8-14 * * 6"      # from 8AM-2:59PM, Sat, UTC
         instances = 1              # scale to 1 instance
       }
     }
   }
}
```

**Scheduling configuration:**

- `timezone`: (Required) The timezone for all cron expressions. Only a single timezone is supported per scheduling configuration.
- `schedule`: One or more schedule blocks defining when to scale to specific instance counts.
  - `cron`: (Required) Cron expression interpreted as continuous time ranges.
  - `instances`: (Required) Number of prebuilt workspaces to maintain during this schedule.

**How scheduling works:**

1. The reconciliation loop evaluates all active schedules every reconciliation interval (`CODER_WORKSPACE_PREBUILDS_RECONCILIATION_INTERVAL`).
1. The schedule that matches the current time becomes active. Overlapping schedules are disallowed by validation rules.
1. If no schedules match the current time, the base `instances` count is used.
1. The reconciliation loop automatically creates or destroys prebuilt workspaces to match the target count.

**Cron expression format:**

Cron expressions follow the format: `* HOUR DOM MONTH DAY-OF-WEEK`

- `*` (minute): Must always be `*` to ensure the schedule covers entire hours rather than specific minute intervals
- `HOUR`: 0-23, range (e.g., 8-18 for 8AM-6:59PM), or `*`
- `DOM` (day-of-month): 1-31, range, or `*`
- `MONTH`: 1-12, range, or `*`
- `DAY-OF-WEEK`: 0-6 (Sunday=0, Saturday=6), range (e.g., 1-5 for Monday to Friday), or `*`

**Important notes about cron expressions:**

- **Minutes must always be `*`**: To ensure the schedule covers entire hours
- **Time ranges are continuous**: A range like `8-18` means from 8AM to 6:59PM (inclusive of both start and end hours)
- **Weekday ranges**: `1-5` means Monday through Friday (Monday=1, Friday=5)
- **No overlapping schedules**: The validation system prevents overlapping schedules.

**Example schedules:**

```tf
# Business hours only (8AM-6:59PM, Mon-Fri)
schedule {
  cron = "* 8-18 * * 1-5"
  instances = 5
}

# 24/7 coverage with reduced capacity overnight and on weekends
schedule {
  cron = "* 8-18 * * 1-5"  # Business hours (8AM-6:59PM, Mon-Fri)
  instances = 10
}
schedule {
  cron = "* 19-23,0-7 * * 1,5"  # Evenings and nights (7PM-11:59PM, 12AM-7:59AM, Mon-Fri)
  instances = 2
}
schedule {
  cron = "* * * * 6,0"  # Weekends
  instances = 2
}

# Weekend support (10AM-4:59PM, Sat-Sun)
schedule {
  cron = "* 10-16 * * 6,0"
  instances = 1
}
```

### Template updates and the prebuilt workspace lifecycle

Prebuilt workspaces are not updated after they are provisioned.

When a template's active version is updated:

1. Prebuilt workspaces for old versions are automatically deleted.
1. New prebuilt workspaces are created for the active template version.
1. If dependencies change (e.g., an [AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) update) without a template version change:
   - You can delete the existing prebuilt workspaces manually.
   - Coder will automatically create new prebuilt workspaces with the updated dependencies.

The system always maintains the desired number of prebuilt workspaces for the active template version.

### Invalidating prebuilds

When external dependencies change without a template version update, you can invalidate presets to force their prebuilt workspaces to be recreated.

This is useful when:

- A base VM image or container image has been updated externally
- Infrastructure configuration has drifted from the desired state
- A monorepo cloned during the prebuild has fallen behind its origin
- You want to ensure prebuilt workspaces use the latest dependencies without publishing a new template version

To invalidate presets:

1. Navigate to **Templates** and select your template.
1. Go to the **Prebuilds** tab.
1. Click **Invalidate Prebuilds**.
1. Confirm the action in the dialog.

Once presets are invalidated, the **next reconciliation loop** run will delete the old prebuilt workspaces and create new ones to maintain the desired instance count.
The process typically completes within a few reconciliation cycles (the interval is controlled by `CODER_WORKSPACE_PREBUILDS_RECONCILIATION_INTERVAL`, which defaults to 15 seconds).

> [!NOTE]
> Preset invalidation only affects unclaimed prebuilt workspaces owned by the `prebuilds` system user.
> Workspaces that have already been claimed by users are not affected.
> The invalidation is not instantaneous and will take effect during the next reconciliation loop run.

## Administration and troubleshooting

### Managing resource quotas

To help prevent unexpected infrastructure costs, prebuilt workspaces can be used in conjunction with [resource quotas](../../users/quotas.md).
Because unclaimed prebuilt workspaces are owned by the `prebuilds` user, you can:

1. Configure quotas for any group that includes this user.
1. Set appropriate limits to balance prebuilt workspace availability with resource constraints.

When prebuilt workspaces are configured for an organization, Coder creates a "prebuilds" group in that organization and adds the prebuilds user to it. This group has a default quota allowance of 0, which you should adjust based on your needs:

- **Set a quota allowance** on the "prebuilds" group to control how many prebuilt workspaces can be provisioned
- **Monitor usage** to ensure the quota is appropriate for your desired number of prebuilt instances
- **Adjust as needed** based on your template costs and desired prebuilt workspace pool size

If a quota is exceeded, the prebuilt workspace will fail provisioning the same way other workspaces do.

### Managing prebuild provisioning queues

Prebuilt workspaces can overwhelm a Coder deployment, causing significant delays when users and template administrators create new workspaces or manage their templates. Fundamentally, this happens when provisioners are not able to meet the demand for provisioner jobs. Prebuilds contribute to provisioner demand by scheduling many jobs in bursts whenever templates are updated. The solution is to either increase the number of provisioners or decrease the number of requested prebuilt workspaces across the entire system.

To identify if prebuilt workspaces have overwhelmed the available provisioners in your Coder deployment, look for:

- Large or growing queue of prebuild-related jobs
- User workspace creation is slow
- Publishing a new template version is not reflected in the UI because the associated template import job has not yet finished

The troubleshooting steps below will help you assess and resolve this situation:

1) Pause prebuilt workspace reconciliation to stop the problem from getting worse
2) Check how many prebuild jobs are clogging your provisioner queue
3) Cancel excess prebuild jobs to free up provisioners for human users
4) Fix any problematic templates that are causing the issue
5) Resume prebuilt reconciliation once everything is back to normal

#### Pause prebuilds to limit potential impact

Run:

```bash
coder prebuilds pause
```

This prevents further pollution of your provisioner queues by stopping the prebuilt workspaces feature from scheduling new creation jobs. While the pause is in effect, no new prebuilt workspaces will be scheduled for any templates in any organizations across the entire Coder deployment.  Therefore, the command must be executed by a user with Owner level access. Existing prebuilt workspaces will remain in place.

**Important**: Remember to run `coder prebuilds resume` once all impact has been mitigated (see the last step in this section).

#### Assess prebuild queue impact

Next, run:

```bash
coder provisioner jobs list --status=pending --initiator=prebuilds
```

This will show a list of all pending jobs that have been enqueued by the prebuilt workspace system. The length of this list indicates whether prebuilt workspaces have overwhelmed your Coder deployment.

Human-initiated jobs have priority over pending prebuild jobs, but running prebuild jobs cannot be preempted. A long list of pending prebuild jobs increases the likelihood that all provisioners are already occupied when a user wants to create a workspace or import a new template version. This increases the likelihood that users will experience delays waiting for the next available provisioner.

#### Cancel pending prebuild jobs

Human-initiated jobs are prioritized above prebuild jobs in the provisioner queue. However, if no human-initiated jobs are queued when a provisioner becomes available, a prebuild job will occupy the provisioner. This can delay human-initiated jobs that arrive later, forcing them to wait for the next available provisioner.

To expedite fixing a broken template by ensuring maximum provisioner availability, cancel all pending prebuild jobs:

```bash
coder provisioner jobs list --status=pending --initiator=prebuilds | jq -r '.[].id' | xargs -n1 -P2 -I{} coder provisioner jobs cancel {}
```

This will clear the provisioner queue of all jobs that were not initiated by a human being, which increases the probability that a provisioner will be available when the next human operator needs it. It does not cancel running provisioner jobs, so there may still be some delay in processing new provisioner jobs until a provisioner completes its current job.

At this stage, most prebuild related impact will have been mitigated. There may still be a bugged template version, but it will no longer pollute provisioner queues with prebuilt workspace jobs. If the latest version of a template is also broken for reasons unrelated to prebuilds, then users are able to create workspaces using a previous template version. Some running jobs may have been initiated by the prebuild system, but these cannot be cancelled without potentially orphaning resources that have already been deployed by Terraform. Depending on your deployment and template provisioning times, it might be best to upload a new template version and wait for it to be processed organically.

#### Cancel running prebuild provisioning jobs (Optional)

If you need to expedite the processing of human-related jobs at the cost of some infrastructure housekeeping, you can run:

```bash
coder provisioner jobs list --status=running --initiator=prebuilds | jq -r '.[].id' | xargs -n1 -P2 -I{} coder provisioner jobs cancel {}
```

This should be done as a last resort. It will cancel running prebuild jobs (orphaning any resources that have already been deployed) and immediately make room for human-initiated jobs. Orphaned infrastructure will need to be manually cleaned up by a human operator. The process to identify and clear these orphaned resources will likely require administrative access to the infrastructure that hosts Coder workspaces. Furthermore, the ability to identify such orphaned resources will depend on metadata that should be included in the workspace template.

Once the provisioner queue has been cleared and all templates have been fixed, resume prebuild reconciliation by running:

#### Resume prebuild reconciliation

```bash
coder prebuilds resume
```

This re-enables the prebuilt workspaces feature and allows the reconciliation loop to resume normal operation. The system will begin creating new prebuilt workspaces according to your template configurations.

### Template configuration best practices

#### Preventing resource replacement

When a prebuilt workspace is claimed, another `terraform apply` run occurs with new values for the workspace owner and name.

This can cause issues in the following scenario:

1. The workspace is initially created with values from the `prebuilds` user and a random name.
1. After claiming, various workspace properties change (ownership, name, and potentially other values), which Terraform sees as configuration drift.
1. If these values are used in immutable fields, Terraform will destroy and recreate the resource, eliminating the benefit of prebuilds.

For example, when these values are used in immutable fields like the AWS instance `user_data`, you'll see resource replacement during claiming:

![Resource replacement notification](../../../images/admin/templates/extend-templates/prebuilt/replacement-notification.png)

To prevent this, add a `lifecycle` block with `ignore_changes`:

```hcl
resource "docker_container" "workspace" {
  lifecycle {
    ignore_changes = [env, image] # include all fields which caused drift
  }

  count = data.coder_workspace.me.start_count
  name  = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
  ...
}
```

Limit the scope of `ignore_changes` to include only the fields specified in the notification.
If you include too many fields, Terraform might ignore changes that wouldn't otherwise cause drift.

Learn more about `ignore_changes` in the [Terraform documentation](https://developer.hashicorp.com/terraform/language/meta-arguments#lifecycle).

_A note on "immutable" attributes: Terraform providers may specify `ForceNew` on their resources' attributes. Any change
to these attributes require the replacement (destruction and recreation) of the managed resource instance, rather than an in-place update.
For example, the [`ami`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#ami-1) attribute on the `aws_instance` resource
has [`ForceNew`](https://github.com/hashicorp/terraform-provider-aws/blob/main/internal/service/ec2/ec2_instance.go#L75-L81) set,
since the AMI cannot be changed in-place._

### Preventing prebuild queue contention (recommended)

The section [Managing prebuild provisioning queues](#managing-prebuild-provisioning-queues) covers how to recover when prebuilds have already overwhelmed the provisioner queue.
This section outlines a **best-practice configuration** to prevent that situation by isolating prebuild jobs to a dedicated provisioner pool.
This setup is optional and requires minor template changes.

Coder supports [external provisioners and provisioner tags](../../provisioners/index.md), which allows you to route jobs to provisioners with matching tags.
By creating external provisioners with a special tag (e.g., `is_prebuild=true`) and updating the template to conditionally add that tag for prebuild jobs,
all prebuild work is handled by the prebuild pool.
This keeps other provisioners available to handle user-initiated jobs.

#### Setup

1. Create a provisioner key with a prebuild tag (e.g., `is_prebuild=true`).
    Provisioner keys are org-scoped and their tags are inferred automatically by provisioner daemons that use the key.
    **Note:** `coder_workspace_tags` are cumulative, so if your template already defines provisioner tags, you will need to create the provisioner key with the same tags plus the `is_prebuild=true` tag so that prebuild jobs correctly match the dedicated prebuild pool.
    See [Scoped Key](../../provisioners/index.md#scoped-key-recommended) for instructions on how to create a provisioner key.

1. Deploy a separate provisioner pool using that key (for example, via the [Helm coder-provisioner chart](https://github.com/coder/coder/pkgs/container/chart%2Fcoder-provisioner)).
    Daemons in this pool will only execute jobs that include all of the tags specified in their provisioner key.
    See [External provisioners](../../provisioners/index.md) for environment-specific deployment examples.

1. Update the template to conditionally add the prebuild tag for prebuild jobs.

    ```hcl
    data "coder_workspace_tags" "prebuilds" {
      count = data.coder_workspace_owner.me.name == "prebuilds" ? 1 : 0
      tags = {
        "is_prebuild" = "true"
      }
    }
    ```

Prebuild workspaces are a special type of workspace owned by the system user `prebuilds`.
The value `data.coder_workspace_owner.me.name` returns the name of the workspace owner, for prebuild workspaces, this value is `"prebuilds"`.
Because the condition evaluates based on the workspace owner, provisioning or deprovisioning prebuilds automatically applies the prebuild tag, whereas regular jobs (like workspace creation or template import) do not.

> [!NOTE]
> The prebuild provisioner pool can still accept non-prebuild jobs.
> To achieve a fully isolated setup, add an additional tag (`is_prebuild=false`) to your standard provisioners, ensuring a clean separation between prebuild and non-prebuild workloads.
> See [Provisioner Tags](../../provisioners/index.md#provisioner-tags) for further details.

#### Validation

To confirm that prebuild jobs are correctly routed to the new provisioner pool, use the Provisioner Jobs dashboard or the [`coder provisioner jobs list`](../../../reference/cli/provisioner_jobs_list.md) CLI command to inspect job metadata and tags.
Follow these steps:

1. Publish the new template version.

1. Validate the status of the prebuild provisioners.
    Check the Provisioners page in the Coder dashboard or run the [`coder provisioner list`](../../../reference/cli/provisioner_list.md) CLI command to ensure all prebuild provisioners are up to date and the tags are properly set.

1. Wait for the prebuilds reconciliation loop to run.
    The loop frequency is controlled by the configuration value [`CODER_WORKSPACE_PREBUILDS_RECONCILIATION_INTERVAL`](../../../reference/cli/server.md#--workspace-prebuilds-reconciliation-interval).
    When the loop runs, it will provision prebuilds for the new template version and deprovision prebuilds for the previous version.
    Both provisioning and deprovisioning jobs for prebuilds should display the tag `is_prebuild=true`.

1. Create a new workspace from a preset.
    Whether the preset uses a prebuild pool or not, the resulting job should not include the `is_prebuild=true` tag.
    This confirms that only prebuild-related jobs are routed to the dedicated prebuild provisioner pool.

### Monitoring and observability

#### Available metrics

Coder provides several metrics to monitor your prebuilt workspaces:

- `coderd_prebuilt_workspaces_created_total` (counter): Total number of prebuilt workspaces created to meet the desired instance count.
- `coderd_prebuilt_workspaces_failed_total` (counter): Total number of prebuilt workspaces that failed to build.
- `coderd_prebuilt_workspaces_claimed_total` (counter): Total number of prebuilt workspaces claimed by users.
- `coderd_prebuilt_workspaces_desired` (gauge): Target number of prebuilt workspaces that should be available.
- `coderd_prebuilt_workspaces_running` (gauge): Current number of prebuilt workspaces in a `running` state.
- `coderd_prebuilt_workspaces_eligible` (gauge): Current number of prebuilt workspaces eligible to be claimed.
- `coderd_prebuilt_workspace_claim_duration_seconds` ([_native histogram_](https://prometheus.io/docs/specs/native_histograms) support): Time to claim a prebuilt workspace from the prebuild pool.

#### Logs

Search for `coderd.prebuilds:` in your logs to track the reconciliation loop's behavior.

These logs provide information about:

1. Creation and deletion attempts for prebuilt workspaces.
1. Backoff events after failed builds.
1. Claiming operations.

---

# Icons

Source: https://coder.com/docs/admin/templates/extending-templates/icons

# Icons

Coder uses icons in several places, including ones that can be configured
throughout the app, or specified in your Terraform. They're specified by a URL,
which can be to an image hosted on a CDN of your own, or one of the icons that
come bundled with your Coder deployment.

- **Template Icons**:

  - Make templates and workspaces visually recognizable with a relevant or
    memorable icon

- [**Terraform**](https://registry.terraform.io/providers/coder/coder/latest/docs):

  - [`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#icon-1)
  - [`coder_parameter`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter#icon-1)
    and
    [`option`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter#nested-schema-for-option)
    blocks
  - [`coder_script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script#icon-1)
  - [`coder_metadata`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/metadata#icon-1)

  These can all be configured to use an icon by setting the `icon` field.

  ```tf
  data "coder_parameter" "my_parameter" {
    icon = "/icon/coder.svg"

    option {
      icon = "/emojis/1f3f3-fe0f-200d-26a7-fe0f.png"
    }
  }
  ```

- [**Authentication Providers**](../../external-auth/index.md):

  - Use icons for external authentication providers to make them recognizable.
    You can set an icon for each provider by setting the
    `CODER_EXTERNAL_AUTH_X_ICON` environment variable, where `X` is the number
    of the provider.

    ```env
    CODER_EXTERNAL_AUTH_0_ICON=/icon/github.svg
    CODER_EXTERNAL_AUTH_1_ICON=/icon/google.svg
    ```

- [**Support Links**](../../setup/appearance.md#support-links):

  - Use icons for support links to make them recognizable. You can set the
    `icon` field for each link in `CODER_SUPPORT_LINKS` array.

## Bundled icons

Coder is distributed with a bundle of icons for popular cloud providers and
programming languages. You can see all of the icons (or suggest new ones) in our
repository on
[GitHub](https://github.com/coder/coder/tree/main/site/static/icon).

You can also view the entire list, with search and previews, by navigating to
`/icons` on your Coder deployment (for example,
`https://coder.example.com/icons`). This can be particularly useful in airgapped
deployments.

![The icon gallery](../../../images/icons-gallery.png)

## External icons

You can use any image served over HTTPS as an icon, by specifying the full URL
of the image. We recommend that you use a CDN that you control, but it can be
served from any source that you trust.

You can also embed an image by using data: URLs.

- Only the https: and data: protocols are supported in icon URLs (not http:)

- Be careful when using images hosted by someone else; they might disappear or
  change!

- Be careful when using data: URLs. They can get rather large, and can
  negatively impact loading times for pages and queries they appear in. Only use
  them for very small icons that compress well.

---

# Resource Metadata

Source: https://coder.com/docs/admin/templates/extending-templates/resource-metadata

# Resource Metadata

Expose key workspace information to your users with
[`coder_metadata`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/metadata)
resources in your template code.

You can use `coder_metadata` to show Terraform resource attributes like these:

- Compute resources
- IP addresses
- [Secrets](../../security/secrets.md#displaying-secrets)
- Important file paths

![ui](../../../images/admin/templates/coder-metadata-ui.png)

> [!NOTE]
> Coder automatically generates the <code>type</code> metadata.

You can also present automatically updating, dynamic values with
[agent metadata](./agent-metadata.md).

## Example

Expose the disk size, deployment name, and persistent directory in a Kubernetes
template with:

```tf
resource "kubernetes_persistent_volume_claim" "root" {
    ...
}

resource "kubernetes_deployment" "coder" {
  # My deployment is ephemeral
  count = data.coder_workspace.me.start_count
  ...
}

resource "coder_metadata" "pvc" {
  resource_id = kubernetes_persistent_volume_claim.root.id
  item {
    key = "size"
    value = kubernetes_persistent_volume_claim.root.spec[0].resources[0].requests.storage
  }
  item {
    key = "dir"
    value = "/home/coder"
  }
}

resource "coder_metadata" "deployment" {
  count = data.coder_workspace.me.start_count
  resource_id = kubernetes_deployment.coder[0].id
  item {
    key = "name"
    value = kubernetes_deployment.coder[0].metadata[0].name
  }
}
```

## Hiding resources in the dashboard

Some resources don't need to be exposed in the dashboard's UI. This helps keep
the workspace view clean for developers. To hide a resource, use the `hide`
attribute:

```tf
resource "coder_metadata" "hide_serviceaccount" {
  count = data.coder_workspace.me.start_count
  resource_id = kubernetes_service_account.user_data.id
  hide = true
  item {
    key = "name"
    value = kubernetes_deployment.coder[0].metadata[0].name
  }
}
```

## Using a custom resource icon

To use custom icons for your resource metadata, use the `icon` attribute. It
must be a valid path or URL.

```tf
resource "coder_metadata" "resource_with_icon" {
  count = data.coder_workspace.me.start_count
  resource_id = kubernetes_service_account.user_data.id
  icon = "/icon/database.svg"
  item {
    key = "name"
    value = kubernetes_deployment.coder[0].metadata[0].name
  }
}
```

To make it easier for you to customize your resource we added some built-in
icons:

- Folder `/icon/folder.svg`
- Memory `/icon/memory.svg`
- Image `/icon/image.svg`
- Widgets `/icon/widgets.svg`
- Database `/icon/database.svg`

We also have other icons related to the IDEs. You can see more information on
how to use the builtin icons [here](./icons.md).

## Up next

- [Secrets](../../security/secrets.md)
- [Agent metadata](./agent-metadata.md)

---

# Resource Monitoring

Source: https://coder.com/docs/admin/templates/extending-templates/resource-monitoring

# Resource monitoring

Use the
[`resources_monitoring`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#resources_monitoring-1)
block on the
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent)
resource in our Terraform provider to monitor out of memory (OOM) and out of
disk (OOD) errors and alert users when they overutilize memory and disk.

This can help prevent agent disconnects due to OOM/OOD issues.

You can specify one or more volumes to monitor for OOD alerts.
OOM alerts are reported per-agent.

## Prerequisites

Notifications are sent through SMTP.
Configure Coder to [use an SMTP server](../../monitoring/notifications/index.md#smtp-email).

## Example

Add the following example to the template's `main.tf`.
Change the `90`, `80`, and `95` to a threshold that's more appropriate for your
deployment:

```hcl
resource "coder_agent" "main" {
  arch = data.coder_provisioner.dev.arch
  os   = data.coder_provisioner.dev.os
  resources_monitoring {
    memory {
      enabled   = true
      threshold = 90
    }
    volume {
      path      = "/volume1"
      enabled   = true
      threshold = 80
    }
    volume {
      path      = "/volume2"
      enabled   = true
      threshold = 95
    }
  }
}
```

---

# Resource Ordering

Source: https://coder.com/docs/admin/templates/extending-templates/resource-ordering

# UI Resource Ordering

In Coder templates, managing the order of UI elements is crucial for a seamless
user experience. This page outlines how resources can be aligned using the
`order` Terraform property or inherit the natural order from the file.

The resource with the lower `order` is presented before the one with greater
value. A missing `order` property defaults to 0. If two resources have the same
`order` property, the resources will be ordered by property `name` (or `key`).

## Using "order" property

### Coder parameters

The `order` property of `coder_parameter` resource allows specifying the order
of parameters in UI forms. In the below example, `project_id` will appear
_before_ `account_id`:

```tf
data "coder_parameter" "project_id" {
  name         = "project_id"
  display_name = "Project ID"
  description  = "Specify cloud provider project ID."
  order = 2
}

data "coder_parameter" "account_id" {
  name         = "account_id"
  display_name = "Account ID"
  description  = "Specify cloud provider account ID."
  order = 1
}
```

### Agents

Agent resources within the UI left pane are sorted based on the `order`
property, followed by `name`, ensuring a consistent and intuitive arrangement.

```tf
resource "coder_agent" "primary" {
  ...

  order = 1
}

resource "coder_agent" "secondary" {
  ...

  order = 2
}
```

The agent with the lowest order is presented at the top in the workspace view.

### Agent metadata

The `coder_agent` exposes metadata to present operational metrics in the UI.
Metrics defined with Terraform `metadata` blocks can be ordered using additional
`order` property; otherwise, they are sorted by `key`.

```tf
resource "coder_agent" "main" {
  ...

  metadata {
    display_name = "CPU Usage"
    key          = "cpu_usage"
    script       = "coder stat cpu"
    interval     = 10
    timeout      = 1
    order        = 1
  }
  metadata {
    display_name = "CPU Usage (Host)"
    key          = "cpu_usage_host"
    script       = "coder stat cpu --host"
    interval     = 10
    timeout      = 1
    order        = 2
  }
  metadata {
    display_name = "RAM Usage"
    key          = "ram_usage"
    script       = "coder stat mem"
    interval     = 10
    timeout      = 1
    order        = 1
  }
  metadata {
    display_name = "RAM Usage (Host)"
    key          = "ram_usage_host"
    script       = "coder stat mem --host"
    interval     = 10
    timeout      = 1
    order        = 2
  }
}
```

### Applications

Similarly to Coder agents, `coder_app` resources incorporate the `order`
property to organize button apps in the app bar within a `coder_agent` in the
workspace view.

Only template defined applications can be arranged. _VS Code_ or _Terminal_
buttons are static.

```tf
resource "coder_app" "code-server" {
  agent_id     = coder_agent.main.id
  slug         = "code-server"
  display_name = "code-server"
  ...

  order = 2
}

resource "coder_app" "filebrowser" {
  agent_id     = coder_agent.main.id
  display_name = "File Browser"
  slug         = "filebrowser"
  ...

  order = 1
}
```

## Inherit order from file

### Coder parameter options

The options for Coder parameters maintain the same order as in the file
structure. This simplifies management and ensures consistency between
configuration files and UI presentation.

```tf
data "coder_parameter" "database_region" {
  name         = "database_region"
  display_name = "Database Region"

  icon        = "/icon/database.svg"
  description = "These are options."
  mutable     = true
  default     = "us-east1-a"

  // The order of options is stable and inherited from .tf file.
  option {
    name        = "US Central"
    description = "Select for central!"
    value       = "us-central1-a"
  }
  option {
    name        = "US East"
    description = "Select for east!"
    value       = "us-east1-a"
  }
  ...
}
```

### Coder metadata items

In cases where multiple item properties exist, the order is inherited from the
file, facilitating seamless integration between a Coder template and UI
presentation.

```tf
resource "coder_metadata" "attached_volumes" {
  resource_id = docker_image.main.id

  // Items will be presented in the UI in the following order.
  item {
    key   = "disk-a"
    value = "60 GiB"
  }
  item {
    key   = "disk-b"
    value = "128 GiB"
  }
}
```

---

# Resource Persistence

Source: https://coder.com/docs/admin/templates/extending-templates/resource-persistence

# Resource persistence

By default, all Coder resources are persistent, but production templates
**must** use the practices laid out in this document to prevent accidental
deletion.

Coder templates have full control over workspace ephemerality. In a completely
ephemeral workspace, there are zero resources in the Off state. In a completely
persistent workspace, there is no difference between the Off and On states.

The needs of most workspaces fall somewhere in the middle, persisting user data
like filesystem volumes, but deleting expensive, reproducible resources such as
compute instances.

## Disabling persistence

The Terraform
[`coder_workspace` data source](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace)
exposes the `start_count = [0 | 1]` attribute. To make a resource ephemeral, you
can assign the `start_count` attribute to resource's
[`count`](https://developer.hashicorp.com/terraform/language/meta-arguments/count)
meta-argument.

In this example, Coder will provision or tear down the `docker_container`
resource:

```tf
data "coder_workspace" "me" {
}

resource "docker_container" "workspace" {
  # When `start_count` is 0, `count` is 0, so no `docker_container` is created.
  count = data.coder_workspace.me.start_count # 0 (stopped), 1 (started)
  # ... other config
}
```

## ⚠️ Persistence pitfalls

Take this example resource:

```tf
data "coder_workspace" "me" {
}

resource "docker_volume" "home_volume" {
  name = "coder-${data.coder_workspace.me.owner}-home"
}
```

Because we depend on `coder_workspace.me.owner`, if the owner changes their
username, Terraform will recreate the volume (wiping its data!) the next time
that Coder starts the workspace.

To prevent this, use immutable IDs:

- `coder_workspace.me.owner_id`
- `coder_workspace.me.id`

You should also avoid using `coder_workspace.me.name` if your deployment allows workspace renaming via `CODER_ALLOW_WORKSPACE_RENAMES` or `--allow-workspace-renames`.

```tf
data "coder_workspace" "me" {
}

resource "docker_volume" "home_volume" {
  # This volume will survive until the Workspace is deleted or the template
  # admin changes this resource block.
  name = "coder-${data.coder_workspace.id}-home"
}
```

## 🛡 Bulletproofing

Even if your persistent resource depends exclusively on immutable IDs, a change
to the `name` format or other attributes would cause Terraform to rebuild the
resource.

You can prevent Terraform from recreating a resource under any circumstance by
setting the
[`ignore_changes = all` directive in the `lifecycle` block](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes).

```tf
data "coder_workspace" "me" {
}

resource "docker_volume" "home_volume" {
  # This resource will survive until either the entire block is deleted
  # or the workspace is.
  name = "coder-${data.coder_workspace.me.id}-home"
  lifecycle {
    ignore_changes = all
  }
}
```

---

# Environment Variables

Source: https://coder.com/docs/admin/templates/extending-templates/environment-variables

# Environment variables

Use the
[`coder_env`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/env)
resource to inject environment variables into your workspace agents. This is
useful for configuring tools, setting paths, and passing configuration to
development environments.

## Basic usage

```tf
resource "coder_agent" "dev" {
  os   = "linux"
  arch = "amd64"
}

resource "coder_env" "go_path" {
  agent_id = coder_agent.dev.id
  name     = "GOPATH"
  value    = "/home/coder/go"
}
```

Each `coder_env` resource sets a single environment variable on the specified
agent. You can define multiple `coder_env` resources targeting the same agent.

## Merge strategies

When multiple `coder_env` resources define the same variable name, use the
`merge_strategy` attribute to control how values are combined:

| Strategy              | Behavior                                            |
|-----------------------|-----------------------------------------------------|
| `replace` _(default)_ | Last value wins. Backward compatible.               |
| `append`              | Appends to the existing value with `:` separator.   |
| `prepend`             | Prepends to the existing value with `:` separator.  |
| `error`               | Fails the build if the variable is already defined. |

The `append` and `prepend` strategies use `:` as a separator, which matches
the convention for `PATH`-style variables on Unix systems.

### Example: Appending to PATH

Multiple `coder_env` resources can each add directories to `PATH`:

```tf
resource "coder_env" "path_tools" {
  agent_id       = coder_agent.dev.id
  name           = "PATH"
  value          = "/home/coder/tools/bin"
  merge_strategy = "append"
}

resource "coder_env" "path_go" {
  agent_id       = coder_agent.dev.id
  name           = "PATH"
  value          = "/home/coder/go/bin"
  merge_strategy = "append"
}
```

This produces `PATH` with the value
`/home/coder/tools/bin:/home/coder/go/bin`.

### Example: Preventing duplicates

Use `error` to catch accidental duplicate definitions:

```tf
resource "coder_env" "editor" {
  agent_id       = coder_agent.dev.id
  name           = "EDITOR"
  value          = "vim"
  merge_strategy = "error"
}
```

If another `coder_env` resource also sets `EDITOR`, the build fails with
a clear error message.

## Ordering

When multiple `coder_env` resources append or prepend to the same variable,
they are processed in alphabetical order by their
[Terraform resource address](https://developer.hashicorp.com/terraform/cli/state/resource-addressing).
In the PATH example above, `coder_env.path_go` is processed before
`coder_env.path_tools` because `path_go` sorts before `path_tools`
alphabetically.

## Agent env override

The `env` block inside a `coder_agent` resource always takes final precedence
over any `coder_env` resources. If both define the same variable, the
`coder_agent` value wins regardless of `merge_strategy`. This override happens
after `coder_env` resources are merged, so `merge_strategy = "error"` does not
trigger when the conflict is with the agent's `env` block — only when two
`coder_env` resources define the same key:

```tf
resource "coder_agent" "dev" {
  os   = "linux"
  arch = "amd64"
  env = {
    PATH = "/usr/local/bin:/usr/bin:/bin"
  }
}

# This value is ignored because coder_agent.dev.env sets PATH directly.
resource "coder_env" "extra_path" {
  agent_id       = coder_agent.dev.id
  name           = "PATH"
  value          = "/home/coder/bin"
  merge_strategy = "append"
}
```

See the
[Coder Terraform provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/env)
for the complete `coder_env` reference.

---

# Terraform Variables

Source: https://coder.com/docs/admin/templates/extending-templates/variables

# Terraform template-wide variables

In Coder, Terraform templates offer extensive flexibility through template-wide
variables. These variables, managed by template authors, facilitate the
construction of customizable templates. Unlike parameters, which are primarily
for workspace customization, template variables remain under the control of the
template author, ensuring workspace users cannot modify them.

```tf
variable "CLOUD_API_KEY" {
  type        = string
  description = "API key for the service"
  default     = "1234567890"
  sensitive   = true
}
```

Given that variables are a
[fundamental concept in Terraform](https://developer.hashicorp.com/terraform/language/values/variables),
Coder endeavors to fully support them. Native support includes `string`,
`number`, and `bool` formats. However, other types such as `list(string)` or
`map(any)` will default to being treated as strings.

## Default value

Upon adding a template variable, it's mandatory to provide a value during the
first push. At this stage, the template administrator faces two choices:

1. _No `default` property_: opt not to define a default property. Instead,
   utilize the `--var name=value` command-line argument during the push to
   supply the variable's value.
2. _Define `default` property_: set a default property for the template
   variable. If the administrator doesn't input a value via CLI, Coder
   automatically uses this default during the push.

After the initial push, variables are stored in the database table, associated
with the specific template version. They can be conveniently managed via
_Template Settings_ without requiring an extra push.

### Resolved values vs. default values

It's crucial to note that Coder templates operate based on resolved values
during a push, rather than default values. This ensures that default values do
not inadvertently override the configured variable settings during the push
process.

This approach caters to users who prefer to avoid accidental overrides of their
variable settings with default values during pushes, thereby enhancing control
and predictability.

If you encounter a situation where you need to override template settings for
variables, you can employ a straightforward solution:

1. Create a `terraform.tfvars` file in in the template directory:

   ```tf
   coder_image = newimage:tag
   ```

1. Push the new template revision using Coder CLI:

   ```shell
   coder templates push my-template -y # no need to use --var
   ```

This file serves as a mechanism to override the template settings for variables.
It can be stored in the repository for easy access and reference. Coder CLI
automatically detects it and loads variable values.

## Input options

When working with Terraform configurations in Coder, you have several options
for providing values to variables using the Coder CLI:

1. _Manual input in CLI_: You can manually input values for Terraform variables
   directly in the CLI during the deployment process.
1. _Web UI_: You can set or edit variable values under **Variables** in the
   template's settings.
1. _Command-line argument_: Utilize the `--var name=value` command-line argument
   to specify variable values inline as key-value pairs.
1. _Variables file selection_: Alternatively, you can use a variables file
   selected via the `--variables-file values.yml` command-line argument. This
   approach is particularly useful when dealing with multiple variables or to
   avoid manual input of numerous values. Variables files can be versioned for
   better traceability and management, and it enhances reproducibility.

Here's an example of a YAML-formatted variables file, `values.yml`:

```yaml
region: us-east-1
bucket_name: magic
zone_types: '{"us-east-1":"US East", "eu-west-1": "EU West"}'
cpu: 1
```

In this sample file:

- `region`, `bucket_name`, `zone_types`, and `cpu` are Terraform variable names.
- Corresponding values are provided for each variable.
- The `zone_types` variable demonstrates how to provide a JSON-formatted string
  as a value in YAML.

## Terraform .tfvars files

In Terraform, `.tfvars` files provide a convenient means to define variable
values for a project in a reusable manner. These files, ending with either
`.tfvars` or `.tfvars.json`, streamline the process of setting numerous
variables.

By utilizing `.tfvars` files, you can efficiently manage and organize variable
values for your Terraform projects. This approach offers several advantages:

- Clarity and consistency: Centralize variable definitions in dedicated files,
  enhancing clarity, instead of input values on template push.
- Ease of maintenance: Modify variable values in a single location under version
  control, simplifying maintenance and updates.

Coder automatically loads variable definition files following a specific order,
providing flexibility and control over variable configuration. The loading
sequence is as follows:

1. `terraform.tfvars`: This file contains variable values and is loaded first.
2. `terraform.tfvars.json`: If present, this JSON-formatted file is loaded after
   `terraform.tfvars`.
3. `\*.auto.tfvars`: Files matching this pattern are loaded next, ordered
   alphabetically.
4. `\*.auto.tfvars.json`: JSON-formatted files matching this pattern are loaded
   last.

---

# Terraform Modules

Source: https://coder.com/docs/admin/templates/extending-templates/modules

# Reusing template code

To reuse code across different Coder templates, such as common scripts or
resource definitions, we suggest using
[Terraform Modules](https://developer.hashicorp.com/terraform/language/modules).

You can store these modules externally from your Coder deployment, like in a git
repository or a Terraform registry. This example shows how to reference a module
from your template:

```tf
data "coder_workspace" "me" {}

module "coder-base" {
  source = "github.com/my-organization/coder-base"

  # Modules take in variables and can provision infrastructure
  vpc_name            = "devex-3"
  subnet_tags         = { "name": data.coder_workspace.me.name }
  code_server_version = 4.14.1
}

resource "coder_agent" "dev" {
  # Modules can provide outputs, such as helper scripts
  startup_script=<<EOF
  #!/bin/sh
  ${module.coder-base.code_server_install_command}
  EOF
}
```

Learn more about
[creating modules](https://developer.hashicorp.com/terraform/language/modules)
and
[module sources](https://developer.hashicorp.com/terraform/language/modules/sources)
in the Terraform documentation.

## Coder modules

Coder publishes plenty of modules that can be used to simplify some common tasks
across templates. Some of the modules we publish are,

1. [`code-server`](https://registry.coder.com/modules/coder/code-server) and
   [`vscode-web`](https://registry.coder.com/modules/coder/vscode-web)
2. [`git-clone`](https://registry.coder.com/modules/coder/git-clone)
3. [`dotfiles`](https://registry.coder.com/modules/coder/dotfiles)
4. [`jetbrains`](https://registry.coder.com/modules/coder/jetbrains)
5. [`jfrog-oauth`](https://registry.coder.com/modules/coder/jfrog-oauth) and
   [`jfrog-token`](https://registry.coder.com/modules/coder/jfrog-token)
6. [`vault-github`](https://registry.coder.com/modules/coder/vault-github)

For a full list of available modules please check
[Coder module registry](https://registry.coder.com/modules).

## Offline installations

In offline and restricted deployments, there are three ways to fetch modules.

1. Artifactory Remote Terraform Repository (Recommended)
2. Artifactory Local Repository (manual publishing)
3. Private git repository

### Artifactory Remote Terraform Repository (Recommended)

Configure Artifactory as a **Remote Terraform Repository** that proxies and
caches the Coder registry. This approach provides automatic updates and
requires no manual synchronization.

See [Mirror the Coder Registry with JFrog Artifactory](../../../install/registry-mirror-artifactory.md)
for complete setup instructions.

### Artifactory Local Repository

Air-gapped users can clone the [coder/registry](https://github.com/coder/registry/)
repo and publish a
[local terraform module repository](https://jfrog.com/help/r/jfrog-artifactory-documentation/set-up-a-terraform-module/provider-registry)
to resolve modules via [Artifactory](https://jfrog.com/artifactory/).

1. Create a local-terraform-repository with name `coder-modules-local`
1. Create a virtual repository with name `tf`
1. Follow the below instructions to publish coder modules to Artifactory

   ```shell
   git clone https://github.com/coder/registry
   cd registry/registry/coder/modules
   jf tfc
   jf tf p --namespace="coder" --provider="coder" --tag="1.0.0"
   ```

1. Generate a token with access to the `tf` repo and set an `ENV` variable
   `TF_TOKEN_example.jfrog.io="XXXXXXXXXXXXXXX"` on the Coder provisioner.
1. Create a file `.terraformrc` with following content and mount at
   `/home/coder/.terraformrc` within the Coder provisioner.

   ```tf
   provider_installation {
     direct {
         exclude = ["registry.terraform.io/*/*"]
     }
     network_mirror {
         url = "https://example.jfrog.io/artifactory/api/terraform/tf/providers/"
     }
   }
   ```

1. Update module source as:

   ```tf
   module "module-name" {
     source = "https://example.jfrog.io/tf__coder/module-name/coder"
     version = "1.0.0"
     agent_id = coder_agent.example.id
     ...
   }
   ```

   Replace `example.jfrog.io` with your Artifactory URL

Based on the instructions
[here](https://jfrog.com/blog/tour-terraform-registries-in-artifactory/).

#### Example template

We have an example template
[here](https://github.com/coder/coder/blob/main/examples/jfrog/remote/main.tf)
that uses our
[JFrog Docker](https://github.com/coder/coder/blob/main/examples/jfrog/docker/main.tf)
template as the underlying module.

### Private git repository

If you are importing a module from a private git repository, the Coder server or
[provisioner](../../provisioners/index.md) needs git credentials. Since this token
will only be used for cloning your repositories with modules, it is best to
create a token with access limited to the repository and no extra permissions.
In GitHub, you can generate a
[fine-grained token](https://docs.github.com/en/rest/overview/permissions-required-for-fine-grained-personal-access-tokens?apiVersion=2022-11-28)
with read only access to the necessary repos.

If you are running Coder on a VM, make sure that you have `git` installed and
the `coder` user has access to the following files:

```shell
# /home/coder/.gitconfig
[credential]
  helper = store
```

```shell
# /home/coder/.git-credentials

# GitHub example:
https://your-github-username:your-github-pat@github.com
```

If you are running Coder on Docker or Kubernetes, `git` is pre-installed in the
Coder image. However, you still need to mount credentials. This can be done via
a Docker volume mount or Kubernetes secrets.

#### Passing git credentials in Kubernetes

First, create a `.gitconfig` and `.git-credentials` file on your local machine.
You might want to do this in a temporary directory to avoid conflicting with
your own git credentials.

Next, create the secret in Kubernetes. Be sure to do this in the same namespace
that Coder is installed in.

```shell
export NAMESPACE=coder
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: git-secrets
  namespace: $NAMESPACE
type: Opaque
data:
  .gitconfig: $(cat .gitconfig | base64 | tr -d '\n')
  .git-credentials: $(cat .git-credentials | base64 | tr -d '\n')
EOF
```

Then, modify Coder's Helm values to mount the secret.

```yaml
coder:
  volumes:
    - name: git-secrets
      secret:
        secretName: git-secrets
  volumeMounts:
    - name: git-secrets
      mountPath: "/home/coder/.gitconfig"
      subPath: .gitconfig
      readOnly: true
    - name: git-secrets
      mountPath: "/home/coder/.git-credentials"
      subPath: .git-credentials
      readOnly: true
```

### Next steps

- JFrog's
  [Terraform Registry support](https://jfrog.com/help/r/jfrog-artifactory-documentation/terraform-registry)
- [Configuring the JFrog toolchain inside a workspace](../../integrations/jfrog-artifactory.md)
- [Coder Module Registry](https://registry.coder.com/modules)

---

# Web IDEs and Coder Apps

Source: https://coder.com/docs/admin/templates/extending-templates/web-ides

# Web IDEs

In Coder, web IDEs are defined as
[coder_app](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
resources in the template. With our generic model, any web application can be
used as a Coder application. For example:

```tf
# Add button to open Portainer in the workspace dashboard
# Note: Portainer must be already running in the workspace
resource "coder_app" "portainer" {
  agent_id      = coder_agent.main.id
  slug          = "portainer"
  display_name  = "Portainer"
  icon          = "https://simpleicons.org/icons/portainer.svg"
  url           = "https://localhost:9443/api/status"

  healthcheck {
    url       = "https://localhost:9443/api/status"
    interval  = 6
    threshold = 10
  }
}
```

## code-server

[code-server](https://github.com/coder/code-server) is our supported method of running
VS Code in the web browser. A simple way to install code-server in Linux/macOS
workspaces is via the Coder agent in your template:

```console
# edit your template
cd your-template/
vim main.tf
```

```tf
resource "coder_agent" "main" {
    arch           = "amd64"
    os             = "linux"
    startup_script = <<EOF
    #!/bin/sh
    # install code-server
    # add '-s -- --version x.x.x' to install a specific code-server version
    curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server

    # start code-server on a specific port
    # authn is off since the user already authn-ed into the coder deployment
    # & is used to run the process in the background
    /tmp/code-server/bin/code-server --auth none --port 13337 &
    EOF
}
```

For advanced use, we recommend installing code-server in your VM snapshot or
container image. Here's a Dockerfile which leverages some special
[code-server features](https://coder.com/docs/code-server/):

```Dockerfile
FROM codercom/enterprise-base:ubuntu

# install the latest version
USER root
RUN curl -fsSL https://code-server.dev/install.sh | sh
USER coder

# pre-install VS Code extensions
RUN code-server --install-extension eamodio.gitlens

# directly start code-server with the agent's startup_script (see above),
# or use a process manager like supervisord
```

You'll also need to specify a `coder_app` resource related to the agent. This is
how code-server is displayed on the workspace page.

```tf
resource "coder_app" "code-server" {
  agent_id     = coder_agent.main.id
  slug         = "code-server"
  display_name = "code-server"
  url          = "http://localhost:13337/?folder=/home/coder"
  icon         = "/icon/code.svg"
  subdomain    = false

  healthcheck {
    url       = "http://localhost:13337/healthz"
    interval  = 2
    threshold = 10
  }

}
```

![code-server in a workspace](../../../images/code-server-ide.png)

## VS Code Web

VS Code supports launching a local web client using the `code serve-web`
command. To add VS Code web as a web IDE, you have two options.

1. Install using the
   [vscode-web module](https://registry.coder.com/modules/vscode-web) from the
   coder registry.

   ```tf
   module "vscode-web" {
     source         = "registry.coder.com/modules/vscode-web/coder"
     version        = "1.0.14"
     agent_id       = coder_agent.main.id
     accept_license = true
   }
   ```

2. Install and start in your `startup_script` and create a corresponding
   `coder_app`

   ```tf
   resource "coder_agent" "main" {
       arch           = "amd64"
       os             = "linux"
       startup_script = <<EOF
       #!/bin/sh
       # install VS Code
       curl -Lk 'https://code.visualstudio.com/sha/download?build=stable&os=cli-alpine-x64' --output vscode_cli.tar.gz
       mkdir -p /tmp/vscode-cli
       tar -xf vscode_cli.tar.gz -C /tmp/vscode-cli
       rm vscode_cli.tar.gz
       # start the web server on a specific port
       /tmp/vscode-cli/code serve-web --port 13338 --without-connection-token  --accept-server-license-terms >/tmp/vscode-web.log 2>&1 &
       EOF
   }
   ```

   > `code serve-web` was introduced in version 1.82.0 (August 2023).

   You also need to add a `coder_app` resource for this.

   ```tf
   # VS Code Web
   resource "coder_app" "vscode-web" {
     agent_id     = coder_agent.coder.id
     slug         = "vscode-web"
     display_name = "VS Code Web"
     icon         = "/icon/code.svg"
     url          = "http://localhost:13338?folder=/home/coder"
     subdomain    = true  # Subdomain is recommended for best compatibility. Subpath mode now works via --server-base-path (added in VS Code 1.88, March 2024)
     share        = "owner"
   }
   ```

## Jupyter Notebook

To use Jupyter Notebook in your workspace, you can install it by using the
[Jupyter Notebook module](https://registry.coder.com/modules/jupyter-notebook)
from the Coder registry:

```tf
module "jupyter-notebook" {
  source   = "registry.coder.com/modules/jupyter-notebook/coder"
  version  = "1.0.19"
  agent_id = coder_agent.example.id
}
```

![Jupyter Notebook in Coder](../../../images/jupyter-notebook.png)

## JupyterLab

Configure your agent and `coder_app` like so to use Jupyter. Notice the
`subdomain=true` configuration:

```tf
data "coder_workspace" "me" {}

resource "coder_agent" "coder" {
  os             = "linux"
  arch           = "amd64"
  dir            = "/home/coder"
  startup_script = <<-EOF
pip3 install jupyterlab
$HOME/.local/bin/jupyter lab --ServerApp.token='' --ip='*'
EOF
}

resource "coder_app" "jupyter" {
  agent_id     = coder_agent.coder.id
  slug         = "jupyter"
  display_name = "JupyterLab"
  url          = "http://localhost:8888"
  icon         = "/icon/jupyter.svg"
  share        = "owner"
  subdomain    = true

  healthcheck {
    url       = "http://localhost:8888/healthz"
    interval  = 5
    threshold = 10
  }
}
```

Or Alternatively, you can use the JupyterLab module from the Coder registry:

```tf
module "jupyter" {
  source   = "registry.coder.com/modules/jupyter-lab/coder"
  version  = "1.0.0"
  agent_id = coder_agent.main.id
}
```

If you cannot enable a
[wildcard subdomain](../../../admin/setup/index.md#wildcard-access-url), you can
configure the template to run Jupyter on a path. There is however
[security risk](../../../reference/cli/server.md#--dangerous-allow-path-app-sharing)
running an app on a path and the template code is more complicated with coder
value substitution to recreate the path structure.

![JupyterLab in Coder](../../../images/jupyter.png)

## RStudio

Configure your agent and `coder_app` like so to use RStudio. Notice the
`subdomain=true` configuration:

```tf
resource "coder_agent" "coder" {
  os             = "linux"
  arch           = "amd64"
  dir            = "/home/coder"
  startup_script = <<EOT
#!/bin/bash
# start rstudio
/usr/lib/rstudio-server/bin/rserver --server-daemonize=1 --auth-none=1 &
EOT
}

resource "coder_app" "rstudio" {
  agent_id      = coder_agent.coder.id
  slug          = "rstudio"
  display_name  = "R Studio"
  icon          = "https://upload.wikimedia.org/wikipedia/commons/d/d0/RStudio_logo_flat.svg"
  url           = "http://localhost:8787"
  subdomain     = true
  share         = "owner"

  healthcheck {
    url       = "http://localhost:8787/healthz"
    interval  = 3
    threshold = 10
  }
}
```

If you cannot enable a
[wildcard subdomain](https://coder.com/docs/admin/setup#wildcard-access-url),
you can configure the template to run RStudio on a path using an NGINX reverse
proxy in the template. There is however
[security risk](https://coder.com/docs/reference/cli/server#--dangerous-allow-path-app-sharing)
running an app on a path and the template code is more complicated with coder
value substitution to recreate the path structure.

[This](https://github.com/sempie/coder-templates/tree/main/rstudio) is a
community template example.

![RStudio in Coder](../../../images/rstudio-port-forward.png)

## Airflow

Configure your agent and `coder_app` like so to use Airflow. Notice the
`subdomain=true` configuration:

```tf
resource "coder_agent" "coder" {
  os   = "linux"
  arch = "amd64"
  dir  = "/home/coder"
  startup_script = <<EOT
#!/bin/bash
# install and start airflow
pip3 install apache-airflow
/home/coder/.local/bin/airflow standalone &
EOT
}

resource "coder_app" "airflow" {
  agent_id      = coder_agent.coder.id
  slug          = "airflow"
  display_name  = "Airflow"
  icon          = "/icon/airflow.svg"
  url           = "http://localhost:8080"
  subdomain     = true
  share         = "owner"

  healthcheck {
    url       = "http://localhost:8080/healthz"
    interval  = 10
    threshold = 60
  }
}
```

or use the [Airflow module](https://registry.coder.com/modules/apache-airflow)
from the Coder registry:

```tf
module "airflow" {
  source   = "registry.coder.com/modules/airflow/coder"
  version  = "1.0.13"
  agent_id = coder_agent.main.id
}
```

![Airflow in Coder](../../../images/airflow-port-forward.png)

## File Browser

To access the contents of a workspace directory in a browser, you can use File
Browser. File Browser is a lightweight file manager that allows you to view and
manipulate files in a web browser.

Show and manipulate the contents of the `/home/coder` directory in a browser.

```tf
resource "coder_agent" "coder" {
  os   = "linux"
  arch = "amd64"
  dir  = "/home/coder"
  startup_script = <<EOT
#!/bin/bash

curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
filebrowser --noauth --root /home/coder --port 13339 >/tmp/filebrowser.log 2>&1 &

EOT
}

resource "coder_app" "filebrowser" {
  agent_id     = coder_agent.coder.id
  display_name = "file browser"
  slug         = "filebrowser"
  url          = "http://localhost:13339"
  icon         = "https://raw.githubusercontent.com/matifali/logos/main/database.svg"
  subdomain    = true
  share        = "owner"

  healthcheck {
    url       = "http://localhost:13339/healthz"
    interval  = 3
    threshold = 10
  }
}
```

Or alternatively, you can use the
[`filebrowser`](https://registry.coder.com/modules/filebrowser) module from the
Coder registry:

```tf
module "filebrowser" {
  source   = "registry.coder.com/modules/filebrowser/coder"
  version  = "1.0.8"
  agent_id = coder_agent.main.id
}
```

![File Browser](../../../images/file-browser.png)

## SSH Fallback

If you prefer to run web IDEs in localhost, you can port forward using
[SSH](../../../user-guides/workspace-access/index.md#ssh) or the Coder CLI
`port-forward` sub-command. Some web IDEs may not support URL base path
adjustment so port forwarding is the only approach.

---

# Pre-install JetBrains IDEs

Source: https://coder.com/docs/admin/templates/extending-templates/jetbrains-preinstall

# Pre-install JetBrains IDEs in your template

For a faster first time connection with JetBrains IDEs, pre-install the IDEs backend in your template.

> [!NOTE]
> This guide only talks about installing the IDEs backend. For a complete guide on setting up JetBrains Gateway with client IDEs, refer to the [JetBrains Gateway air-gapped guide](./jetbrains-airgapped.md).

## Install the Client Downloader

Install the JetBrains Client Downloader binary:

```shell
wget -O jetbrains-clients-downloader-linux-x86_64.tar.gz \
  'https://data.services.jetbrains.com/products/download?code=JCD&platform=linux_x86-64' && \
tar -xzvf jetbrains-clients-downloader-linux-x86_64.tar.gz
rm jetbrains-clients-downloader-linux-x86_64.tar.gz
```

## Install Gateway backend

```shell
mkdir ~/JetBrains
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64 --download-backends ~/JetBrains
```

For example, to install the build `243.26053.27` of IntelliJ IDEA:

```shell
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter IU --build-filter 243.26053.27 --platforms-filter linux-x64 --download-backends ~/JetBrains
tar -xzvf ~/JetBrains/backends/IU/*.tar.gz -C ~/JetBrains/backends/IU
rm -rf ~/JetBrains/backends/IU/*.tar.gz
```

## Register the Gateway backend

Add the following command to your template's `startup_script`:

```shell
~/JetBrains/*/bin/remote-dev-server.sh registerBackendLocationForGateway
```

## Configure JetBrains Gateway Module

If you are using our [jetbrains-gateway](https://registry.coder.com/modules/coder/jetbrains-gateway) module, you can configure it by adding the following snippet to your template:

```tf
module "jetbrains_gateway" {
  count          = data.coder_workspace.me.start_count
  source         = "registry.coder.com/modules/jetbrains-gateway/coder"
  version        = "1.0.29"
  agent_id       = coder_agent.main.id
  folder         = "/home/coder/example"
  jetbrains_ides = ["IU"]
  default        = "IU"
  latest         = false
  jetbrains_ide_versions = {
    "IU" = {
      build_number = "251.25410.129"
      version      = "2025.1"
    }
  }
}

resource "coder_agent" "main" {
    ...
    startup_script = <<-EOF
    ~/JetBrains/*/bin/remote-dev-server.sh registerBackendLocationForGateway
    EOF
}
```

## Dockerfile example

If you are using Docker based workspaces, you can add the command to your Dockerfile:

```dockerfile
FROM codercom/enterprise-base:ubuntu

# JetBrains IDE installation (configurable)
ARG IDE_CODE=IU
ARG IDE_VERSION=2025.1

# Fetch and install IDE dynamically
RUN mkdir -p ~/JetBrains \
    && IDE_URL=$(curl -s "https://data.services.jetbrains.com/products/releases?code=${IDE_CODE}&majorVersion=${IDE_VERSION}&latest=true" | jq -r ".${IDE_CODE}[0].downloads.linux.link") \
    && IDE_NAME=$(curl -s "https://data.services.jetbrains.com/products/releases?code=${IDE_CODE}&majorVersion=${IDE_VERSION}&latest=true" | jq -r ".${IDE_CODE}[0].name") \
    && echo "Installing ${IDE_NAME}..." \
    && wget -q ${IDE_URL} -P /tmp \
    && tar -xzf /tmp/$(basename ${IDE_URL}) -C ~/JetBrains \
    && rm -f /tmp/$(basename ${IDE_URL}) \
    && echo "${IDE_NAME} installed successfully"
```

## Next steps

- [Pre-install the Client IDEs](./jetbrains-airgapped.md#1-deploy-the-server-and-install-the-client-downloader)

---

# JetBrains IDEs in Air-Gapped Deployments

Source: https://coder.com/docs/admin/templates/extending-templates/jetbrains-airgapped

# JetBrains IDEs in an air-gapped environment

In networks that restrict access to the internet, you will need to leverage the
JetBrains Client Installer to download and save the IDE clients locally. Please
see the
[JetBrains documentation for more information](https://www.jetbrains.com/help/idea/fully-offline-mode.html).

This page is an example that the Coder team used as a proof-of-concept (POC) of the JetBrains Gateway Offline Mode solution.

We used Ubuntu on a virtual machine to test the steps.
If you have a suggestion or encounter an issue, please
[file a GitHub issue](https://github.com/coder/coder/issues/new?title=request%28docs%29%3A+jetbrains-airgapped+-+request+title+here%0D%0A&labels=["community","docs"]&body=doc%3A+%5Bjetbrains-airgapped%5D%28https%3A%2F%2Fcoder.com%2Fdocs%2Fuser-guides%2Fworkspace-access%2Fjetbrains%2Fjetbrains-airgapped%29%0D%0A%0D%0Aplease+enter+your+request+here%0D%0A).

## 1. Deploy the server and install the Client Downloader

Install the JetBrains Client Downloader binary. Note that the server must be a Linux-based distribution:

```shell
wget -O jetbrains-clients-downloader-linux-x86_64.tar.gz \
  'https://data.services.jetbrains.com/products/download?code=JCD&platform=linux_x86-64' && \
tar -xzvf jetbrains-clients-downloader-linux-x86_64.tar.gz
```

## 2. Install backends and clients

JetBrains Gateway requires both a backend to be installed on the remote host
(your Coder workspace) and a client to be installed on your local machine. You
can host both on the server in this example.

See here for the full
[JetBrains product list and builds](https://data.services.jetbrains.com/products).
Below is the full list of supported `--platforms-filter` values:

```console
windows-x64, windows-aarch64, linux-x64, linux-aarch64, osx-x64, osx-aarch64
```

To install both backends and clients, you will need to run two commands.

### Backends

```shell
mkdir ~/backends
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64,windows-x64,osx-x64 --download-backends ~/backends
```

### Clients

This is the same command as above, with the `--download-backends` flag removed.

```shell
mkdir ~/clients
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64,windows-x64,osx-x64 ~/clients
```

We now have both clients and backends installed.

## 3. Install a web server

You will need to run a web server in order to serve requests to the backend and
client files. We installed `nginx` and setup an FQDN and routed all requests to
`/`. See below:

```console
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                root /home/ubuntu;
        }
}
```

Then, configure your DNS entry to point to the IP address of the server. For the
purposes of the POC, we did not configure TLS, although that is a supported
option.

## 4. Add Client Files

You will need to add the following files on your local machine in order for
Gateway to pull the backend and client from the server.

```shell
$ cat productsInfoUrl # a path to products.json that was generated by the backend's downloader (it could be http://, https://, or file://)

https://internal.site/backends/<PRODUCT_CODE>/products.json

$ cat clientDownloadUrl # a path for clients that you got from the clients' downloader (it could be http://, https://, or file://)

https://internal.site/clients/

$ cat jreDownloadUrl # a path for JBR that you got from the clients' downloader (it could be http://, https://, or file://)

https://internal.site/jre/

$ cat pgpPublicKeyUrl # a URL to the KEYS file that was downloaded with the clients builds.

https://internal.site/KEYS
```

The location of these files will depend upon your local operating system:

<div class="tabs">

### macOS

```console
# User-specific settings
/Users/UserName/Library/Application Support/JetBrains/RemoteDev
# System-wide settings
/Library/Application Support/JetBrains/RemoteDev/
```

### Linux

```console
# User-specific settings
$HOME/.config/JetBrains/RemoteDev
# System-wide settings
/etc/xdg/JetBrains/RemoteDev/
```

### Windows

```console
# User-specific settings
HKEY_CURRENT_USER registry
# System-wide settings
HKEY_LOCAL_MACHINE registry
```

Additionally, create a string for each setting with its appropriate value in
`SOFTWARE\JetBrains\RemoteDev`:

![JetBrains offline - Windows](../../../images/gateway/jetbrains-offline-windows.png)

</div>

## 5. Setup SSH connection with JetBrains Gateway

With the server now configured, you can now configure your local machine to use
Gateway. Here is the documentation to
[setup SSH config via the Coder CLI](../../../user-guides/workspace-access/index.md#configure-ssh).
On the Gateway side, follow our guide here until step 16.

Instead of downloading from jetbrains.com, we will point Gateway to our server
endpoint. Select `Installation options...` and select `Use download link`. Note
that the URL must explicitly reference the archive file:

![Offline Gateway](../../../images/gateway/offline-gateway.png)

Click `Download IDE and Connect`. Gateway should now download the backend and
clients from the server into your remote workspace and local machine,
respectively.

## Next steps

- [Pre-install the JetBrains IDEs backend in your workspace](./jetbrains-preinstall.md)

---

# Docker in Workspaces

Source: https://coder.com/docs/admin/templates/extending-templates/docker-in-workspaces

# Docker in Workspaces

There are a few ways to run Docker within container-based Coder workspaces.

| Method                                                     | Description                                                                                                                                                        | Limitations                                                                                                                                                                                                                                        |
|------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Sysbox container runtime](#sysbox-container-runtime)      | Install the Sysbox runtime on your Kubernetes nodes or Docker host(s) for secure docker-in-docker and systemd-in-docker. Works with GKE, EKS, AKS, Docker.         | Requires [compatible nodes](https://github.com/nestybox/sysbox#host-requirements). [Limitations](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/limitations.md)                                                                    |
| [Envbox](#envbox)                                          | A container image with all the packages necessary to run an inner Sysbox container. Removes the need to setup sysbox-runc on your nodes. Works with GKE, EKS, AKS. | Requires running the outer container as privileged (the inner container that acts as the workspace is locked down). Requires compatible [nodes](https://github.com/nestybox/sysbox/blob/master/docs/distro-compat.md#sysbox-distro-compatibility). |
| [Rootless Podman](#rootless-podman)                        | Run Podman inside Coder workspaces. Does not require a custom runtime or privileged containers. Works with GKE, EKS, AKS, RKE, OpenShift                           | Requires smarter-device-manager for FUSE mounts. [See all](https://github.com/containers/podman/blob/main/rootless.md#shortcomings-of-rootless-podman)                                                                                             |
| [Privileged docker sidecar](#privileged-sidecar-container) | Run Docker as a privileged sidecar container.                                                                                                                      | Requires a privileged container. Workspaces can break out to root on the host machine.                                                                                                                                                             |

## Sysbox container runtime

The [Sysbox](https://github.com/nestybox/sysbox) container runtime allows
unprivileged users to run system-level applications, such as Docker, securely
from the workspace containers. Sysbox requires a
[compatible Linux distribution](https://github.com/nestybox/sysbox/blob/master/docs/distro-compat.md)
to implement these security features. Sysbox can also be used to run systemd
inside Coder workspaces. See [Systemd in Docker](#systemd-in-docker).

### Use Sysbox in Docker-based templates

After [installing Sysbox](https://github.com/nestybox/sysbox#installation) on
the Coder host, modify your template to use the sysbox-runc runtime:

```tf
resource "docker_container" "workspace" {
  # ...
  name    = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
  image   = "codercom/enterprise-base:ubuntu"
  env     = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
  command = ["sh", "-c", coder_agent.main.init_script]
  # Use the Sysbox container runtime (required)
  runtime = "sysbox-runc"
}

resource "coder_agent" "main" {
  arch           = data.coder_provisioner.me.arch
  os             = "linux"
  startup_script = <<-EOF
    #!/bin/sh
    set -e
    sudo service docker start
  EOF
}
```

### Use Sysbox in Kubernetes-based templates

After
[installing Sysbox on Kubernetes](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/install-k8s.md),
modify your template to use the sysbox-runc RuntimeClass. This requires the
Kubernetes Terraform provider version 2.16.0 or greater.

```tf
terraform {
  required_providers {
    coder = {
      source  = "coder/coder"
    }
    kubernetes = {
      source = "hashicorp/kubernetes"
      version = "2.16.0"
    }
  }
}

variable "workspaces_namespace" {
  default = "coder-namespace"
}

data "coder_workspace" "me" {}

resource "coder_agent" "main" {
  os   = "linux"
  arch = "amd64"
  dir  = "/home/coder"
  startup_script = <<-EOF
    #!/bin/sh
    set -e
    sudo service docker start
  EOF
}

resource "kubernetes_pod" "dev" {
  count = data.coder_workspace.me.start_count
  metadata {
    name      = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
    namespace = var.workspaces_namespace
    annotations = {
      "io.kubernetes.cri-o.userns-mode" = "auto:size=65536"
    }
  }

  spec {
  runtime_class_name = "sysbox-runc"
  # Use the Sysbox container runtime (required)
    security_context {
      run_as_user = 1000
      fs_group    = 1000
    }
    container {
      name = "dev"
      env {
        name  = "CODER_AGENT_TOKEN"
        value = coder_agent.main.token
      }
      image = "codercom/enterprise-base:ubuntu"
      command = ["sh", "-c", coder_agent.main.init_script]
    }
  }
}
```

## Envbox

[Envbox](https://github.com/coder/envbox) is an image developed and maintained
by Coder that bundles the sysbox runtime. It works by starting an outer
container that manages the various sysbox daemons and spawns an unprivileged
inner container that acts as the user's workspace. The inner container is able
to run system-level software similar to a regular virtual machine (e.g.
`systemd`, `dockerd`, etc). Envbox offers the following benefits over running
sysbox directly on the nodes:

- No custom runtime installation or management on your Kubernetes nodes.
- No limit to the number of pods that run envbox.

Some drawbacks include:

- The outer container must be run as privileged
  - Note: the inner container is _not_ privileged. For more information on the
    security of sysbox containers see sysbox's
    [official documentation](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/security.md).
- Initial workspace startup is slower than running `sysbox-runc` directly on the
  nodes. This is due to `envbox` having to pull the image to its own Docker
  cache on its initial startup. Once the image is cached in `envbox`, startup
  performance is similar.

Envbox requires the same kernel requirements as running sysbox directly on the
nodes. Refer to sysbox's
[compatibility matrix](https://github.com/nestybox/sysbox/blob/master/docs/distro-compat.md#sysbox-distro-compatibility)
to ensure your nodes are compliant.

To get started with `envbox` check out the
[starter template](https://github.com/coder/coder/tree/main/examples/templates/kubernetes-envbox)
or visit the [repo](https://github.com/coder/envbox).

### Authenticating with a Private Registry

Authenticating with a private container registry can be done by referencing the
credentials via the `CODER_IMAGE_PULL_SECRET` environment variable. It is
encouraged to populate this
[environment variable](https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data)
by using a Kubernetes
[secret](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials).

Refer to your container registry documentation to understand how to best create
this secret.

The following shows a minimal example using a the JSON API key from a GCP
service account to pull a private image:

```bash
# Create the secret
$ kubectl create secret docker-registry <name> \
  --docker-server=us.gcr.io \
  --docker-username=_json_key \
  --docker-password="$(cat ./json-key-file.yaml)" \
  --docker-email=<service-account-email>
```

```tf
env {
  name = "CODER_IMAGE_PULL_SECRET"
  value_from {
    secret_key_ref {
      name = "<name>"
      key = ".dockerconfigjson"
    }
  }
}
```

## Rootless podman

[Podman](https://docs.podman.io/en/latest/) is Docker alternative that is
compatible with OCI containers specification. which can run rootless inside
Kubernetes pods. No custom RuntimeClass is required.

Before using Podman, please review the following documentation:

- [Basic setup and use of Podman in a rootless environment](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md)

- [Shortcomings of Rootless Podman](https://github.com/containers/podman/blob/main/rootless.md#shortcomings-of-rootless-podman)

1. Enable
   [smart-device-manager](https://github.com/smarter-project/smarter-device-manager#enabling-access)
   to securely expose a FUSE devices to pods.

   ```shell
   cat <<EOF | kubectl create -f -
   apiVersion: apps/v1
   kind: DaemonSet
   metadata:
     name: fuse-device-plugin-daemonset
     namespace: kube-system
   spec:
     selector:
       matchLabels:
         name: fuse-device-plugin-ds
     template:
       metadata:
         labels:
           name: fuse-device-plugin-ds
       spec:
         hostNetwork: true
         containers:
         - name: fuse-device-plugin-ctr
           image: soolaugust/fuse-device-plugin:v1.0
           securityContext:
             allowPrivilegeEscalation: false
             capabilities:
               drop: ["ALL"]
           volumeMounts:
           - name: device-plugin
             mountPath: /var/lib/kubelet/device-plugins
         volumes:
         - name: device-plugin
           hostPath:
             path: /var/lib/kubelet/device-plugins
         imagePullSecrets:
         - name: registry-secret
   EOF
   ```

2. Be sure to label your nodes to enable smarter-device-manager:

   ```shell
   kubectl get nodes
   kubectl label nodes --all smarter-device-manager=enabled
   ```

   > ⚠️ **Warning**: If you are using a managed Kubernetes distribution (e.g.
   > AKS, EKS, GKE), be sure to set node labels via your cloud provider.
   > Otherwise, your nodes may drop the labels and break podman functionality.

3. For systems running SELinux (typically Fedora-, CentOS-, and Red Hat-based
   systems), you might need to disable SELinux or set it to permissive mode.

4. Use this
   [kubernetes-with-podman](https://github.com/coder/community-templates/tree/main/kubernetes-podman)
   example template, or make your own.

   ```shell
   echo "kubernetes-with-podman" | coder templates init
   cd ./kubernetes-with-podman
   coder templates create
   ```

   > For more information around the requirements of rootless podman pods, see:
   > [How to run Podman inside of Kubernetes](https://www.redhat.com/sysadmin/podman-inside-kubernetes)

### Rootless Podman on Bottlerocket nodes

Rootless containers rely on Linux user-namespaces.
[Bottlerocket](https://github.com/bottlerocket-os/bottlerocket) disables them by default (`user.max_user_namespaces = 0`), so Podman commands will return an error until you raise the limit:

```output
cannot clone: Invalid argument
user namespaces are not enabled in /proc/sys/user/max_user_namespaces
```

1. Add a `user.max_user_namespaces` value to your Bottlerocket user data to use rootless Podman on the node:

  ```toml
  [settings.kernel.sysctl]
  "user.max_user_namespaces" = "65536"
  ```

1. Reboot the node.
1. Verify that the value is more than `0`:

  ```shell
  sysctl -n user.max_user_namespaces
  ```

For Karpenter-managed Bottlerocket nodes, add the `user.max_user_namespaces` setting in your `EC2NodeClass`:

```yaml
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: bottlerocket-rootless
spec:
  amiFamily: Bottlerocket # required for BR-style userData
  # …
  userData: |
    [settings.kernel]
    sysctl = { "user.max_user_namespaces" = "65536" }
```

## Privileged sidecar container

A
[privileged container](https://docs.docker.com/engine/containers/run/#runtime-privilege-and-linux-capabilities)
can be added to your templates to add docker support. This may come in handy if
your nodes cannot run Sysbox.

> [!WARNING]
> This is insecure. Workspaces will be able to gain root access to the host machine.

### Use a privileged sidecar container in Docker-based templates

```tf
resource "coder_agent" "main" {
  os             = "linux"
  arch           = "amd64"
}

resource "docker_network" "private_network" {
  name = "network-${data.coder_workspace.me.id}"
}

resource "docker_container" "dind" {
  image      = "docker:dind"
  privileged = true
  name       = "dind-${data.coder_workspace.me.id}"
  entrypoint = ["dockerd", "-H", "tcp://0.0.0.0:2375"]
  networks_advanced {
    name = docker_network.private_network.name
  }
}

resource "docker_container" "workspace" {
  count   = data.coder_workspace.me.start_count
  image   = "codercom/enterprise-base:ubuntu"
  name    = "dev-${data.coder_workspace.me.id}"
  command = ["sh", "-c", coder_agent.main.init_script]
  env = [
    "CODER_AGENT_TOKEN=${coder_agent.main.token}",
    "DOCKER_HOST=${docker_container.dind.name}:2375"
  ]
  networks_advanced {
    name = docker_network.private_network.name
  }
}
```

### Use a privileged sidecar container in Kubernetes-based templates

```tf
terraform {
  required_providers {
    coder = {
      source  = "coder/coder"
    }
    kubernetes = {
      source = "hashicorp/kubernetes"
      version = "2.16.0"
    }
  }
}

variable "workspaces_namespace" {
  default = "coder-namespace"
}

data "coder_workspace" "me" {}

resource "coder_agent" "main" {
  os             = "linux"
  arch           = "amd64"
}

resource "kubernetes_pod" "main" {
  count = data.coder_workspace.me.start_count
  metadata {
    name      = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
    namespace = var.namespace
  }
  spec {
    # Run a privileged dind (Docker in Docker) container
    container {
      name  = "docker-sidecar"
      image = "docker:dind"
      security_context {
        privileged = true
        run_as_user = 0
      }
      command = ["dockerd", "-H", "tcp://127.0.0.1:2375"]
    }
    container {
      name    = "dev"
      image   = "codercom/enterprise-base:ubuntu"
      command = ["sh", "-c", coder_agent.main.init_script]
      security_context {
        run_as_user = "1000"
      }
      env {
        name  = "CODER_AGENT_TOKEN"
        value = coder_agent.main.token
      }
      # Use the Docker daemon in the "docker-sidecar" container
      env {
        name  = "DOCKER_HOST"
        value = "localhost:2375"
      }
    }
  }
}
```

## Systemd in Docker

Additionally, [Sysbox](https://github.com/nestybox/sysbox) can be used to give
workspaces full `systemd` capabilities.

After
[installing Sysbox on Kubernetes](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/install-k8s.md),
modify your template to use the sysbox-runc RuntimeClass. This requires the
Kubernetes Terraform provider version 2.16.0 or greater.

```tf
terraform {
  required_providers {
    coder = {
      source  = "coder/coder"
    }
    kubernetes = {
      source = "hashicorp/kubernetes"
      version = "2.16.0"
    }
  }
}

variable "workspaces_namespace" {
  default = "coder-namespace"
}

data "coder_workspace" "me" {}

resource "coder_agent" "main" {
  os   = "linux"
  arch = "amd64"
  dir  = "/home/coder"
}

resource "kubernetes_pod" "dev" {
  count = data.coder_workspace.me.start_count
  metadata {
    name      = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
    namespace = var.workspaces_namespace
    annotations = {
      "io.kubernetes.cri-o.userns-mode" = "auto:size=65536"
    }
  }

  spec {

    # Use Sysbox container runtime (required)
    runtime_class_name = "sysbox-runc"

    # Run as root in order to start systemd (required)
    security_context {
      run_as_user = 0
      fs_group    = 0
    }

    container {
      name = "dev"
      env {
        name  = "CODER_AGENT_TOKEN"
        value = coder_agent.main.token
      }
      image = "codercom/enterprise-base:ubuntu"
      command = ["sh", "-c", <<EOF
    # Start the Coder agent as the "coder" user
    # once systemd has started up
    sudo -u coder --preserve-env=CODER_AGENT_TOKEN /bin/bash -- <<-'    EOT' &
    while [[ ! $(systemctl is-system-running) =~ ^(running|degraded) ]]
    do
      echo "Waiting for system to start... $(systemctl is-system-running)"
      sleep 2
    done
    ${coder_agent.main.init_script}
    EOT

    exec /sbin/init
    EOF
      ]
    }
  }
}
```

---

# Workspace Tags

Source: https://coder.com/docs/admin/templates/extending-templates/workspace-tags

# Workspace Tags

Template administrators can leverage static template tags to limit workspace
provisioning to designated provisioner groups that have locally deployed
credentials for creating workspace resources. While this method ensures
controlled access, it offers limited flexibility and does not permit users to
select the nodes for their workspace creation.

By using `coder_workspace_tags` and `coder_parameter`s, template administrators
can enable dynamic tag selection and modify static template tags.

## Dynamic tag selection

Here is a sample `coder_workspace_tags` data resource with a few workspace tags
specified:

```tf
data "coder_workspace_tags" "custom_workspace_tags" {
  tags = {
    "az"          = var.az
    "zone"        = "developers"
    "runtime"     = data.coder_parameter.runtime_selector.value
    "project_id"  = "PROJECT_${data.coder_parameter.project_name.value}"
    "cache"       = data.coder_parameter.feature_cache_enabled.value == "true" ? "with-cache" : "no-cache"
  }
}
```

### Legend

- `zone` - static tag value set to `developers`
- `runtime` - supported by the string-type `coder_parameter` to select
  provisioner runtime, `runtime_selector`
- `project_id` - a formatted string supported by the string-type
  `coder_parameter`, `project_name`
- `cache` - an HCL condition involving boolean-type `coder_parameter`,
  `feature_cache_enabled`

Review the
[full template example](https://github.com/coder/coder/tree/main/examples/workspace-tags)
using `coder_workspace_tags` and `coder_parameter`s.

## How it Works

In order to correctly import a template that defines tags in
`coder_workspace_tags`, Coder needs to know the tags to assign the template
import job ahead of time. To work around this chicken-and-egg problem, Coder
performs static analysis of the Terraform to determine a reasonable set of tags
to assign to the template import job. This happens _before_ the job is started.

When the template is imported, Coder will then store the _raw_ Terraform
expressions for the values of the workspace tags for that template version. The
next time a workspace is created from that template, Coder retrieves the stored
raw values from the database and evaluates them using provided template
variables and parameters. This is illustrated in the table below:

| Value Type | Template Import                                    | Workspace Creation      |
|------------|----------------------------------------------------|-------------------------|
| Static     | `{"region": "us"}`                                 | `{"region": "us"}`      |
| Variable   | `{"az": var.az}`                                   | `{"region": "us-east"}` |
| Parameter  | `{"cluster": data.coder_parameter.cluster.value }` | `{"cluster": "dev"}`    |

## Constraints

### Tagged provisioners

It is possible to choose tag combinations that no provisioner can handle. This
will cause the provisioner job to get stuck in the queue until a provisioner is
added that can handle its combination of tags.

Before releasing the template version with configurable workspace tags, ensure
that every tag set is associated with at least one healthy provisioner.

> [!NOTE]
> It may be useful to run at least one provisioner with no additional
> tag restrictions that is able to take on any job.
>
> `coder_workspace_tags` are cumulative.
> Jobs will only match provisioners that have all tags defined in both your template configuration and `coder_workspace_tags`.

### Parameters types

Provisioners require job tags to be defined in plain string format. When a
workspace tag refers to a `coder_parameter` without involving the string
formatter, for example,
(`"runtime" = data.coder_parameter.runtime_selector.value`), the Coder
provisioner server can transform only the following parameter types to strings:
_string_, _number_, and _bool_.

### Mutability

A mutable `coder_parameter` can be dangerous for a workspace tag as it allows
the workspace owner to change a provisioner group (due to different tags). In
most cases, `coder_parameter`s backing `coder_workspace_tags` should be marked
as immutable and set only once, during workspace creation.

You may only specify the following as inputs for `coder_workspace_tags`:

|                    | Example                                       |
|:-------------------|:----------------------------------------------|
| Static values      | `"developers"`                                |
| Template variables | `var.az`                                      |
| Coder parameters   | `data.coder_parameter.runtime_selector.value` |

Passing template tags in from other data sources or resources is not permitted.

### HCL syntax

When importing the template version with `coder_workspace_tags`, the Coder
provisioner server extracts raw partial queries for each workspace tag and
stores them in the database. During workspace build time, the Coder server uses
the [Hashicorp HCL library](https://github.com/hashicorp/hcl) to evaluate these
raw queries on-the-fly without processing the entire Terraform template. This
evaluation is simpler but also limited in terms of available functions,
variables, and references to other resources.

#### Supported syntax

- Static string: `foobar_tag = "foobaz"`
- Formatted string: `foobar_tag = "foobaz ${data.coder_parameter.foobaz.value}"`
- Reference to `coder_parameter`:
  `foobar_tag = data.coder_parameter.foobar.value`
- Boolean logic: `production_tag = !data.coder_parameter.staging_env.value`
- Condition:
  `cache = data.coder_parameter.feature_cache_enabled.value == "true" ? "with-cache" : "no-cache"`

#### Not supported

- Function calls that reference files on disk: `abspath`, `file*`, `pathexpand`
- Resources: `compute_instance.dev.name`
- Data sources other than `coder_parameter`: `data.local_file.hostname.content`

---

# Provider Authentication

Source: https://coder.com/docs/admin/templates/extending-templates/provider-authentication

# Provider Authentication

> [!CAUTION]
> Do not store secrets in templates. Assume every user has cleartext access to every template.

The Coder server's
[provisioner](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/provisioner)
process needs to authenticate with other provider APIs to provision workspaces.
There are two approaches to do this:

- Pass credentials to the provisioner as parameters.
- Preferred: Execute the Coder server in an environment that is authenticated
  with the provider.

We encourage the latter approach where supported:

- Simplifies the template.
- Keeps provider credentials out of Coder's database, making it a less valuable
  target for attackers.
- Compatible with agent-based authentication schemes, which handle credential
  rotation or ensure the credentials are not written to disk.

Generally, you can set up an environment to provide credentials to Coder in
these ways:

- A well-known location on disk. For example, `~/.aws/credentials` for AWS on
  POSIX systems.
- Environment variables.

It is usually sufficient to authenticate using the CLI or SDK for the provider
before running Coder, but check the Terraform provider's documentation for
details.

These platforms have Terraform providers that support authenticated
environments:

- [Google Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs)
- [Amazon Web Services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)
- [Microsoft Azure](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs)
- [Kubernetes](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs)
- [Docker](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs)

## Use a remote Docker host for authentication

There are two ways to use a remote Docker host for authentication:

- Configure the Docker provider to use a
  [remote host over SSH or TCP](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs#remote-hosts).
- Run an [external provisioner](../../provisioners/index.md) on the remote docker
  host.

Other providers might also support authenticated environments. Check the
[documentation of the Terraform provider](https://registry.terraform.io/browse/providers)
for details.

---

# Dev Containers

Source: https://coder.com/docs/admin/templates/extending-templates/devcontainers

# Dev Containers

Dev containers extend your template with containerized development environments,
allowing developers to work in consistent, reproducible setups defined by
`devcontainer.json` files.

Coder's Dev Containers Integration uses the standard `@devcontainers/cli` and
Docker to run containers inside workspaces.

For setup instructions, see
[Dev Containers Integration](../../integrations/devcontainers/integration.md).

For an alternative approach that doesn't require Docker, see
[Envbuilder](../../integrations/devcontainers/envbuilder/index.md).

---

# Improving Agent Resiliency

Source: https://coder.com/docs/admin/templates/extending-templates/process-priority

# Improving Agent Resiliency

Coder's agent can automatically lower the scheduling priority
and raise the OOM (out-of-memory) kill score of user processes
so the agent itself stays alive under resource pressure.

## Prerequisites

- **Linux** — The feature is ignored on other operating systems.
- **`CAP_SYS_NICE`** — Required if the agent needs to lower
  the nice value below its current value. In Kubernetes, add
  it to the container's security context:

  ```hcl
  container {
    security_context {
      capabilities {
        add = ["CAP_SYS_NICE"]
      }
    }
  }
  ```

## Environment variables

Configure the feature with environment variables in the
environment that launches the agent binary. These must be set
on the workspace container or host, not in the `coder_agent`
resource's `env` block — the agent reads them from its own
process environment at startup.

| Variable                | Required | Default                       | Description                                                                                                                                                                                   |
|-------------------------|----------|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `CODER_PROC_PRIO_MGMT`  | Yes      | —                             | Set to enable the feature. The agent checks whether the variable is present, not its value — even an empty string enables it. Use `1` by convention. To disable, unset the variable entirely. |
| `CODER_PROC_OOM_SCORE`  | No       | Computed from agent's score   | Explicit `oom_score_adj` value for child processes. Range: `-1000` to `1000`.                                                                                                                 |
| `CODER_PROC_NICE_SCORE` | No       | Agent nice + 5 (capped at 19) | Explicit nice value for child processes. Range: `-20` to `19` (higher = lower priority).                                                                                                      |

### OOM score defaults

If you do not set `CODER_PROC_OOM_SCORE`, the agent computes a
value based on its own `oom_score_adj`:

| Agent's `oom_score_adj` | Child score | Rationale                                      |
|-------------------------|-------------|------------------------------------------------|
| Negative (< 0)          | `0`         | Children are treated as normal processes.      |
| >= 998                  | `1000`      | Children get the maximum score (killed first). |
| Any other value         | `998`       | Children get a near-maximum score.             |

The goal is for the kernel's OOM killer to target child
processes before the agent, keeping remote connectivity alive
even when a workspace runs out of memory.

### Nice score defaults

If you do not set `CODER_PROC_NICE_SCORE`, the agent sets
children to its own nice value plus 5, capped at 19. This
gives the agent more CPU scheduling priority than user
workloads.

## Example

The following Kubernetes template snippet enables process
priority management on the workspace container:

```hcl
resource "kubernetes_deployment" "workspace" {
  # ... other configuration

  spec {
    template {
      spec {
        container {
          name  = "dev"
          image = "codercom/enterprise-base:ubuntu"

          env {
            name  = "CODER_AGENT_TOKEN"
            value = coder_agent.main.token
          }
          env {
            name  = "CODER_PROC_PRIO_MGMT"
            value = "1"
          }
          env {
            name  = "CODER_PROC_OOM_SCORE"
            value = "10"
          }
          env {
            name  = "CODER_PROC_NICE_SCORE"
            value = "1"
          }

          security_context {
            capabilities {
              add = ["CAP_SYS_NICE"]
            }
          }
        }
      }
    }
  }
}
```

- `CODER_PROC_OOM_SCORE=10` gives child processes a slightly
  elevated OOM score while keeping them well below the maximum.
- `CODER_PROC_NICE_SCORE=1` gives children a mildly lower CPU
  priority than the agent.
- `CAP_SYS_NICE` allows the agent to set nice values.

## Troubleshooting

### OOM score adjustment fails

If you see `failed to adjust oom score` in stderr but the
process still starts, the agent likely lacks permission to
write to `/proc/self/oom_score_adj`. Ensure the process is
dumpable — this is handled automatically by the agent, but
can fail if the container runtime restricts `prctl` calls.

### Nice value is not applied

If you see `failed to adjust niceness` in stderr, nice values
can only be increased (lowered in priority) without
`CAP_SYS_NICE`. If your template sets a `CODER_PROC_NICE_SCORE`
lower than the agent's current nice value, add the capability
to the container's security context.

### Environment variables leak to nested Coder agents

The agent strips all `CODER_PROC_*` variables from child
environments automatically. This prevents interference in
"Coder on Coder" development scenarios where a workspace
runs another Coder agent.

### Verifying the feature is enabled

The agent logs whether process priority management is active
at startup. Look for these lines in the agent log:

```text
"process priority management enabled"
"process priority management not enabled (linux-only)"
```

The log entry includes the `CODER_PROC_PRIO_MGMT` value and
the operating system. Check the agent log file at
`<log-dir>/coder-agent.log` or stderr output.

### Feature has no effect on macOS or Windows

Process priority management is Linux-only. Setting
`CODER_PROC_PRIO_MGMT` on other operating systems is safe
but has no effect.

---

# Process Logging

Source: https://coder.com/docs/admin/templates/extending-templates/process-logging

# Workspace Process Logging

The workspace process logging feature allows you to log all system-level
processes executing in the workspace.

This feature is only available on Linux in Kubernetes. There are
additional requirements outlined further in this document.

> [!NOTE]
> Workspace process logging is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Workspace process logging adds a sidecar container to workspace pods that will
log all processes started in the workspace container (e.g., commands executed in
the terminal or processes created in the background by other processes).
Processes launched inside containers or nested containers within the workspace
are also logged. You can view the output from the sidecar or send it to a
monitoring stack, such as CloudWatch, for further analysis or long-term storage.

Please note that these logs are not recorded or captured by the Coder
organization in any way, shape, or form.

## How this works

Coder uses [eBPF](https://ebpf.io/) (which we chose for its minimal performance
impact) to perform in-kernel logging and filtering of all exec system calls
originating from the workspace container.

The core of this feature is also open source and can be found in the
[exectrace](https://github.com/coder/exectrace) GitHub repo. The enterprise
component (in the `enterprise/` directory of the repo) is responsible for
starting the eBPF program with the correct filtering options for the specific
workspace.

## Requirements

The host machine must be running a Linux kernel >= 5.8 with the kernel config
`CONFIG_DEBUG_INFO_BTF=y` enabled.

To check your kernel version, run:

```shell
uname -r
```

To validate the required kernel config is enabled, run either of the following
commands on your nodes directly (_not_ from a workspace terminal):

```shell
cat /proc/config.gz | gunzip | grep CONFIG_DEBUG_INFO_BTF
```

```shell
cat "/boot/config-$(uname -r)" | grep CONFIG_DEBUG_INFO_BTF
```

If these requirements are not met, workspaces will fail to start for security
reasons.

Your template must be a Kubernetes template. Workspace process logging is not
compatible with the `sysbox-runc` runtime due to technical limitations, but it
is compatible with our `envbox` template family.

## Example templates

We provide working example templates for Kubernetes, and Kubernetes with
`envbox` (for [Docker support in workspaces](./docker-in-workspaces.md)). You
can view these templates in the
[exectrace repo](https://github.com/coder/exectrace/tree/main/enterprise/templates).

## Configuring custom templates to use workspace process logging

If you have an existing Kubernetes or Kubernetes with `envbox` template that you
would like to add workspace process logging to, follow these steps:

1. Ensure the image used in your template has `curl` installed.

1. Add the following section to your template's `main.tf` file:

   <!--
     If you are updating this section, please also update the example templates
     in the exectrace repo.
   -->

   ```hcl
   locals {
     # This is the init script for the main workspace container that runs before the
     # agent starts to configure workspace process logging.
     exectrace_init_script = <<EOT
       set -eu
       pidns_inum=$(readlink /proc/self/ns/pid | sed 's/[^0-9]//g')
       if [ -z "$pidns_inum" ]; then
         echo "Could not determine process ID namespace inum"
         exit 1
       fi

       # Before we start the script, does curl exist?
       if ! command -v curl >/dev/null 2>&1; then
         echo "curl is required to download the Coder binary"
         echo "Please install curl to your image and try again"
         # 127 is command not found.
         exit 127
       fi

       echo "Sending process ID namespace inum to exectrace sidecar"
       rc=0
       max_retry=5
       counter=0
       until [ $counter -ge $max_retry ]; do
         set +e
         curl \
           --fail \
           --silent \
           --connect-timeout 5 \
           -X POST \
           -H "Content-Type: text/plain" \
           --data "$pidns_inum" \
           http://127.0.0.1:56123
         rc=$?
         set -e
         if [ $rc -eq 0 ]; then
           break
         fi

         counter=$((counter+1))
         echo "Curl failed with exit code $${rc}, attempt $${counter}/$${max_retry}; Retrying in 3 seconds..."
         sleep 3
       done
       if [ $rc -ne 0 ]; then
         echo "Failed to send process ID namespace inum to exectrace sidecar"
         exit $rc
       fi

     EOT
   }
   ```

1. Update the `command` of your workspace container like the following:

   <!--
     If you are updating this section, please also update the example templates
     in the exectrace repo.
   -->

   ```hcl
   resource "kubernetes_pod" "main" {
     ...
     spec {
       ...
       container {
         ...
         // NOTE: this command is changed compared to the upstream kubernetes
         // template
         command = [
           "sh",
           "-c",
           "${local.exectrace_init_script}\n\n${coder_agent.main.init_script}",
         ]
         ...
       }
       ...
     }
     ...
   }
   ```

   > [!NOTE]
   > If you are using the `envbox` template, you will need to update
   > the third argument to be
   > `"${local.exectrace_init_script}\n\nexec /envbox docker"` instead.

1. Add the following container to your workspace pod spec.

   <!--
     If you are updating this section, please also update the example templates
     in the exectrace repo.
   -->

   ```hcl
   resource "kubernetes_pod" "main" {
     ...
     spec {
       ...
       // NOTE: this container is added compared to the upstream kubernetes
       // template
       container {
         name              = "exectrace"
         image             = "ghcr.io/coder/exectrace:latest"
         image_pull_policy = "Always"
         command = [
           "/opt/exectrace",
           "--init-address", "127.0.0.1:56123",
           "--label", "workspace_id=${data.coder_workspace.me.id}",
           "--label", "workspace_name=${data.coder_workspace.me.name}",
           "--label", "user_id=${data.coder_workspace_owner.me.id}",
           "--label", "username=${data.coder_workspace_owner.me.name}",
           "--label", "user_email=${data.coder_workspace_owner.me.email}",
         ]
         security_context {
           // exectrace must be started as root so it can attach probes into the
           // kernel to record process events with high throughput.
           run_as_user  = "0"
           run_as_group = "0"
           // exectrace requires a privileged container so it can control mounts
           // and perform privileged syscalls against the host kernel to attach
           // probes.
           privileged = true
         }
       }
       ...
     }
     ...
   }
   ```

   > [!NOTE]
   > `exectrace` requires root privileges and a privileged container
   > to attach probes to the kernel. This is a requirement of eBPF.

1. Add the following environment variable to your workspace pod:

   <!--
     If you are updating this section, please also update the example templates
     in the exectrace repo.
   -->

   ```hcl
   resource "kubernetes_pod" "main" {
     ...
     spec {
       ...
       env {
         name = "CODER_AGENT_SUBSYSTEM"
         value = "exectrace"
       }
       ...
     }
     ...
   }
   ```

Once you have made these changes, you can push a new version of your template
and workspace process logging will be enabled for all workspaces once they are
restarted.

## Viewing workspace process logs

To view the process logs for a specific workspace you can use `kubectl` to print
the logs:

```bash
kubectl logs pod-name --container exectrace
```

The raw logs will look something like this:

```json
{
    "ts": "2022-02-28T20:29:38.038452202Z",
    "level": "INFO",
    "msg": "exec",
    "fields": {
        "labels": {
            "user_email": "jessie@coder.com",
            "user_id": "5e876e9a-121663f01ebd1522060d5270",
            "username": "jessie",
            "workspace_id": "621d2e52-a6987ef6c56210058ee2593c",
            "workspace_name": "main"
        },
        "cmdline": "uname -a",
        "event": {
            "filename": "/usr/bin/uname",
            "argv": ["uname", "-a"],
            "truncated": false,
            "pid": 920684,
            "uid": 101000,
            "gid": 101000,
            "comm": "bash"
        }
    }
}
```

### View logs in AWS EKS

If you're using AWS' Elastic Kubernetes Service, you can
[configure your cluster](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-EKS-logs.html)
to send logs to CloudWatch. This allows you to view the logs for a specific user
or workspace.

To view your logs, go to the CloudWatch dashboard (which is available on the
**Log Insights** tab) and run a query similar to the following:

```text
fields @timestamp, log_processed.fields.cmdline
| sort @timestamp asc
| filter kubernetes.container_name="exectrace"
| filter log_processed.fields.labels.username="zac"
| filter log_processed.fields.labels.workspace_name="code"
```

## Usage considerations

- The sidecar attached to each workspace is a privileged container, so you may
  need to review your organization's security policies before enabling this
  feature. Enabling workspace process logging does _not_ grant extra privileges
  to the workspace container itself, however.
- `exectrace` will log processes from nested Docker containers (including deeply
  nested containers) correctly, but Coder does not distinguish between processes
  started in the workspace and processes started in a child container in the
  logs.
- With `envbox` workspaces, this feature will detect and log startup processes
  begun in the outer container (including container initialization processes).
- Because this feature logs **all** processes in the workspace, high levels of
  usage (e.g., during a `make` run) will result in an abundance of output in the
  sidecar container. Depending on how your Kubernetes cluster is configured, you
  may incur extra charges from your cloud provider to store the additional logs.

---

# Startup Dependencies

Source: https://coder.com/docs/admin/templates/startup-coordination

# Workspace Startup Coordination

> [!NOTE]
> This feature is experimental and may change without notice in future releases.

When workspaces start, scripts often need to run in a specific order.
For example, an IDE or coding agent might need the repository cloned
before it can start. Without explicit coordination, these scripts can
race against each other, leading to startup failures and inconsistent
workspace states.

Coder's workspace startup coordination feature lets you declare
dependencies between startup scripts and ensure they run in the correct order.
This eliminates race conditions and makes workspace startup predictable and
reliable.

## Why use this?

Simply placing all of your workspace initialization logic in a single script works, but leads to slow workspace startup times.
Breaking this out into multiple independent `coder_script` resources improves startup times by allowing the scripts to run in parallel.
However, this can lead to intermittent failures between dependent scripts due to timing issues.
Up until now, template authors have had to rely on manual coordination methods (for example, touching a file upon completion).
The goal of startup script coordination is to provide a single reliable source of truth for coordination between workspace startup scripts.

## Quick Start

To start using workspace startup coordination, add calls to `coder exp sync (start|complete)` in your startup scripts where required:

  ```bash
  trap 'coder exp sync complete my-script' EXIT
  coder exp sync want my-script my-other-script
  coder exp sync start my-script
  # Existing startup logic
  ```

For more information, refer to the [usage documentation](./usage.md), [troubleshooting documentation](./troubleshooting.md), or view our [examples](./example.md).

---

# Usage

Source: https://coder.com/docs/admin/templates/startup-coordination/usage

# Workspace Startup Coordination Usage

> [!NOTE]
> This feature is experimental and may change without notice in future releases.

Startup coordination is built around the concept of **units**. You declare units in your Coder workspace template using the `coder exp sync` command in `coder_script` resources. When the Coder agent starts, it keeps an in-memory directed acyclic graph (DAG) of all units of which it is aware. When you need to synchronize with another unit, you can use `coder exp sync start $UNIT_NAME` to block until all dependencies of that unit have been marked complete.

## What is a unit?

A **unit** is a named phase of work, typically corresponding to a script or initialization
task.

- Units **may** declare dependencies on other units, creating an explicit ordering for workspace initialization.
- Units **must** be registered before they can be marked as complete.
- Units **may** be marked as dependencies before they are registered.
- Units **must not** declare cyclic dependencies. Attempting to create a cyclic dependency will result in an error.

## Requirements

> [!IMPORTANT]
> The `coder exp sync` command is only available from Coder version >=v2.30 onwards.

To use startup dependencies in your templates, you must:

- Modify your workspace startup scripts to run in parallel
- Declare dependencies as required using `coder exp sync`

### Declare Dependencies in your Workspace Startup Scripts

<div class="tabs">

#### Single Dependency

Here's a simple example of a script that depends on another unit completing
first:

```bash
#!/bin/bash
UNIT_NAME="my-setup"

# Declare dependency on git-clone
coder exp sync want "$UNIT_NAME" "git-clone"

# Wait for dependencies and mark as started
coder exp sync start "$UNIT_NAME"

# Do your work here
echo "Running after git-clone completes"

# Signal completion
coder exp sync complete "$UNIT_NAME"
```

This script will wait until the `git-clone` unit completes before starting its
own work.

#### Multiple Dependencies

If your unit depends on multiple other units, you can declare all dependencies
before starting:

```bash
#!/bin/bash
UNIT_NAME="my-app"
DEPENDENCIES="git-clone,env-setup,database-migration"

# Declare all dependencies
if [ -n "$DEPENDENCIES" ]; then
  IFS=',' read -ra DEPS <<< "$DEPENDENCIES"
  for dep in "${DEPS[@]}"; do
    dep=$(echo "$dep" | xargs)  # Trim whitespace
    if [ -n "$dep" ]; then
      coder exp sync want "$UNIT_NAME" "$dep"
    fi
  done
fi

# Wait for all dependencies
coder exp sync start "$UNIT_NAME"

# Your work here
echo "All dependencies satisfied, starting application"

# Signal completion
coder exp sync complete "$UNIT_NAME"
```

</div>

## Best Practices

### Test your changes before rolling out to all users

Before rolling out to all users:

1. Create a test workspace from the updated template
2. Check workspace build logs for sync messages
3. Verify all units reach "completed" status
4. Test workspace functionality

Once you're satisfied, [promote the new template version](../../../reference/cli/templates_versions_promote.md).

### Handle missing CLI gracefully

Not all workspaces will have the Coder CLI available in `$PATH`. Check for availability of the Coder CLI before using
sync commands:

```bash
if command -v coder > /dev/null 2>&1; then
  coder exp sync start "$UNIT_NAME"
else
  echo "Coder CLI not available, continuing without coordination"
fi
```

### Complete units that start successfully

Units **must** call `coder exp sync complete` to unblock dependent units. Use `trap` to ensure
completion even if your script exits early or encounters errors:

```bash

SYNC_STARTED=0
if coder exp sync start "$UNIT_NAME"; then
  SYNC_STARTED=1
fi

cleanup_sync() {
  if [ "$SYNC_STARTED" -eq 1 ]; then
    coder exp sync complete "$UNIT_NAME"
  fi
}
trap cleanup_sync EXIT
```

### Use descriptive unit names

Names should explain what the unit does, not its position in a sequence:

- Good: `git-clone`, `env-setup`, `database-migration`
- Avoid: `step1`, `init`, `script-1`

### Prefix a unique name to your units

When using `coder exp sync` in modules, note that unit names like `git-clone` might be common. Prefix the name of your module to your units to
ensure that your unit does not conflict with others.

- Good: `<module>.git-clone`, `<module>.claude`
- Bad: `git-clone`, `claude`

### Document dependencies

Add comments explaining why dependencies exist:

```hcl
resource "coder_script" "ide_setup" {
  # Depends on git-clone because we need .vscode/extensions.json
  # Depends on env-setup because we need $NODE_PATH configured
  script = <<-EOT
    coder exp sync want "ide-setup" "git-clone"
    coder exp sync want "ide-setup" "env-setup"
    # ...
  EOT
}
```

### Avoid circular dependencies

The Coder Agent detects and rejects circular dependencies, but they indicate a design problem:

```bash
# This will fail
coder exp sync want "unit-a" "unit-b"
coder exp sync want "unit-b" "unit-a"
```

## Frequently Asked Questions

### How do I identify scripts that can benefit from startup coordination?

Look for these patterns in existing templates:

- `sleep` commands used to order scripts
- Using files to coordinate startup between scripts (e.g. `touch /tmp/startup-complete`)
- Scripts that fail intermittently on startup
- Comments like "must run after X" or "wait for Y"

### Will this slow down my workspace?

No. The socket server adds minimal overhead, and the default polling interval is 1
second, so waiting for dependencies adds at most a few seconds to startup.
You are more likely to notice an improvement in startup times as it becomes easier to manage complex dependencies in parallel.

### How do units interact with each other?

Units with no dependencies run immediately and in parallel.
Only units with unsatisfied dependencies wait for their dependencies.

### How long can a dependency take to complete?

By default, `coder exp sync start` has a 5-minute timeout to prevent indefinite hangs.
Upon timeout, the command will exit with an error code and print `timeout waiting for dependencies of unit <unit_name>` to stderr.

You can adjust this timeout as necessary for long-running operations:

```bash
coder exp sync start "long-operation" --timeout 10m
```

### Is state stored between restarts?

No. Sync state is kept in-memory only and resets on workspace restart.
This is intentional to ensure clean initialization on every start.

---

# Troubleshooting

Source: https://coder.com/docs/admin/templates/startup-coordination/troubleshooting

# Workspace Startup Coordination Troubleshooting

> [!NOTE]
> This feature is experimental and may change without notice in future releases.

## Test Sync Availability

From a workspace terminal, test if sync is working using `coder exp sync ping`:

```bash
coder exp sync ping
```

* If sync is working, expect the output to be `Success`.
* Otherwise, you will see an error message similar to the below:

```bash
error: connect to agent socket: connect to socket: dial unix /tmp/coder-agent.sock: connect: permission denied
```

## Check Unit Status

You can check the status of a specific unit using `coder exp sync status`:

```bash
coder exp sync status git-clone
```

If the unit exists, you will see output similar to the below:

```bash
# coder exp sync status git-clone
Unit: git-clone
Status: completed
Ready: true
```

If the unit is not known to the agent, you will see output similar to the below:

```bash
# coder exp sync status doesnotexist
Unit: doesnotexist
Status: not registered
Ready: true

Dependencies:
No dependencies found
```

## Common Issues

### Workspace startup script hangs

If the workspace startup scripts appear to 'hang', one or more of your startup scripts may be waiting for a dependency that never completes.

* Inside the workspace, review `/tmp/coder-script-*.log` for more details on your script's execution.
    > **Tip:** add `set -x` to the top of your script to enable debug mode and update/restart the workspace.
* Review your template and verify that `coder exp sync complete <unit>` is called after the script completes e.g. with an exit trap.
* View the unit status using `coder exp sync status <unit>`.

### Workspace startup scripts fail

If the workspace startup scripts fail:

* Review `/tmp/coder-script-*.log` inside the workspace for script errors.
* Verify the Coder CLI is available in `$PATH` inside the workspace:

    ```bash
    command -v coder
    ```

### Cycle detected

If you see an error similar to the below in your startup script logs, you have defined a cyclic dependency:

```bash
error: declare dependency failed: cannot add dependency: adding edge for unit "bar": failed to add dependency
adding edge (bar -> foo): cycle detected
```

To fix this, review your dependency declarations and redesign them to remove the cycle. It may help to draw out the dependency graph to find
the cycle.

---

# Examples

Source: https://coder.com/docs/admin/templates/startup-coordination/example

# Workspace Startup Coordination Examples

## Script Example

This example shows a complete, production-ready script that starts Claude Code
only after a repository has been cloned. It includes error handling, graceful
degradation, and cleanup on exit:

```bash
#!/bin/bash
set -euo pipefail

UNIT_NAME="claude-code"
DEPENDENCIES="git-clone"
REPO_DIR="/workspace/repo"

# Track if sync started successfully
SYNC_STARTED=0

# Declare dependencies
if [ -n "$DEPENDENCIES" ]; then
  if command -v coder > /dev/null 2>&1; then
    IFS=',' read -ra DEPS <<< "$DEPENDENCIES"
    for dep in "${DEPS[@]}"; do
      dep=$(echo "$dep" | xargs)
      if [ -n "$dep" ]; then
        echo "Waiting for dependency: $dep"
        coder exp sync want "$UNIT_NAME" "$dep" > /dev/null 2>&1 || \
          echo "Warning: Failed to register dependency $dep, continuing..."
      fi
    done
  else
    echo "Coder CLI not found, running without sync coordination"
  fi
fi

# Start sync and track success
if [ -n "$UNIT_NAME" ]; then
  if command -v coder > /dev/null 2>&1; then
    if coder exp sync start "$UNIT_NAME" > /dev/null 2>&1; then
      SYNC_STARTED=1
      echo "Started sync: $UNIT_NAME"
    else
      echo "Sync start failed or not available, continuing without sync..."
    fi
  fi
fi

# Ensure completion on exit (even if script fails)
cleanup_sync() {
  if [ "$SYNC_STARTED" -eq 1 ] && [ -n "$UNIT_NAME" ]; then
    echo "Completing sync: $UNIT_NAME"
    coder exp sync complete "$UNIT_NAME" > /dev/null 2>&1 || \
      echo "Warning: Sync complete failed, but continuing..."
  fi
}
trap cleanup_sync EXIT

# Now do the actual work
echo "Repository cloned, starting Claude Code"
cd "$REPO_DIR"
claude
```

This script demonstrates several [best practices](./usage.md#best-practices):

- Checking for Coder CLI availability before using sync commands
- Tracking whether `coder exp sync` started successfully
- Using `trap` to ensure completion even if the script exits early
- Graceful degradation when `coder exp sync` isn't available
- Redirecting `coder exp sync` output to reduce noise in logs

## Template Migration Example

Below is a simple example Docker template that clones [Miguel Grinberg's example Flask repo](https://github.com/miguelgrinberg/microblog/) using the [`git-clone` module](https://registry.coder.com/modules/coder/git-clone) and installs the required dependencies for the project:

- Python development headers (required for building some Python packages)
- Python dependencies from the project's `requirements.txt`

We've omitted some details (such as persistent storage) for brevity, but these are easily added.

### Before

```terraform
data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = "codercom/enterprise-base:ubuntu"
  name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
  entrypoint = ["sh", "-c", coder_agent.main.init_script]
  env        = [
    "CODER_AGENT_TOKEN=${coder_agent.main.token}",
    ]
}

resource "coder_agent" "main" {
  arch           = data.coder_provisioner.me.arch
  os             = "linux"
}

module "git-clone" {
  count             = data.coder_workspace.me.start_count
  source            = "registry.coder.com/coder/git-clone/coder"
  version           = "1.2.3"
  agent_id          = coder_agent.main.id
  url               = "https://github.com/miguelgrinberg/microblog"
}

resource "coder_script" "setup" {
  count              = data.coder_workspace.me.start_count
  agent_id           = coder_agent.main.id
  display_name       = "Installing Dependencies"
  run_on_start       = true
  script             = <<EOT
    sudo apt-get update
    sudo apt-get install --yes python-dev-is-python3
    cd ${module.git-clone[count.index].repo_dir}
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
  EOT
}
```

We can note the following issues in the above template:

1. There is a race between cloning the repository and the `pip install` commands, which can lead to failed workspace startups in some cases.
2. The `apt` commands can run independently of the `git clone` command, meaning that there is a potential speedup here.

Based on the above, we can improve both the startup time and reliability of the template by splitting the monolithic startup script into multiple independent scripts:

- Install `apt` dependencies
- Install `pip` dependencies (depends on the `git-clone` module and the above step)

### After

Here is the updated version of the template:

```terraform
data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = "codercom/enterprise-base:ubuntu"
  name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
  entrypoint = ["sh", "-c", coder_agent.main.init_script]
  env        = [
    "CODER_AGENT_TOKEN=${coder_agent.main.token}",
    ]
}

resource "coder_agent" "main" {
  arch           = data.coder_provisioner.me.arch
  os             = "linux"
}

module "git-clone" {
  count             = data.coder_workspace.me.start_count
  source            = "registry.coder.com/coder/git-clone/coder"
  version           = "1.2.3"
  agent_id          = coder_agent.main.id
  url               = "https://github.com/miguelgrinberg/microblog/"
  post_clone_script = <<-EOT
    coder exp sync start git-clone && coder exp sync complete git-clone
  EOT
}

resource "coder_script" "apt-install" {
  count              = data.coder_workspace.me.start_count
  agent_id           = coder_agent.main.id
  display_name       = "Installing APT Dependencies"
  run_on_start       = true
  script             = <<EOT
    trap 'coder exp sync complete apt-install' EXIT
    coder exp sync start apt-install

    sudo apt-get update
    sudo apt-get install --yes python-dev-is-python3
  EOT
}

resource "coder_script" "pip-install" {
  count              = data.coder_workspace.me.start_count
  agent_id           = coder_agent.main.id
  display_name       = "Installing Python Dependencies"
  run_on_start       = true
  script             = <<EOT
    trap 'coder exp sync complete pip-install' EXIT
    coder exp sync want pip-install git-clone apt-install
    coder exp sync start pip-install

    cd ${module.git-clone[count.index].repo_dir}
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
  EOT
}
```

A short summary of the changes:

- We've broken the monolithic "setup" script into two separate scripts: one for the `apt` commands, and one for the `pip` commands.
  - In each script, we've added a `coder exp sync start $SCRIPT_NAME` command to mark the startup script as started.
  - We've also added an exit trap to ensure that we mark the startup scripts as completed. Without this, the `coder exp sync wait` command would eventually time out.
- We have used the `post_clone_script` feature of the `git-clone` module to allow waiting on the Git repository clone.
- In the `pip-install` script, we have declared a dependency on both `git-clone` and `apt-install`.

With these changes, the startup time has been reduced significantly and there is no longer any possibility of a race condition.

---

# Open in Coder

Source: https://coder.com/docs/admin/templates/open-in-coder

# Open in Coder

You can embed an "Open in Coder" button into your git repos or internal wikis to
let developers quickly launch a new workspace.

<video autoplay playsinline loop>
  <source src="https://github.com/coder/coder/blob/main/docs/images/templates/open-in-coder.mp4?raw=true" type="video/mp4">
Your browser does not support the video tag.
</video>

## How it works

To support any infrastructure and software stack, Coder provides a generic
approach for "Open in Coder" flows.

### 1. Set up git authentication

See [External Authentication](../external-auth/index.md) to set up Git authentication
in your Coder deployment.

### 2. Modify your template to auto-clone repos

The id in the template's `coder_external_auth` data source must match the
`CODER_EXTERNAL_AUTH_X_ID` in the Coder deployment configuration.

If you want the template to clone a specific git repo:

```hcl
# Require external authentication to use this template
data "coder_external_auth" "github" {
    id = "primary-github"
}

resource "coder_agent" "dev" {
    # ...
    dir = "~/coder"
    startup_script =<<EOF

    # Clone repo from GitHub
    if [ ! -d "coder" ]
    then
        git clone https://github.com/coder/coder
    fi

    EOF
}
```

> [!NOTE]
> The `dir` attribute can be set in multiple ways, for example:
>
> - `~/coder`
> - `/home/coder/coder`
> - `coder` (relative to the home directory)

If you want the template to support any repository via
[parameters](./extending-templates/parameters.md)

```hcl
# Require external authentication to use this template
data "coder_external_auth" "github" {
    id = "primary-github"
}

# Prompt the user for the git repo URL
data "coder_parameter" "git_repo" {
    name          = "git_repo"
    display_name  = "Git repository"
    default       = "https://github.com/coder/coder"
}

locals {
    folder_name = try(element(split("/", data.coder_parameter.git_repo.value), length(split("/", data.coder_parameter.git_repo.value)) - 1), "")
}

resource "coder_agent" "dev" {
    # ...
    dir = "~/${local.folder_name}"
    startup_script =<<EOF

    # Clone repo from GitHub
    if [ ! -d "${local.folder_name}" ]
    then
        git clone ${data.coder_parameter.git_repo.value}
    fi

    EOF
}
```

### 3. Embed the "Open in Coder" button with Markdown

```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace)
```

Be sure to replace `YOUR_ACCESS_URL` with your Coder access url (e.g.
<https://coder.example.com>) and `YOUR_TEMPLATE` with the name of your template.

### 4. Optional: pre-fill parameter values in the "Create Workspace" page

This can be used to pre-fill the git repo URL, disk size, image, etc.

```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace?param.git_repo=https://github.com/coder/slog&param.home_disk_size%20%28GB%29=20)
```

![Pre-filled parameters](../../images/templates/pre-filled-parameters.png)

### 5. Optional: disable specific parameter fields by including their names as

specified in your template in the `disable_params` search params list

```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace?disable_params=first_parameter,second_parameter)
```

### Security: consent dialog for automatic creation

When using `mode=auto` with prefilled `param.*` values, Coder displays a
security consent dialog before creating the workspace. This protects users
from malicious links that could provision workspaces with untrusted
configurations, such as dotfiles or startup scripts from unknown sources.

The dialog shows:

- A warning that a workspace is about to be created automatically from a link
- All prefilled `param.*` values from the URL
- **Confirm and Create** and **Cancel** buttons

The workspace is only created if the user explicitly clicks **Confirm and
Create**. Clicking **Cancel** falls back to the standard creation form where
all parameters can be reviewed manually.

![Consent dialog for automatic workspace creation](../../images/templates/auto-create-consent-dialog.png)

### Example: Kubernetes

For a full example of the Open in Coder flow in Kubernetes, check out
[this example template](https://github.com/bpmct/coder-templates/tree/main/kubernetes-open-in-coder).

---

# Permissions & Policies

Source: https://coder.com/docs/admin/templates/template-permissions

# Permissions

> [!NOTE]
> Template permissions are a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Licensed Coder administrators can control who can use and modify the template.

![Template Permissions](../../images/templates/permissions.png)

Permissions allow you to control who can use and modify the template. Both
individual user and groups can be added to the access list for a template.
Members can be assigned either a `Use` role, granting use of the template to
create workspaces, or `Admin`, allowing a user or members of a group to control
all aspects of the template. This offers a way to elevate the privileges of
ordinary users for specific templates without granting them the site-wide role
of `Template Admin`.

By default the `Everyone` group is assigned to each template meaning any Coder
user can use the template to create a workspace. To prevent this, disable the
`Allow everyone to use the template` setting when creating a template.

![Create Template Permissions](../../images/templates/create-template-permissions.png)

---

# Troubleshooting Templates

Source: https://coder.com/docs/admin/templates/troubleshooting

# Troubleshooting templates

Occasionally, you may run into scenarios where a workspace is created, but the
agent is either not connected or the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1)
has failed or timed out.

## Agent connection issues

If the agent is not connected, it means the agent or
[init script](https://github.com/coder/coder/tree/main/provisionersdk/scripts)
has failed on the resource.

```console
$ coder ssh myworkspace
⢄⡱ Waiting for connection from [agent]...
```

While troubleshooting steps vary by resource, here are some general best
practices:

- Ensure the resource has `curl` installed (alternatively, `wget` or `busybox`)
- Ensure the resource can `curl` your Coder
  [access URL](../../admin/setup/index.md#access-url)
- Manually connect to the resource and check the agent logs (e.g.,
  `kubectl exec`, `docker exec` or AWS console)
  - The Coder agent logs are typically stored in `/tmp/coder-agent.log`
  - The Coder agent startup script logs are typically stored in
    `/tmp/coder-startup-script.log`
  - The Coder agent shutdown script logs are typically stored in
    `/tmp/coder-shutdown-script.log`
- This can also happen if the websockets are not being forwarded correctly when
  running Coder behind a reverse proxy.
  [Read our reverse-proxy docs](../../admin/setup/index.md#tls--reverse-proxy)

## Startup script issues

Depending on the contents of the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1),
and whether or not the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior-1)
is set to blocking or non-blocking, you may notice issues related to the startup
script. In this section we will cover common scenarios and how to resolve them.

### Unable to access workspace, startup script is still running

If you're trying to access your workspace and are unable to because the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1)
is still running, it means the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior-1)
option is set to blocking or you have enabled the `--wait=yes` option (for e.g.
`coder ssh` or `coder config-ssh`). In such an event, you can always access the
workspace by using the web terminal, or via SSH using the `--wait=no` option. If
the startup script is running longer than it should, or never completing, you
can try to [debug the startup script](#debugging-the-startup-script) to resolve
the issue. Alternatively, you can try to force the startup script to exit by
terminating processes started by it or terminating the startup script itself (on
Linux, `ps` and `kill` are useful tools).

For tips on how to write a startup script that doesn't run forever, see the
[`startup_script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1)
section. For more ways to override the startup script behavior, see the
[`startup_script_behavior`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior-1)
section.

Template authors can also set the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior-1)
option to non-blocking, which will allow users to access the workspace while the
startup script is still running. Note that the workspace must be updated after
changing this option.

### Your workspace may be incomplete

If you see a warning that your workspace may be incomplete, it means you should
be aware that programs, files, or settings may be missing from your workspace.
This can happen if the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1)
is still running or has exited with a non-zero status (see
[startup script error](#startup-script-exited-with-an-error)). No action is
necessary, but you may want to
[start a new shell session](#session-was-started-before-the-startup-script-finished)
after it has completed or check the
[startup script logs](#debugging-the-startup-script) to see if there are any
issues.

### Session was started before the startup script finished

The web terminal may show this message if it was started before the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1)
finished, but the startup script has since finished. This message can safely be
dismissed, however, be aware that your preferred shell or dotfiles may not yet
be activated for this shell session. You can either start a new session or
source your dotfiles manually. Note that starting a new session means that
commands running in the terminal will be terminated and you may lose unsaved
work.

Examples for activating your preferred shell or sourcing your dotfiles:

- `exec zsh -l`
- `source ~/.bashrc`

### Startup script exited with an error

When the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1)
exits with an error, it means the last command run by the script failed. When
`set -e` is used, this means that any failing command will immediately exit the
script and the remaining commands will not be executed. This also means that
[your workspace may be incomplete](#your-workspace-may-be-incomplete). If you
see this error, you can check the
[startup script logs](#debugging-the-startup-script) to figure out what the
issue is.

Common causes for startup script errors:

- A missing command or file
- A command that fails due to missing permissions
- Network issues (e.g., unable to reach a server)

### Debugging the startup script

The simplest way to debug the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script-1)
is to open the workspace in the Coder dashboard and click "Show startup log" (if
not already visible). This will show all the output from the script. Another
option is to view the log file inside the workspace (usually
`/tmp/coder-startup-script.log`). If the logs don't indicate what's going on or
going wrong, you can increase verbosity by adding `set -x` to the top of the
startup script (note that this will show all commands run and may output
sensitive information). Alternatively, you can add `echo` statements to show
what's going on.

Here's a short example of an informative startup script:

```shell
echo "Running startup script..."
echo "Run: long-running-command"
/path/to/long-running-command
status=$?
echo "Done: long-running-command, exit status: ${status}"
if [ $status -ne 0 ]; then
  echo "Startup script failed, exiting..."
  exit $status
fi
```

> [!NOTE]
> We don't use `set -x` here because we're manually echoing the
> commands. This protects against sensitive information being shown in the log.

This script tells us what command is being run and what the exit status is. If
the exit status is non-zero, it means the command failed and we exit the script.
Since we are manually checking the exit status here, we don't need `set -e` at
the top of the script to exit on error.

> [!NOTE]
> If you aren't seeing any logs, check that the `dir` directive points
> to a valid directory in the file system.

## Slow workspace startup times

If your workspaces are taking longer to start than expected, or longer than
desired, you can diagnose which steps have the highest impact in the workspace
build timings UI (available in v2.17 and beyond). Admins can can
programmatically pull startup times for individual workspace builds using our
[build timings API endpoint](../../reference/api/builds.md#get-workspace-build-timings-by-id).

See our
[guide on optimizing workspace build times](../../tutorials/best-practices/speed-up-templates.md)
to optimize your templates based on this data.

![Workspace build timings UI](../../images/admin/templates/troubleshooting/workspace-build-timings-ui.png)

## Docker Workspaces on Raspberry Pi OS

### Unable to query ContainerMemory

When you query `ContainerMemory` and encounter the error:

```shell
open /sys/fs/cgroup/memory.max: no such file or directory
```

This error mostly affects Raspberry Pi OS, but might also affect older Debian-based systems as well.

<details><summary>Add cgroup_memory and cgroup_enable to cmdline.txt:</summary>

1. Confirm the list of existing cgroup controllers doesn't include `memory`:

   ```console
   $ cat /sys/fs/cgroup/cgroup.controllers
   cpuset cpu io pids

   $ cat /sys/fs/cgroup/cgroup.subtree_control
   cpuset cpu io pids
   ```

1. Add cgroup entries to `cmdline.txt` in `/boot/firmware` (or `/boot/` on older Pi OS releases):

   ```text
   cgroup_memory=1 cgroup_enable=memory
   ```

   You can use `sed` to add it to the file for you:

   ```bash
   sudo sed -i '$s/$/ cgroup_memory=1 cgroup_enable=memory/' /boot/firmware/cmdline.txt
   ```

1. Reboot:

   ```bash
   sudo reboot
   ```

1. Confirm that the list of cgroup controllers now includes `memory`:

   ```console
   $ cat /sys/fs/cgroup/cgroup.controllers
   cpuset cpu io memory pids

   $ cat /sys/fs/cgroup/cgroup.subtree_control
   cpuset cpu io memory pids
   ```

Read more about cgroup controllers in [The Linux Kernel](https://docs.kernel.org/admin-guide/cgroup-v2.html#controlling-controllers) documentation.

</details>

---

# External Provisioners

Source: https://coder.com/docs/admin/provisioners

# External provisioners

By default, the Coder server runs
[built-in provisioner daemons](../../reference/cli/server.md#--provisioner-daemons),
which execute `terraform` during workspace and template builds. However, there
are often benefits to running external provisioner daemons:

- **Secure build environments:** Run build jobs in isolated containers,
  preventing malicious templates from gaining sh access to the Coder host.

- **Isolate APIs:** Deploy provisioners in isolated environments (on-prem, AWS,
  Azure) instead of exposing APIs (Docker, Kubernetes, VMware) to the Coder
  server. See
  [Provider Authentication](../../admin/templates/extending-templates/provider-authentication.md)
  for more details.

- **Isolate secrets**: Keep Coder unaware of cloud secrets, manage/rotate
  secrets on provisioner servers.

- **Reduce server load**: External provisioners reduce load and build queue
  times from the Coder server. See
  [Scaling Coder](../../admin/infrastructure/index.md#scale-tests) for more
  details.

Each provisioner runs a single
[concurrent workspace build](../../admin/infrastructure/scale-testing.md#control-plane-provisionerd).
For example, running 30 provisioner containers will allow 30 users to start
workspaces at the same time.

Provisioners are started with the
[`coder provisioner start`](../../reference/cli/provisioner_start.md) command in
the [full Coder binary](https://github.com/coder/coder/releases). Keep reading
to learn how to start provisioners via Docker, Kubernetes, Systemd, etc.

You can use the dashboard, CLI, or API to [manage provisioners](./manage-provisioner-jobs.md).

## Authentication

The provisioner daemon must authenticate with your Coder deployment.

<div class="tabs">

## Scoped Key (Recommended)

We recommend creating finely-scoped keys for provisioners. Keys are scoped to an
organization, and optionally to a specific set of tags.

1. Use `coder provisioner` to create the key:

   - To create a key for an organization that will match untagged jobs:

     ```sh
     coder provisioner keys create my-key \
       --org default

     Successfully created provisioner key   my-key! Save this authentication token, it   will not be shown    again.

     <key omitted>
     ```

   - To restrict the provisioner to jobs with specific tags:

     ```sh
     coder provisioner keys create kubernetes-key \
       --org default \
       --tag environment=kubernetes

     Successfully created provisioner key kubernetes-key! Save this    authentication token, it will not be    shown again.

     <key omitted>
     ```

1. Start the provisioner with the specified key:

   ```sh
   export CODER_URL=https://<your-coder-url>
   export CODER_PROVISIONER_DAEMON_KEY=<key>
   coder provisioner start
   ```

Keep reading to see instructions for running provisioners on
Kubernetes/Docker/etc.

## User Tokens

A user account with the role `Template Admin` or `Owner` can start provisioners
using their user account. This may be beneficial if you are running provisioners
via [automation](../../reference/index.md).

```sh
coder login https://<your-coder-url>
coder provisioner start
```

To start a provisioner with specific tags:

```sh
coder login https://<your-coder-url>
coder provisioner start \
  --tag environment=kubernetes
```

Note: Any user can start [user-scoped provisioners](#user-scoped-provisioners),
but this will also require a template on your deployment with the corresponding
tags.

## Global PSK (Not Recommended)

We do not recommend using global PSK.

Global pre-shared keys (PSK) make it difficult to rotate keys or isolate provisioners.

A deployment-wide PSK can be used to authenticate any provisioner. To use a
global PSK, set a
[provisioner daemon pre-shared key (PSK)](../../reference/cli/server.md#--provisioner-daemon-psk)
on the Coder server.

Next, start the provisioner:

```sh
coder provisioner start --psk <your-psk>
```

</div>

## Provisioner Tags

You can use **provisioner tags** to control which provisioners can pick up build
jobs from templates (and corresponding workspaces) with matching explicit tags.

Provisioners have two implicit tags: `scope` and `owner`. Coder sets these tags
automatically.

- Organization-scoped provisioners always have the implicit tags
  `scope=organization owner=""`
- User-scoped provisioners always have the implicit tags
  `scope=user owner=<uuid>`

For example:

```sh
# Start a provisioner with the explicit tags
# environment=on_prem and datacenter=chicago
coder provisioner start \
  --tag environment=on_prem \
  --tag datacenter=chicago

# In another terminal, create/push
# a template that requires the explicit
# tag environment=on_prem
coder templates push on-prem \
  --provisioner-tag environment=on_prem

# Or, match the provisioner's explicit tags exactly
coder templates push on-prem-chicago \
  --provisioner-tag environment=on_prem \
  --provisioner-tag datacenter=chicago
```

This can also be done in the UI when building a template:

![template tags](../../images/admin/provisioner-tags.png)

Alternatively, a template can target a provisioner via
[workspace tags](https://github.com/coder/coder/tree/main/examples/workspace-tags)
inside the Terraform. See the
[workspace tags documentation](../../admin/templates/extending-templates/workspace-tags.md)
for more information.

> [!NOTE]
> Workspace tags defined with the `coder_workspace_tags` data source
> template **do not** automatically apply to the template import job! You may
> need to specify the desired tags when importing the template.

A provisioner can run a given build job if one of the below is true:

1. A job with no explicit tags can only be run on a provisioner with no explicit
   tags. This way you can introduce tagging into your deployment without
   disrupting existing provisioners and jobs.
1. If a job has any explicit tags, it can only run on a provisioner with those
   explicit tags (the provisioner could have additional tags).

The external provisioner in the above example can run build jobs in the same
organization with tags:

- `environment=on_prem`
- `datacenter=chicago`
- `environment=on_prem datacenter=chicago`

However, it will not pick up any build jobs that do not have either of the
`environment` or `datacenter` tags set. It will also not pick up any build jobs
from templates with the tag `scope=user` set, or build jobs from templates in
different organizations.

> [!NOTE]
> If you only run tagged provisioners, you will need to specify a set of
> tags that matches at least one provisioner for _all_ template import jobs and
> workspace build jobs.
>
> You may wish to run at least one additional provisioner with no additional
> tags so that provisioner jobs with no additional tags defined will be picked
> up instead of potentially remaining in the Pending state indefinitely.

This is illustrated in the below table:

| Provisioner Tags                                                  | Job Tags                                                         | Same Org | Can Run Job? |
|-------------------------------------------------------------------|------------------------------------------------------------------|----------|--------------|
| scope=organization owner=                                         | scope=organization owner=                                        | ✅        | ✅            |
| scope=organization owner= environment=on-prem                     | scope=organization owner= environment=on-prem                    | ✅        | ✅            |
| scope=organization owner= environment=on-prem datacenter=chicago  | scope=organization owner= environment=on-prem                    | ✅        | ✅            |
| scope=organization owner= environment=on-prem datacenter=chicago  | scope=organization owner= environment=on-prem datacenter=chicago | ✅        | ✅            |
| scope=user owner=aaa                                              | scope=user owner=aaa                                             | ✅        | ✅            |
| scope=user owner=aaa environment=on-prem                          | scope=user owner=aaa                                             | ✅        | ✅            |
| scope=user owner=aaa environment=on-prem                          | scope=user owner=aaa environment=on-prem                         | ✅        | ✅            |
| scope=user owner=aaa environment=on-prem datacenter=chicago       | scope=user owner=aaa environment=on-prem                         | ✅        | ✅            |
| scope=user owner=aaa environment=on-prem datacenter=chicago       | scope=user owner=aaa environment=on-prem datacenter=chicago      | ✅        | ✅            |
| scope=organization owner=                                         | scope=organization owner= environment=on-prem                    | ✅        | ❌            |
| scope=organization owner= environment=on-prem                     | scope=organization owner=                                        | ✅        | ❌            |
| scope=organization owner= environment=on-prem                     | scope=organization owner= environment=on-prem datacenter=chicago | ✅        | ❌            |
| scope=organization owner= environment=on-prem datacenter=new_york | scope=organization owner= environment=on-prem datacenter=chicago | ✅        | ❌            |
| scope=user owner=aaa                                              | scope=organization owner=                                        | ✅        | ❌            |
| scope=user owner=aaa                                              | scope=user owner=bbb                                             | ✅        | ❌            |
| scope=organization owner=                                         | scope=user owner=aaa                                             | ✅        | ❌            |
| scope=organization owner=                                         | scope=user owner=aaa environment=on-prem                         | ✅        | ❌            |
| scope=user owner=aaa                                              | scope=user owner=aaa environment=on-prem                         | ✅        | ❌            |
| scope=user owner=aaa environment=on-prem                          | scope=user owner=aaa environment=on-prem datacenter=chicago      | ✅        | ❌            |
| scope=user owner=aaa environment=on-prem datacenter=chicago       | scope=user owner=aaa environment=on-prem datacenter=new_york     | ✅        | ❌            |
| scope=organization owner= environment=on-prem                     | scope=organization owner= environment=on-prem                    | ❌        | ❌            |

> [!TIP]
> To generate this table, run the following command and
> copy the output:
>
> ```go
> go test -v -count=1 ./coderd/provisionerdserver/ -test.run='^TestAcquirer_MatchTags/GenTable$'
> ```

## Types of provisioners

Provisioners can broadly be categorized by scope: `organization` or `user`. The
scope of a provisioner can be specified with
[`-tag=scope=<scope>`](../../reference/cli/provisioner_start.md#-t---tag) when
starting the provisioner daemon. Only users with at least the
[Template Admin](../users/index.md#roles) role or higher may create
organization-scoped provisioner daemons.

There are two exceptions:

- [Built-in provisioners](../../reference/cli/server.md#--provisioner-daemons) are
  always organization-scoped.
- External provisioners started using a
  [pre-shared key (PSK)](../../reference/cli/provisioner_start.md#--psk) are always
  organization-scoped.

### Organization-Scoped Provisioners

**Organization-scoped Provisioners** can pick up build jobs created by any user.
These provisioners always have the implicit tags `scope=organization owner=""`.

```sh
coder provisioner start --org <organization_name>
```

If you omit the `--org` argument, the provisioner will be assigned to the
default organization.

```sh
coder provisioner start
```

### User-scoped Provisioners

**User-scoped Provisioners** can only pick up build jobs created from
user-tagged templates. Unlike the other provisioner types, any Coder user can
run user provisioners, but they have no impact unless there exists at least one
template with the `scope=user` provisioner tag.

```sh
coder provisioner start \
  --tag scope=user

# In another terminal, create/push
# a template that requires user provisioners
coder templates push on-prem \
  --provisioner-tag scope=user
```

## Example: Running an external provisioner with Helm

Coder provides a Helm chart for running external provisioner daemons, which you
will use in concert with the Helm chart for deploying the Coder server.

1. Create a provisioner key:

   ```sh
   coder provisioner keys create my-cool-key --org default
   # Optionally, you can specify tags for the provisioner key:
   # coder provisioner keys create my-cool-key --org default --tag location=auh --tag kind=k8s

   Successfully created provisioner key kubernetes-key! Save this authentication
   token, it will not be shown again.

   <key omitted>
   ```

1. Store the key in a kubernetes secret:

   ```sh
   kubectl create secret generic coder-provisioner-keys --from-literal=my-cool-key=`<key omitted>`
   ```

1. Create a `provisioner-values.yaml` file for the provisioner daemons Helm
   chart. For example:

   ```yaml
   coder:
     env:
       - name: CODER_URL
         value: "https://coder.example.com"
     replicaCount: 10
   provisionerDaemon:
     # NOTE: in older versions of the Helm chart (2.17.0 and below), it is required to set this to an empty string.
     pskSecretName: ""
     keySecretName: "coder-provisioner-keys"
     keySecretKey: "my-cool-key"
   ```

   This example creates a deployment of 10 provisioner daemons (for 10
   concurrent builds) authenticating using the above key. The daemons will
   authenticate using the provisioner key created in the previous step and
   acquire jobs matching the tags specified when the provisioner key was
   created. The set of tags is inferred automatically from the provisioner key.

   > Refer to the
   > [values.yaml](https://github.com/coder/coder/blob/main/helm/provisioner/values.yaml)
   > file for the coder-provisioner chart for information on what values can be
   > specified.

1. Install the provisioner daemon chart

   ```sh
   helm install coder-provisioner coder-v2/coder-provisioner \
       --namespace coder \
       --version <your version> \
       --values provisioner-values.yaml
   ```

   You can verify that your provisioner daemons have successfully connected to
   Coderd by looking for a debug log message that says
   `provisioner: successfully connected to coderd` from each Pod.

## Example: Running an external provisioner on a VM

```sh
curl -L https://coder.com/install.sh | sh
export CODER_URL=https://coder.example.com
export CODER_SESSION_TOKEN=your_token
coder provisioner start
```

## Example: Running an external provisioner via Docker

```sh
docker run --rm -it \
  -e CODER_URL=https://coder.example.com/ \
  -e CODER_SESSION_TOKEN=your_token \
  --entrypoint /opt/coder \
  ghcr.io/coder/coder:latest \
  provisioner start
```

## Disable built-in provisioners

As mentioned above, the Coder server will run built-in provisioners by default.
This can be disabled with a server-wide
[flag or environment variable](../../reference/cli/server.md#--provisioner-daemons).

```sh
coder server --provisioner-daemons=0
```

## Prometheus metrics

Coder provisioner daemon exports metrics via the HTTP endpoint, which can be
enabled using either the environment variable `CODER_PROMETHEUS_ENABLE` or the
flag `--prometheus-enable`.

The Prometheus endpoint address is `http://localhost:2112/` by default. You can
use either the environment variable `CODER_PROMETHEUS_ADDRESS` or the flag
`--prometheus-address <network-interface>:<port>` to select a different listen
address.

If you have provisioners daemons deployed as pods, it is advised to monitor them
separately.

## Next

- [Manage Provisioners](./manage-provisioner-jobs.md)

---

# Manage Provisioner Jobs

Source: https://coder.com/docs/admin/provisioners/manage-provisioner-jobs

# Manage provisioner jobs

[Provisioners](./index.md) start and run provisioner jobs to create or delete workspaces.
Each time a workspace is built, rebuilt, or destroyed, it generates a new job and assigns
the job to an available provisioner daemon for execution.

While most jobs complete smoothly, issues with templates, cloud resources, or misconfigured
provisioners can cause jobs to fail or hang indefinitely (these are in a `Pending` state).

![Provisioner jobs in the dashboard](../../images/admin/provisioners/provisioner-jobs.png)

## How to find provisioner jobs

Coder admins can view and manage provisioner jobs.

Use the dashboard, CLI, or API:

- **Dashboard**:

   Select **Admin settings** > **Organizations** > **Provisioner Jobs**

   Provisioners are organization-specific. If you have more than one organization, select it first.

- **CLI**: `coder provisioner jobs list`
- **API**: `/api/v2/provisioner/jobs`

## Manage provisioner jobs from the dashboard

View more information about and manage your provisioner jobs from the Coder dashboard.

1. Under **Admin settings** select **Organizations**, then select **Provisioner jobs**.

1. Select the **>** to expand each entry for more information.

1. To delete a job, select the 🚫 at the end of the entry's row.

   If your user doesn't have the correct permissions, this option is greyed out.

## Provisioner job status

Each provisioner job has a lifecycle state:

| Status        | Description                                                    |
|---------------|----------------------------------------------------------------|
| **Pending**   | Job is queued but has not yet been picked up by a provisioner. |
| **Running**   | A provisioner is actively working on the job.                  |
| **Completed** | Job succeeded.                                                 |
| **Failed**    | Provisioner encountered an error while executing the job.      |
| **Canceled**  | Job was manually terminated by an admin.                       |

The following diagram shows how a provisioner job transitions between lifecycle states:

![Provisioner jobs state transitions](../../images/admin/provisioners/provisioner-jobs-status-flow.png)

## When to cancel provisioner jobs

A job might need to be cancelled when:

- It has been stuck in **Pending** for too long. This can be due to misconfigured tags or unavailable provisioners.
- It is **Running** indefinitely, often caused by external system failures or buggy templates.
- An admin wants to abort a failed attempt, fix the root cause, and retry provisioning.
- A workspace was deleted in the UI but the underlying cloud resource wasn’t cleaned up, causing a hanging delete job.

Cancelling a job does not automatically retry the operation.
It clears the stuck state and allows the admin or user to trigger the action again if needed.

## Troubleshoot provisioner jobs

Provisioner jobs can fail or slow workspace creation for a number of reasons.
Follow these steps to identify problematic jobs or daemons:

1. Filter jobs by `pending` status in the dashboard, or use the CLI:

   ```bash
   coder provisioner jobs list -s pending
   ```

1. Look for daemons with multiple failed jobs and for template [tag mismatches](./index.md#provisioner-tags).

1. Cancel the job through the dashboard, or use the CLI:

   ```shell
   coder provisioner jobs cancel <job-id>
   ```

---

# External Authentication

Source: https://coder.com/docs/admin/external-auth

# External Authentication

Coder supports external authentication via OAuth2.0. This allows enabling any OAuth provider as well as integrations with Git providers,
such as GitHub, GitLab, and Bitbucket.

External authentication can also be used to integrate with external services
like JFrog Artifactory and others.

To add an external authentication provider, you'll need to create an OAuth
application. The following providers have been tested and work with Coder:

- [Azure DevOps](https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops)
- [Azure DevOps (via Entra ID)](https://learn.microsoft.com/en-us/entra/architecture/auth-oauth2)
- [BitBucket](https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/)
- [GitHub](#configure-a-github-oauth-app)
- [GitLab](https://docs.gitlab.com/ee/integration/oauth_provider.html)

If you have experience with a provider that is not listed here, please
[file an issue](https://github.com/coder/internal/issues/new?title=request%28docs%29%3A+external-auth+-+request+title+here%0D%0A&labels=["customer-feedback","docs"]&body=doc%3A+%5Bexternal-auth%5D%28https%3A%2F%2Fcoder.com%2Fdocs%2Fadmin%2Fexternal-auth%29%0D%0A%0D%0Aplease+enter+your+request+here%0D%0A)

## Configuration

### Set environment variables

After you create an OAuth application, set environment variables to configure the Coder server to use it:

```env
CODER_EXTERNAL_AUTH_0_ID="<USER_DEFINED_ID>"
CODER_EXTERNAL_AUTH_0_TYPE=<github|gitlab|azure-devops|bitbucket-cloud|bitbucket-server|etc>
CODER_EXTERNAL_AUTH_0_CLIENT_ID=<OAuth app client ID>
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=<OAuth app client secret>

# Optionally, configure a custom display name and icon:
CODER_EXTERNAL_AUTH_0_DISPLAY_NAME="Google Calendar"
CODER_EXTERNAL_AUTH_0_DISPLAY_ICON="https://mycustomicon.com/google.svg"
```

The `CODER_EXTERNAL_AUTH_0_ID` environment variable is used as an identifier for the authentication provider.

This variable is used as part of the callback URL path that you must configure in your OAuth provider settings.
If the value in your callback URL doesn't match the `CODER_EXTERNAL_AUTH_0_ID` value, authentication will fail with `redirect URI is not valid`.
Set it with a value that helps you identify the provider.
For example, if you use `CODER_EXTERNAL_AUTH_0_ID="primary-github"` for your GitHub provider,
configure your callback URL as `https://example.com/external-auth/primary-github/callback`.

### Add an authentication button to the workspace template

Add the following code to any template to add a button to the workspace setup page which will allow you to authenticate with your provider:

```tf
data "coder_external_auth" "<github|gitlab|azure-devops|bitbucket-cloud|bitbucket-server|other>" {
    id = "<USER_DEFINED_ID>"
}

# GitHub Example (CODER_EXTERNAL_AUTH_0_ID="primary-github")
# makes a GitHub authentication token available at data.coder_external_auth.github.access_token
data "coder_external_auth" "github" {
   id = "primary-github"
}

```

Inside your Terraform code, you now have access to authentication variables.
Reference the documentation for your chosen provider for more information on how to supply it with a token.

### Workspace CLI

Use [`external-auth`](../../reference/cli/external-auth.md) in the Coder CLI to access a token within the workspace:

```shell
coder external-auth access-token <USER_DEFINED_ID>
```

## Git Authentication in Workspaces

Coder provides automatic Git authentication for workspaces through SSH authentication and Git-provider specific env variables.

When performing Git operations, Coder first attempts to use external auth provider tokens if available.
If no tokens are available, it defaults to SSH authentication.

### OAuth (external auth)

For Git providers configured with [external authentication](#configuration), Coder can use OAuth tokens for Git operations over HTTPS.
When using SSH URLs (like `git@github.com:organization/repo.git`), Coder uses SSH keys as described in the [SSH Authentication](#ssh-authentication) section instead.

For Git operations over HTTPS, Coder automatically uses the appropriate external auth provider
token based on the repository URL.
This works through Git's `GIT_ASKPASS` mechanism, which Coder configures in each workspace.

To use OAuth tokens for Git authentication over HTTPS:

1. Complete the OAuth authentication flow (**Login with GitHub**, **Login with GitLab**).
1. Use HTTPS URLs when interacting with repositories (`https://github.com/organization/repo.git`).
1. Coder automatically handles authentication. You can perform your Git operations as you normally would.

Behind the scenes, Coder:

- Stores your OAuth token securely in its database
- Sets up `GIT_ASKPASS` at `/tmp/coder.<random-string>/coder` in your workspaces
- Retrieves and injects the appropriate token when Git operations require authentication

To manually access these tokens within a workspace:

```shell
coder external-auth access-token <USER_DEFINED_ID>
```

### SSH Authentication

Coder automatically generates an SSH key pair for each user that can be used for Git operations.
When you use SSH URLs for Git repositories, for example, `git@github.com:organization/repo.git`, Coder checks for and uses an existing SSH key.
If one is not available, it uses the Coder-generated one.

The `coder gitssh` command wraps the standard `ssh` command and injects the SSH key during Git operations.
This works automatically when you:

1. Clone a repository using SSH URLs
1. Pull/push changes to remote repositories
1. Use any Git command that requires SSH authentication

You must add the SSH key to your Git provider.

#### Add your Coder SSH key to your Git provider

1. View your Coder Git SSH key:

   ```shell
   coder publickey
   ```

1. Add the key to your Git provider accounts:

   - [GitHub](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account#adding-a-new-ssh-key-to-your-account)
   - [GitLab](https://docs.gitlab.com/user/ssh/#add-an-ssh-key-to-your-gitlab-account)

## PKCE Support

[PKCE (Proof Key for Code Exchange)](https://datatracker.ietf.org/doc/html/rfc7636) is an OAuth 2.0
security extension that prevents authorization code interception attacks. Coder supports PKCE when
acting as an OAuth client to external identity providers.

Coder will usually assume PKCE support is available with "S256" as the code challenge method. Manual
configuration is available to override any default behavior.

```env
# Enable PKCE with S256 (recommended when supported)
CODER_EXTERNAL_AUTH_0_PKCE_METHODS="S256"

# Disable PKCE entirely
CODER_EXTERNAL_AUTH_0_PKCE_METHODS="none"
```

## Git-provider specific env variables

### Azure DevOps

Azure DevOps requires the following environment variables:

```env
CODER_EXTERNAL_AUTH_0_ID="primary-azure-devops"
CODER_EXTERNAL_AUTH_0_TYPE=azure-devops
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
# Ensure this value is your "Client Secret", not "App Secret"
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://app.vssps.visualstudio.com/oauth2/authorize"
CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://app.vssps.visualstudio.com/oauth2/token"
```

### Azure DevOps (via Entra ID)

Azure DevOps (via Entra ID) requires the following environment variables:

```env
CODER_EXTERNAL_AUTH_0_ID="primary-azure-devops"
CODER_EXTERNAL_AUTH_0_TYPE=azure-devops-entra
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://login.microsoftonline.com/<TENANT ID>/oauth2/authorize"
```

> [!NOTE]
> Your app registration in Entra ID requires the `vso.code_write` scope

### Bitbucket Server

Bitbucket Server requires the following environment variables:

```env
CODER_EXTERNAL_AUTH_0_ID="primary-bitbucket-server"
CODER_EXTERNAL_AUTH_0_TYPE=bitbucket-server
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxx
CODER_EXTERNAL_AUTH_0_AUTH_URL=https://bitbucket.example.com/rest/oauth2/latest/authorize
```

When configuring your Bitbucket OAuth application, set the redirect URI to
`https://example.com/external-auth/primary-bitbucket-server/callback`.
This callback path includes the value of `CODER_EXTERNAL_AUTH_0_ID`.

### Gitea

```env
CODER_EXTERNAL_AUTH_0_ID="gitea"
CODER_EXTERNAL_AUTH_0_TYPE=gitea
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
# If self managed, set the Auth URL to your Gitea instance
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://gitea.com/login/oauth/authorize"
```

The redirect URI for Gitea should be
`https://coder.example.com/external-auth/gitea/callback`.

### GitHub

Use this section as a reference for environment variables to customize your setup
or to integrate with an existing GitHub authentication.

For a more complete, step-by-step guide, follow the
[configure a GitHub OAuth app](#configure-a-github-oauth-app) section instead.

```env
CODER_EXTERNAL_AUTH_0_ID="primary-github"
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_REVOKE_URL=https://api.github.com/applications/<CLIENT ID>/grant
```

When configuring your GitHub OAuth application, set the
[authorization callback URL](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/about-the-user-authorization-callback-url)
as `https://example.com/external-auth/primary-github/callback`, where
`primary-github` matches your `CODER_EXTERNAL_AUTH_0_ID` value.

### GitHub Enterprise

GitHub Enterprise requires the following environment variables:

```env
CODER_EXTERNAL_AUTH_0_ID="primary-github"
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_VALIDATE_URL="https://github.example.com/api/v3/user"
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://github.example.com/login/oauth/authorize"
CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://github.example.com/login/oauth/access_token"
```

When configuring your GitHub Enterprise OAuth application, set the
[authorization callback URL](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/about-the-user-authorization-callback-url)
as `https://example.com/external-auth/primary-github/callback`, where
`primary-github` matches your `CODER_EXTERNAL_AUTH_0_ID` value.

### GitLab self-managed

GitLab self-managed requires the following environment variables:

```env
CODER_EXTERNAL_AUTH_0_ID="primary-gitlab"
CODER_EXTERNAL_AUTH_0_TYPE=gitlab
# This value is the "Application ID"
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_VALIDATE_URL="https://gitlab.example.com/oauth/token/info"
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://gitlab.example.com/oauth/authorize"
CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://gitlab.example.com/oauth/token"
CODER_EXTERNAL_AUTH_0_REVOKE_URL="https://gitlab.example.com/oauth/revoke"
CODER_EXTERNAL_AUTH_0_REGEX=gitlab\.example\.com
```

When [configuring your GitLab OAuth application](https://docs.gitlab.com/17.5/integration/oauth_provider/),
set the redirect URI to `https://example.com/external-auth/primary-gitlab/callback`.
Note that the redirect URI must include the value of `CODER_EXTERNAL_AUTH_0_ID` (in this example, `primary-gitlab`).

### JFrog Artifactory

Visit the [JFrog Artifactory](../../admin/integrations/jfrog-artifactory.md) guide for instructions on how to set up for JFrog Artifactory.

## Self-managed Git providers

Custom authentication and token URLs should be used for self-managed Git
provider deployments.

```env
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://github.example.com/oauth/authorize"
CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://github.example.com/oauth/token"
CODER_EXTERNAL_AUTH_0_REVOKE_URL="https://github.example.com/oauth/revoke"
CODER_EXTERNAL_AUTH_0_VALIDATE_URL="https://example.com/oauth/token/info"
CODER_EXTERNAL_AUTH_0_REGEX=github\.company\.com
```

> [!NOTE]
> The `REGEX` variable must be set if using a custom Git domain.

## Custom scopes

Optionally, you can request custom scopes:

```env
CODER_EXTERNAL_AUTH_0_SCOPES="repo:read repo:write write:gpg_key"
```

## OAuth provider

### Configure a GitHub OAuth app

1. [Create a GitHub App](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app)

   - Set the authorization callback URL to
     `https://coder.example.com/external-auth/primary-github/callback`, where `primary-github`
     is the value you set for `CODER_EXTERNAL_AUTH_0_ID`.
   - Deactivate Webhooks.
   - Enable fine-grained access to specific repositories or a subset of
     permissions for security.

   ![Register GitHub App](../../images/admin/github-app-register.png)

1. Adjust the GitHub app permissions. You can use more or fewer permissions than
   are listed here, this example allows users to clone
   repositories:

   ![Adjust GitHub App Permissions](../../images/admin/github-app-permissions.png)

   | Name          | Permission   | Description                                            |
   |---------------|--------------|--------------------------------------------------------|
   | Contents      | Read & Write | Grants access to code and commit statuses.             |
   | Pull requests | Read & Write | Grants access to create and update pull requests.      |
   | Workflows     | Read & Write | Grants access to update files in `.github/workflows/`. |
   | Metadata      | Read-only    | Grants access to metadata written by GitHub Apps.      |
   | Members       | Read-only    | Grants access to organization members and teams.       |

1. Install the App for your organization. You may select a subset of
   repositories to grant access to.

   ![Install GitHub App](../../images/admin/github-app-install.png)

## Multiple External Providers (Premium)

Below is an example configuration with multiple providers:

> [!IMPORTANT]
> To support regex matching for paths like `github\.com/org`, add the following `git config` line to the [Coder agent startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script):
>
> ```shell
> git config --global credential.useHttpPath true
> ```

```env
# Provider 1) github.com
CODER_EXTERNAL_AUTH_0_ID=primary-github
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_REGEX=github\.com/org

# Provider 2) github.example.com
CODER_EXTERNAL_AUTH_1_ID=secondary-github
CODER_EXTERNAL_AUTH_1_TYPE=github
CODER_EXTERNAL_AUTH_1_CLIENT_ID=xxxxxx
CODER_EXTERNAL_AUTH_1_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_1_REGEX=github\.example\.com
CODER_EXTERNAL_AUTH_1_AUTH_URL="https://github.example.com/login/oauth/authorize"
CODER_EXTERNAL_AUTH_1_TOKEN_URL="https://github.example.com/login/oauth/access_token"
CODER_EXTERNAL_AUTH_1_REVOKE_URL="https://github.example.com/login/oauth/revoke"
CODER_EXTERNAL_AUTH_1_VALIDATE_URL="https://github.example.com/api/v3/user"
```

---

# Integrations

Source: https://coder.com/docs/admin/integrations

# Integrations

Coder is highly extensible and is not limited to the platforms outlined in these
docs. The control plane can be provisioned on any VM or container compute, and
workspaces can include any Terraform resource. See our
[architecture diagram](../infrastructure/architecture.md) for more details.

You can host your deployment on almost any infrastructure. To learn how, read
our [installation guides](../../install/index.md).

<children></children>

The following resources may help as you're deploying Coder.

- [Coder packages: one-click install on cloud providers](https://github.com/coder/packages)
- [Deploy Coder Air-gapped](../../install/airgap.md)
- [Supported resources (Terraform registry)](https://registry.terraform.io)
- [Writing custom templates](../templates/index.md)

---

# Prometheus

Source: https://coder.com/docs/admin/integrations/prometheus

# Prometheus

Coder exposes many metrics which can be consumed by a Prometheus server, and
give insight into the current state of a live Coder deployment.

If you don't have a Prometheus server installed, you can follow the Prometheus
[Getting started](https://prometheus.io/docs/prometheus/latest/getting_started/) guide.

## Enable Prometheus metrics

Coder server exports metrics via the HTTP endpoint, which can be enabled using
either the environment variable `CODER_PROMETHEUS_ENABLE` or the flag
`--prometheus-enable`.

The Prometheus endpoint address is `http://localhost:2112/` by default. You can
use either the environment variable `CODER_PROMETHEUS_ADDRESS` or the flag
`--prometheus-address <network-interface>:<port>` to select a different listen
address.

If `coder server --prometheus-enable` is started locally, you can preview the
metrics endpoint in your browser or with `curl`:

```console
$ curl http://localhost:2112/
# HELP coderd_api_active_users_duration_hour The number of users that have been active within the last hour.
# TYPE coderd_api_active_users_duration_hour gauge
coderd_api_active_users_duration_hour 0
...
```

### Kubernetes deployment

The Prometheus endpoint can be enabled in the [Helm chart's](https://github.com/coder/coder/tree/main/helm)
`values.yml` by setting `CODER_PROMETHEUS_ENABLE=true`. Once enabled, the environment variable `CODER_PROMETHEUS_ADDRESS` will be set by default to
`0.0.0.0:2112`. A Service Endpoint will not be exposed; if you need to
expose the Prometheus port on a Service, (for example, to use a
`ServiceMonitor`), create a separate headless service instead.

```yaml
apiVersion: v1
kind: Service
metadata:
  name: coder-prom
  namespace: coder
spec:
  clusterIP: None
  ports:
    - name: prom-http
      port: 2112
      protocol: TCP
      targetPort: 2112
  selector:
    app.kubernetes.io/instance: coder
    app.kubernetes.io/name: coder
  type: ClusterIP
```

### Prometheus configuration

To allow Prometheus to scrape the Coder metrics, you will need to create a
`scrape_config` in your `prometheus.yml` file, or in the Prometheus Helm chart
values. The following is an example `scrape_config`.

```yaml
scrape_configs:
  - job_name: "coder"
    scheme: "http"
    static_configs:
      # replace with the the IP address of the Coder pod or server
      - targets: ["<ip>:2112"]
        labels:
          apps: "coder"
```

To use the Kubernetes Prometheus operator to scrape metrics, you will need to
create a `ServiceMonitor` in your Coder deployment namespace. The following is
an example `ServiceMonitor`.

```yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: coder-service-monitor
  namespace: coder
spec:
  endpoints:
    - port: prom-http
      interval: 10s
      scrapeTimeout: 10s
  namespaceSelector:
    matchNames:
    - coder
  selector:
    matchLabels:
      app.kubernetes.io/name: coder
```

## Available metrics

You must first enable `coderd_agentstats_*` with the flag
`--prometheus-collect-agent-stats`, or the environment variable
`CODER_PROMETHEUS_COLLECT_AGENT_STATS` before they can be retrieved from the
deployment. They will always be available from the agent.

<!-- Code generated by 'make docs/admin/integrations/prometheus.md'. DO NOT EDIT -->

| Name                                                                    | Type      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Labels                                                                                                |
|-------------------------------------------------------------------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
| `agent_boundary_log_proxy_batches_dropped_total`                        | counter   | Total number of boundary log batches dropped before reaching coderd. Reason: buffer_full = the agent's internal buffer is full, meaning boundary is producing logs faster than the agent can forward them to coderd; forward_failed = the agent failed to send the batch to coderd, potentially because coderd is unreachable or the connection was interrupted.                                                                                                                                           | `reason`                                                                                              |
| `agent_boundary_log_proxy_batches_forwarded_total`                      | counter   | Total number of boundary log batches successfully forwarded to coderd. Compare with batches_dropped_total to compute a drop rate.                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                       |
| `agent_boundary_log_proxy_logs_dropped_total`                           | counter   | Total number of individual boundary log entries dropped before reaching coderd. Reason: buffer_full = the agent's internal buffer is full; forward_failed = the agent failed to send the batch to coderd; boundary_channel_full = boundary's internal send channel overflowed, meaning boundary is generating logs faster than it can batch and send them; boundary_batch_full = boundary's outgoing batch buffer overflowed after a failed flush, meaning boundary could not write to the agent's socket. | `reason`                                                                                              |
| `agent_scripts_executed_total`                                          | counter   | Total number of scripts executed by the Coder agent. Includes cron scheduled scripts.                                                                                                                                                                                                                                                                                                                                                                                                                      | `agent_name` `success` `template_name` `username` `workspace_name`                                    |
| `coder_aibridged_circuit_breaker_rejects_total`                         | counter   | Total number of requests rejected due to open circuit breaker.                                                                                                                                                                                                                                                                                                                                                                                                                                             | `endpoint` `model` `provider`                                                                         |
| `coder_aibridged_circuit_breaker_state`                                 | gauge     | Current state of the circuit breaker (0=closed, 0.5=half-open, 1=open).                                                                                                                                                                                                                                                                                                                                                                                                                                    | `endpoint` `model` `provider`                                                                         |
| `coder_aibridged_circuit_breaker_trips_total`                           | counter   | Total number of times the circuit breaker transitioned to open state.                                                                                                                                                                                                                                                                                                                                                                                                                                      | `endpoint` `model` `provider`                                                                         |
| `coder_aibridged_injected_tool_invocations_total`                       | counter   | The number of times an injected MCP tool was invoked by aibridge.                                                                                                                                                                                                                                                                                                                                                                                                                                          | `model` `name` `provider` `server`                                                                    |
| `coder_aibridged_interceptions_duration_seconds`                        | histogram | The total duration of intercepted requests, in seconds. The majority of this time will be the upstream processing of the request. aibridge has no control over upstream processing time, so it's just an illustrative metric.                                                                                                                                                                                                                                                                              | `model` `provider`                                                                                    |
| `coder_aibridged_interceptions_inflight`                                | gauge     | The number of intercepted requests which are being processed.                                                                                                                                                                                                                                                                                                                                                                                                                                              | `model` `provider` `route`                                                                            |
| `coder_aibridged_interceptions_total`                                   | counter   | The count of intercepted requests.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `initiator_id` `method` `model` `provider` `route` `status`                                           |
| `coder_aibridged_non_injected_tool_selections_total`                    | counter   | The number of times an AI model selected a tool to be invoked by the client.                                                                                                                                                                                                                                                                                                                                                                                                                               | `model` `name` `provider`                                                                             |
| `coder_aibridged_passthrough_total`                                     | counter   | The count of requests which were not intercepted but passed through to the upstream.                                                                                                                                                                                                                                                                                                                                                                                                                       | `method` `provider` `route`                                                                           |
| `coder_aibridged_prompts_total`                                         | counter   | The number of prompts issued by users (initiators).                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `initiator_id` `model` `provider`                                                                     |
| `coder_aibridged_tokens_total`                                          | counter   | The number of tokens used by intercepted requests.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `initiator_id` `model` `provider` `type`                                                              |
| `coder_aibridgeproxyd_connect_sessions_total`                           | counter   | Total number of CONNECT sessions established.                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `type`                                                                                                |
| `coder_aibridgeproxyd_inflight_mitm_requests`                           | gauge     | Number of MITM requests currently being processed.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `provider`                                                                                            |
| `coder_aibridgeproxyd_mitm_requests_total`                              | counter   | Total number of MITM requests handled by the proxy.                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `provider`                                                                                            |
| `coder_aibridgeproxyd_mitm_responses_total`                             | counter   | Total number of MITM responses by HTTP status code class.                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `code` `provider`                                                                                     |
| `coder_derp_server_accepts_total`                                       | counter   | Total DERP connections accepted.                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `coder_derp_server_average_queue_duration_ms`                           | gauge     | Average queue duration in milliseconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                       |
| `coder_derp_server_bytes_received_total`                                | counter   | Total bytes received.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                       |
| `coder_derp_server_bytes_sent_total`                                    | counter   | Total bytes sent.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                       |
| `coder_derp_server_clients`                                             | gauge     | Total clients (local + remote).                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `coder_derp_server_clients_local`                                       | gauge     | Local clients.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                       |
| `coder_derp_server_clients_remote`                                      | gauge     | Remote (mesh) clients.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `coder_derp_server_connections`                                         | gauge     | Current DERP connections.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                       |
| `coder_derp_server_got_ping_total`                                      | counter   | Total pings received.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                       |
| `coder_derp_server_home_connections`                                    | gauge     | Current home DERP connections.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                       |
| `coder_derp_server_home_moves_in_total`                                 | counter   | Total home moves in.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                       |
| `coder_derp_server_home_moves_out_total`                                | counter   | Total home moves out.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                       |
| `coder_derp_server_packets_dropped_reason_total`                        | counter   | Packets dropped by reason.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `reason`                                                                                              |
| `coder_derp_server_packets_dropped_total`                               | counter   | Total packets dropped.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `coder_derp_server_packets_dropped_type_total`                          | counter   | Packets dropped by type.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `type`                                                                                                |
| `coder_derp_server_packets_forwarded_in_total`                          | counter   | Total packets forwarded in from mesh peers.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `coder_derp_server_packets_forwarded_out_total`                         | counter   | Total packets forwarded out to mesh peers.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                       |
| `coder_derp_server_packets_received_kind_total`                         | counter   | Packets received by kind.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `kind`                                                                                                |
| `coder_derp_server_packets_received_total`                              | counter   | Total packets received.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                       |
| `coder_derp_server_packets_sent_total`                                  | counter   | Total packets sent.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                       |
| `coder_derp_server_peer_gone_disconnected_total`                        | counter   | Total peer gone (disconnected) frames sent.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `coder_derp_server_peer_gone_not_here_total`                            | counter   | Total peer gone (not here) frames sent.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                       |
| `coder_derp_server_sent_pong_total`                                     | counter   | Total pongs sent.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                       |
| `coder_derp_server_unknown_frames_total`                                | counter   | Total unknown frames received.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                       |
| `coder_derp_server_watchers`                                            | gauge     | Current watchers.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                       |
| `coder_pubsub_connected`                                                | gauge     | Whether we are connected (1) or not connected (0) to postgres                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                       |
| `coder_pubsub_current_events`                                           | gauge     | The current number of pubsub event channels listened for                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                       |
| `coder_pubsub_current_subscribers`                                      | gauge     | The current number of active pubsub subscribers                                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `coder_pubsub_disconnections_total`                                     | counter   | Total number of times we disconnected unexpectedly from postgres                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `coder_pubsub_latency_measure_errs_total`                               | counter   | The number of pubsub latency measurement failures                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                       |
| `coder_pubsub_latency_measures_total`                                   | counter   | The number of pubsub latency measurements                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                       |
| `coder_pubsub_messages_total`                                           | counter   | Total number of messages received from postgres                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `size`                                                                                                |
| `coder_pubsub_published_bytes_total`                                    | counter   | Total number of bytes successfully published across all publishes                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                       |
| `coder_pubsub_publishes_total`                                          | counter   | Total number of calls to Publish                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `success`                                                                                             |
| `coder_pubsub_receive_latency_seconds`                                  | gauge     | The time taken to receive a message from a pubsub event channel                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `coder_pubsub_received_bytes_total`                                     | counter   | Total number of bytes received across all messages                                                                                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                       |
| `coder_pubsub_send_latency_seconds`                                     | gauge     | The time taken to send a message into a pubsub event channel                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                       |
| `coder_pubsub_subscribes_total`                                         | counter   | Total number of calls to Subscribe/SubscribeWithErr                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `success`                                                                                             |
| `coder_servertailnet_connections_total`                                 | counter   | Total number of TCP connections made to workspace agents.                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `network`                                                                                             |
| `coder_servertailnet_open_connections`                                  | gauge     | Total number of TCP connections currently open to workspace agents.                                                                                                                                                                                                                                                                                                                                                                                                                                        | `network`                                                                                             |
| `coderd_agentapi_metadata_batch_size`                                   | histogram | Total number of metadata entries in each batch, updated before flushes.                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                       |
| `coderd_agentapi_metadata_batch_utilization`                            | histogram | Number of metadata keys per agent in each batch, updated before flushes.                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                       |
| `coderd_agentapi_metadata_batches_total`                                | counter   | Total number of metadata batches flushed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `reason`                                                                                              |
| `coderd_agentapi_metadata_dropped_keys_total`                           | counter   | Total number of metadata keys dropped due to capacity limits.                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                       |
| `coderd_agentapi_metadata_flush_duration_seconds`                       | histogram | Time taken to flush metadata batch to database and pubsub.                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `reason`                                                                                              |
| `coderd_agentapi_metadata_flushed_total`                                | counter   | Total number of unique metadatas flushed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                       |
| `coderd_agentapi_metadata_publish_errors_total`                         | counter   | Total number of metadata batch pubsub publish calls that have resulted in an error.                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                       |
| `coderd_agents_apps`                                                    | gauge     | Agent applications with statuses.                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `agent_name` `app_name` `health` `username` `workspace_name`                                          |
| `coderd_agents_connection_latencies_seconds`                            | gauge     | Agent connection latencies in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `agent_name` `derp_region` `preferred` `username` `workspace_name`                                    |
| `coderd_agents_connections`                                             | gauge     | Agent connections with statuses.                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `agent_name` `lifecycle_state` `status` `tailnet_node` `username` `workspace_name`                    |
| `coderd_agents_first_connection_seconds`                                | histogram | Duration from agent creation to first connection to the control plane in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                          | `agent_name` `template_name` `username` `workspace_name`                                              |
| `coderd_agents_up`                                                      | gauge     | The number of active agents per workspace.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `template_name` `template_version` `username` `workspace_name`                                        |
| `coderd_agentstats_connection_count`                                    | gauge     | The number of established connections by agent                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `agent_name` `username` `workspace_name`                                                              |
| `coderd_agentstats_connection_median_latency_seconds`                   | gauge     | The median agent connection latency                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `agent_name` `username` `workspace_name`                                                              |
| `coderd_agentstats_currently_reachable_peers`                           | gauge     | The number of peers (e.g. clients) that are currently reachable over the encrypted network.                                                                                                                                                                                                                                                                                                                                                                                                                | `agent_name` `connection_type` `template_name` `username` `workspace_name`                            |
| `coderd_agentstats_rx_bytes`                                            | gauge     | Agent Rx bytes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `agent_name` `username` `workspace_name`                                                              |
| `coderd_agentstats_session_count_jetbrains`                             | gauge     | The number of session established by JetBrains                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `agent_name` `username` `workspace_name`                                                              |
| `coderd_agentstats_session_count_reconnecting_pty`                      | gauge     | The number of session established by reconnecting PTY                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `agent_name` `username` `workspace_name`                                                              |
| `coderd_agentstats_session_count_ssh`                                   | gauge     | The number of session established by SSH                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `agent_name` `username` `workspace_name`                                                              |
| `coderd_agentstats_session_count_vscode`                                | gauge     | The number of session established by VSCode                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `agent_name` `username` `workspace_name`                                                              |
| `coderd_agentstats_startup_script_seconds`                              | gauge     | The number of seconds the startup script took to execute.                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `agent_name` `success` `template_name` `username` `workspace_name`                                    |
| `coderd_agentstats_tx_bytes`                                            | gauge     | Agent Tx bytes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `agent_name` `username` `workspace_name`                                                              |
| `coderd_api_active_users_duration_hour`                                 | gauge     | The number of users that have been active within the last hour.                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `coderd_api_concurrent_requests`                                        | gauge     | The number of concurrent API requests.                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `method` `path`                                                                                       |
| `coderd_api_concurrent_websockets`                                      | gauge     | The total number of concurrent API websockets.                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `path`                                                                                                |
| `coderd_api_request_latencies_seconds`                                  | histogram | Latency distribution of requests in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `method` `path`                                                                                       |
| `coderd_api_requests_processed_total`                                   | counter   | The total number of processed API requests                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `code` `method` `path`                                                                                |
| `coderd_api_total_user_count`                                           | gauge     | The total number of registered users, partitioned by status.                                                                                                                                                                                                                                                                                                                                                                                                                                               | `status`                                                                                              |
| `coderd_api_websocket_durations_seconds`                                | histogram | Websocket duration distribution of requests in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `path`                                                                                                |
| `coderd_api_workspace_latest_build`                                     | gauge     | The current number of workspace builds by status for all non-deleted workspaces.                                                                                                                                                                                                                                                                                                                                                                                                                           | `status`                                                                                              |
| `coderd_authz_authorize_duration_seconds`                               | histogram | Duration of the 'Authorize' call in seconds. Only counts calls that succeed.                                                                                                                                                                                                                                                                                                                                                                                                                               | `allowed`                                                                                             |
| `coderd_authz_prepare_authorize_duration_seconds`                       | histogram | Duration of the 'PrepareAuthorize' call in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                       |
| `coderd_build_info`                                                     | gauge     | Describes the current build/version of the Coder server. Value is always 1.                                                                                                                                                                                                                                                                                                                                                                                                                                | `revision` `version`                                                                                  |
| `coderd_chat_auto_archive_records_archived_total`                       | counter   | Total number of chats archived by the auto-archive job (counting both roots and cascaded children).                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                       |
| `coderd_chatd_chats`                                                    | gauge     | Number of chats being processed, by state.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `state`                                                                                               |
| `coderd_chatd_compaction_total`                                         | counter   | Total compaction outcomes (only recorded when compaction was triggered or failed).                                                                                                                                                                                                                                                                                                                                                                                                                         | `model` `provider` `result`                                                                           |
| `coderd_chatd_message_count`                                            | histogram | Number of messages in the prompt per LLM request.                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `model` `provider`                                                                                    |
| `coderd_chatd_prompt_size_bytes`                                        | histogram | Estimated byte size of the prompt per LLM request.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `model` `provider`                                                                                    |
| `coderd_chatd_steps_total`                                              | counter   | Total agentic loop steps across all chats.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `model` `provider`                                                                                    |
| `coderd_chatd_stream_buffer_dropped_total`                              | counter   | Number of chat stream buffer events dropped due to the per-chat buffer cap.                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `coderd_chatd_stream_buffer_events`                                     | gauge     | Sum of current buffer lengths across all chat streams.                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `coderd_chatd_stream_buffer_size_max`                                   | gauge     | Maximum current buffer length across all chat streams.                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `coderd_chatd_stream_retries_total`                                     | counter   | Total LLM stream retries.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `kind` `model` `provider`                                                                             |
| `coderd_chatd_stream_subscribers`                                       | gauge     | Current number of chat stream subscribers across all chat streams.                                                                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                       |
| `coderd_chatd_streams_active`                                           | gauge     | Current number of chat stream state entries (in-flight plus retained).                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `coderd_chatd_tool_errors_total`                                        | counter   | Total tool calls that returned an error result.                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `model` `provider` `tool_name`                                                                        |
| `coderd_chatd_tool_result_size_bytes`                                   | histogram | Size in bytes of each tool execution result.                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `model` `provider` `tool_name`                                                                        |
| `coderd_chatd_ttft_seconds`                                             | histogram | Time-to-first-token: wall time from LLM request to first streamed chunk.                                                                                                                                                                                                                                                                                                                                                                                                                                   | `model` `provider`                                                                                    |
| `coderd_db_query_counts_total`                                          | counter   | Total number of queries labelled by HTTP route, method, and query name.                                                                                                                                                                                                                                                                                                                                                                                                                                    | `method` `query` `route`                                                                              |
| `coderd_db_query_latencies_seconds`                                     | histogram | Latency distribution of queries in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `query`                                                                                               |
| `coderd_db_tx_duration_seconds`                                         | histogram | Duration of transactions in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | `success` `tx_id`                                                                                     |
| `coderd_db_tx_executions_count`                                         | counter   | Total count of transactions executed. 'retries' is expected to be 0 for a successful transaction.                                                                                                                                                                                                                                                                                                                                                                                                          | `retries` `success` `tx_id`                                                                           |
| `coderd_dbpurge_iteration_duration_seconds`                             | histogram | Duration of each dbpurge iteration in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `success`                                                                                             |
| `coderd_dbpurge_records_purged_total`                                   | counter   | Total number of records purged by type.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `record_type`                                                                                         |
| `coderd_experiments`                                                    | gauge     | Indicates whether each experiment is enabled (1) or not (0)                                                                                                                                                                                                                                                                                                                                                                                                                                                | `experiment`                                                                                          |
| `coderd_insights_applications_usage_seconds`                            | gauge     | The application usage per template.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | `application_name` `organization_name` `slug` `template_name`                                         |
| `coderd_insights_parameters`                                            | gauge     | The parameter usage per template.                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `organization_name` `parameter_name` `parameter_type` `parameter_value` `template_name`               |
| `coderd_insights_templates_active_users`                                | gauge     | The number of active users of the template.                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `organization_name` `template_name`                                                                   |
| `coderd_license_active_users`                                           | gauge     | The number of active users.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `coderd_license_errors`                                                 | gauge     | The number of active license errors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                       |
| `coderd_license_limit_users`                                            | gauge     | The user seats limit based on the active Coder license.                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                       |
| `coderd_license_user_limit_enabled`                                     | gauge     | Returns 1 if the current license enforces the user limit.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                       |
| `coderd_license_warnings`                                               | gauge     | The number of active license warnings.                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `coderd_lifecycle_autobuild_execution_duration_seconds`                 | histogram | Duration of each autobuild execution.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                       |
| `coderd_notifications_dispatcher_send_seconds`                          | histogram | The time taken to dispatch notifications.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `method`                                                                                              |
| `coderd_notifications_inflight_dispatches`                              | gauge     | The number of dispatch attempts which are currently in progress.                                                                                                                                                                                                                                                                                                                                                                                                                                           | `method` `notification_template_id`                                                                   |
| `coderd_notifications_pending_updates`                                  | gauge     | The number of dispatch attempt results waiting to be flushed to the store.                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                       |
| `coderd_notifications_queued_seconds`                                   | histogram | The time elapsed between a notification being enqueued in the store and retrieved for dispatching (measures the latency of the notifications system). This should generally be within CODER_NOTIFICATIONS_FETCH_INTERVAL seconds; higher values for a sustained period indicates delayed processing and CODER_NOTIFICATIONS_LEASE_COUNT can be increased to accommodate this.                                                                                                                              | `method`                                                                                              |
| `coderd_notifications_retry_count`                                      | counter   | The count of notification dispatch retry attempts.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `method` `notification_template_id`                                                                   |
| `coderd_notifications_synced_updates_total`                             | counter   | The number of dispatch attempt results flushed to the store.                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                       |
| `coderd_oauth2_external_requests_rate_limit`                            | gauge     | The total number of allowed requests per interval.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `name` `resource`                                                                                     |
| `coderd_oauth2_external_requests_rate_limit_next_reset_unix`            | gauge     | Unix timestamp for when the next interval starts                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `name` `resource`                                                                                     |
| `coderd_oauth2_external_requests_rate_limit_remaining`                  | gauge     | The remaining number of allowed requests in this interval.                                                                                                                                                                                                                                                                                                                                                                                                                                                 | `name` `resource`                                                                                     |
| `coderd_oauth2_external_requests_rate_limit_reset_in_seconds`           | gauge     | Seconds until the next interval                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `name` `resource`                                                                                     |
| `coderd_oauth2_external_requests_rate_limit_used`                       | gauge     | The number of requests made in this interval.                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `name` `resource`                                                                                     |
| `coderd_oauth2_external_requests_total`                                 | counter   | The total number of api calls made to external oauth2 providers. 'status_code' will be 0 if the request failed with no response.                                                                                                                                                                                                                                                                                                                                                                           | `name` `source` `status_code`                                                                         |
| `coderd_open_file_refs_current`                                         | gauge     | The count of file references currently open in the file cache. Multiple references can be held for the same file.                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                       |
| `coderd_open_file_refs_total`                                           | counter   | The total number of file references ever opened in the file cache. The 'hit' label indicates if the file was loaded from the cache.                                                                                                                                                                                                                                                                                                                                                                        | `hit`                                                                                                 |
| `coderd_open_files_current`                                             | gauge     | The count of unique files currently open in the file cache.                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `coderd_open_files_size_bytes_current`                                  | gauge     | The current amount of memory of all files currently open in the file cache.                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `coderd_open_files_size_bytes_total`                                    | counter   | The total amount of memory ever opened in the file cache. This number never decrements.                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                       |
| `coderd_open_files_total`                                               | counter   | The total count of unique files ever opened in the file cache.                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                       |
| `coderd_prebuilds_reconciliation_duration_seconds`                      | histogram | Duration of each prebuilds reconciliation cycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `coderd_prebuilt_workspace_claim_duration_seconds`                      | histogram | Time to claim a prebuilt workspace by organization, template, and preset.                                                                                                                                                                                                                                                                                                                                                                                                                                  | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_claimed_total`                              | counter   | Total number of prebuilt workspaces which were claimed by users. Claiming refers to creating a workspace with a preset selected for which eligible prebuilt workspaces are available and one is reassigned to a user.                                                                                                                                                                                                                                                                                      | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_created_total`                              | counter   | Total number of prebuilt workspaces that have been created to meet the desired instance count of each template preset.                                                                                                                                                                                                                                                                                                                                                                                     | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_desired`                                    | gauge     | Target number of prebuilt workspaces that should be available for each template preset.                                                                                                                                                                                                                                                                                                                                                                                                                    | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_eligible`                                   | gauge     | Current number of prebuilt workspaces that are eligible to be claimed by users. These are workspaces that have completed their build process with their agent reporting 'ready' status.                                                                                                                                                                                                                                                                                                                    | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_failed_total`                               | counter   | Total number of prebuilt workspaces that failed to build.                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_metrics_last_updated`                       | gauge     | The unix timestamp when the metrics related to prebuilt workspaces were last updated; these metrics are cached.                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `coderd_prebuilt_workspaces_preset_hard_limited`                        | gauge     | Indicates whether a given preset has reached the hard failure limit (1 = hard-limited). Metric is omitted otherwise.                                                                                                                                                                                                                                                                                                                                                                                       | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_preset_validation_failed`                   | gauge     | Indicates whether a given preset has validation failures (1 = validation failed). Metric is omitted otherwise.                                                                                                                                                                                                                                                                                                                                                                                             | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_reconciliation_paused`                      | gauge     | Indicates whether prebuilds reconciliation is currently paused (1 = paused, 0 = not paused).                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                       |
| `coderd_prebuilt_workspaces_resource_replacements_total`                | counter   | Total number of prebuilt workspaces whose resource(s) got replaced upon being claimed. In Terraform, drift on immutable attributes results in resource replacement. This represents a worst-case scenario for prebuilt workspaces because the pre-provisioned resource would have been recreated when claiming, thus obviating the point of pre-provisioning. See https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces#preventing-resource-replacement                           | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prebuilt_workspaces_running`                                    | gauge     | Current number of prebuilt workspaces that are in a running state. These workspaces have started successfully but may not yet be claimable by users (see coderd_prebuilt_workspaces_eligible).                                                                                                                                                                                                                                                                                                             | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_prometheusmetrics_agents_execution_seconds`                     | histogram | Histogram for duration of agents metrics collection in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `coderd_prometheusmetrics_agentstats_execution_seconds`                 | histogram | Histogram for duration of agent stats metrics collection in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                       |
| `coderd_prometheusmetrics_metrics_aggregator_execution_cleanup_seconds` | histogram | Histogram for duration of metrics aggregator cleanup in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `coderd_prometheusmetrics_metrics_aggregator_execution_update_seconds`  | histogram | Histogram for duration of metrics aggregator update in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `coderd_prometheusmetrics_metrics_aggregator_store_size`                | gauge     | The number of metrics stored in the aggregator                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                       |
| `coderd_provisioner_job_queue_wait_seconds`                             | histogram | Time from job creation to acquisition by a provisioner daemon.                                                                                                                                                                                                                                                                                                                                                                                                                                             | `build_reason` `job_type` `provisioner_type` `transition`                                             |
| `coderd_provisionerd_job_timings_seconds`                               | histogram | The provisioner job time duration in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `provisioner` `status`                                                                                |
| `coderd_provisionerd_jobs_current`                                      | gauge     | The number of currently running provisioner jobs.                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `provisioner`                                                                                         |
| `coderd_provisionerd_num_daemons`                                       | gauge     | The number of provisioner daemons.                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                       |
| `coderd_provisionerd_workspace_build_timings_seconds`                   | histogram | The time taken for a workspace to build.                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `status` `template_name` `template_version` `workspace_transition`                                    |
| `coderd_proxyhealth_health_check_duration_seconds`                      | histogram | Histogram for duration of proxy health collection in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                       |
| `coderd_proxyhealth_health_check_results`                               | gauge     | This endpoint returns a number to indicate the health status. -3 (unknown), -2 (Unreachable), -1 (Unhealthy), 0 (Unregistered), 1 (Healthy)                                                                                                                                                                                                                                                                                                                                                                | `proxy_id`                                                                                            |
| `coderd_template_workspace_build_duration_seconds`                      | histogram | Duration from workspace build creation to agent ready, by template.                                                                                                                                                                                                                                                                                                                                                                                                                                        | `is_prebuild` `organization_name` `status` `template_name` `transition`                               |
| `coderd_workspace_builds_enqueued_total`                                | counter   | Total number of workspace build enqueue attempts.                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `build_reason` `provisioner_type` `status` `transition`                                               |
| `coderd_workspace_builds_total`                                         | counter   | The number of workspaces started, updated, or deleted.                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `status` `template_name` `template_version` `workspace_name` `workspace_owner` `workspace_transition` |
| `coderd_workspace_creation_duration_seconds`                            | histogram | Time to create a workspace by organization, template, preset, and type (regular or prebuild).                                                                                                                                                                                                                                                                                                                                                                                                              | `organization_name` `preset_name` `template_name` `type`                                              |
| `coderd_workspace_creation_total`                                       | counter   | Total regular (non-prebuilt) workspace creations by organization, template, and preset.                                                                                                                                                                                                                                                                                                                                                                                                                    | `organization_name` `preset_name` `template_name`                                                     |
| `coderd_workspace_latest_build_status`                                  | gauge     | The current workspace statuses by template, transition, and owner for all non-deleted workspaces.                                                                                                                                                                                                                                                                                                                                                                                                          | `status` `template_name` `template_version` `workspace_owner` `workspace_transition`                  |
| `go_gc_duration_seconds`                                                | summary   | A summary of the pause duration of garbage collection cycles.                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                       |
| `go_goroutines`                                                         | gauge     | Number of goroutines that currently exist.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                       |
| `go_info`                                                               | gauge     | Information about the Go environment.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `version`                                                                                             |
| `go_memstats_alloc_bytes`                                               | gauge     | Number of bytes allocated and still in use.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `go_memstats_alloc_bytes_total`                                         | counter   | Total number of bytes allocated, even if freed.                                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `go_memstats_buck_hash_sys_bytes`                                       | gauge     | Number of bytes used by the profiling bucket hash table.                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                       |
| `go_memstats_frees_total`                                               | counter   | Total number of frees.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `go_memstats_gc_sys_bytes`                                              | gauge     | Number of bytes used for garbage collection system metadata.                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                       |
| `go_memstats_heap_alloc_bytes`                                          | gauge     | Number of heap bytes allocated and still in use.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `go_memstats_heap_idle_bytes`                                           | gauge     | Number of heap bytes waiting to be used.                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                       |
| `go_memstats_heap_inuse_bytes`                                          | gauge     | Number of heap bytes that are in use.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                       |
| `go_memstats_heap_objects`                                              | gauge     | Number of allocated objects.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                       |
| `go_memstats_heap_released_bytes`                                       | gauge     | Number of heap bytes released to OS.                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                       |
| `go_memstats_heap_sys_bytes`                                            | gauge     | Number of heap bytes obtained from system.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |                                                                                                       |
| `go_memstats_last_gc_time_seconds`                                      | gauge     | Number of seconds since 1970 of last garbage collection.                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                       |
| `go_memstats_lookups_total`                                             | counter   | Total number of pointer lookups.                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `go_memstats_mallocs_total`                                             | counter   | Total number of mallocs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                       |
| `go_memstats_mcache_inuse_bytes`                                        | gauge     | Number of bytes in use by mcache structures.                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                       |
| `go_memstats_mcache_sys_bytes`                                          | gauge     | Number of bytes used for mcache structures obtained from system.                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `go_memstats_mspan_inuse_bytes`                                         | gauge     | Number of bytes in use by mspan structures.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |                                                                                                       |
| `go_memstats_mspan_sys_bytes`                                           | gauge     | Number of bytes used for mspan structures obtained from system.                                                                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                       |
| `go_memstats_next_gc_bytes`                                             | gauge     | Number of heap bytes when next garbage collection will take place.                                                                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                       |
| `go_memstats_other_sys_bytes`                                           | gauge     | Number of bytes used for other system allocations.                                                                                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                       |
| `go_memstats_stack_inuse_bytes`                                         | gauge     | Number of bytes in use by the stack allocator.                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                       |
| `go_memstats_stack_sys_bytes`                                           | gauge     | Number of bytes obtained from system for stack allocator.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                       |
| `go_memstats_sys_bytes`                                                 | gauge     | Number of bytes obtained from system.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                       |
| `go_threads`                                                            | gauge     | Number of OS threads created.                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                       |
| `process_cpu_seconds_total`                                             | counter   | Total user and system CPU time spent in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `process_max_fds`                                                       | gauge     | Maximum number of open file descriptors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                       |
| `process_open_fds`                                                      | gauge     | Number of open file descriptors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |                                                                                                       |
| `process_resident_memory_bytes`                                         | gauge     | Resident memory size in bytes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                       |
| `process_start_time_seconds`                                            | gauge     | Start time of the process since unix epoch in seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                     |                                                                                                       |
| `process_virtual_memory_bytes`                                          | gauge     | Virtual memory size in bytes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                       |
| `process_virtual_memory_max_bytes`                                      | gauge     | Maximum amount of virtual memory available in bytes.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                       |
| `promhttp_metric_handler_requests_in_flight`                            | gauge     | Current number of scrapes being served.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                       |
| `promhttp_metric_handler_requests_total`                                | counter   | Total number of scrapes by HTTP status code.                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `code`                                                                                                |

<!-- End generated by 'make docs/admin/integrations/prometheus.md'. -->

### Note on Prometheus native histogram support

The following metrics support native histograms:

* `coderd_workspace_creation_duration_seconds`
* `coderd_prebuilt_workspace_claim_duration_seconds`
* `coderd_template_coderd_template_workspace_build_duration_seconds`

Native histograms are an **experimental** Prometheus feature that removes the need to predefine bucket boundaries and allows higher-resolution buckets that adapt to deployment characteristics.
Whether a metric is exposed as classic or native depends entirely on the Prometheus server configuration (see [Prometheus docs](https://prometheus.io/docs/specs/native_histograms/) for details):

* If native histograms are enabled, Prometheus ingests the high-resolution histogram.
* If not, it falls back to the predefined buckets.

⚠️ Important: classic and native histograms cannot be aggregated together. If Prometheus is switched from classic to native at a certain point in time, dashboards may need to account for that transition.
For this reason, it’s recommended to follow [Prometheus’ migration guidelines](https://prometheus.io/docs/specs/native_histograms/#migration-considerations) when moving from classic to native histograms.

---

# Kubernetes Logging

Source: https://coder.com/docs/admin/integrations/kubernetes-logs

# Kubernetes event logs

To stream Kubernetes events into your workspace startup logs, you can use
Coder's [`coder-logstream-kube`](https://github.com/coder/coder-logstream-kube)
tool. `coder-logstream-kube` provides useful information about the workspace pod
or deployment, such as:

- Causes of pod provisioning failures, or why a pod is stuck in a pending state.
- Visibility into when pods are OOMKilled, or when they are evicted.

## Installation

Install the `coder-logstream-kube` helm chart on the cluster where the
deployment is running.

```shell
helm repo add coder-logstream-kube https://helm.coder.com/logstream-kube
helm install coder-logstream-kube coder-logstream-kube/coder-logstream-kube \
    --namespace coder \
    --set url=<your-coder-url-including-http-or-https>
```

## Example logs

Here is an example of the logs you can expect to see in the workspace startup
logs:

### Normal pod deployment

![normal pod deployment](../../images/admin/integrations/coder-logstream-kube-logs-normal.png)

### Wrong image

![Wrong image name](../../images/admin/integrations/coder-logstream-kube-logs-wrong-image.png)

### Kubernetes quota exceeded

![Kubernetes quota exceeded](../../images/admin/integrations/coder-logstream-kube-logs-quota-exceeded.png)

### Pod crash loop

![Pod crash loop](../../images/admin/integrations/coder-logstream-kube-logs-pod-crashed.png)

## How it works

Kubernetes provides an
[informers](https://pkg.go.dev/k8s.io/client-go/informers) API that streams pod
and event data from the API server.

coder-logstream-kube listens for pod creation events with containers that have
the CODER_AGENT_TOKEN environment variable set. All pod events are streamed as
logs to the Coder API using the agent token for authentication. For more
details, see the
[coder-logstream-kube](https://github.com/coder/coder-logstream-kube)
repository.

---

# Additional Kubernetes Clusters

Source: https://coder.com/docs/admin/integrations/multiple-kube-clusters

# Additional clusters

With Coder, you can deploy workspaces in additional Kubernetes clusters using
different
[authentication methods](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#authentication)
in the Terraform provider.

![Region picker in "Create Workspace" screen](../../images/admin/integrations/kube-region-picker.png)

## Option 1) Kubernetes contexts and kubeconfig

First, create a kubeconfig file with
[multiple contexts](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/).

```shell
kubectl config get-contexts

CURRENT   NAME                        CLUSTER
          workspaces-europe-west2-c   workspaces-europe-west2-c
*         workspaces-us-central1-a    workspaces-us-central1-a
```

### Kubernetes control plane

If you deployed Coder on Kubernetes, you can attach a kubeconfig as a secret.

This assumes Coder is deployed on the `coder` namespace and your kubeconfig file
is in ~/.kube/config.

```shell
kubectl create secret generic kubeconfig-secret -n coder --from-file=~/.kube/config
```

Modify your helm values to mount the secret:

```yaml
coder:
  # ...
  volumes:
    - name: "kubeconfig-mount"
      secret:
        secretName: "kubeconfig-secret"
  volumeMounts:
    - name: "kubeconfig-mount"
      mountPath: "/mnt/secrets/kube"
      readOnly: true
```

[Upgrade Coder](../../install/kubernetes.md#upgrading-coder-via-helm) with these
new values.

### VM control plane

If you deployed Coder on a VM, copy the kubeconfig file to
`/home/coder/.kube/config`.

### Create a Coder template

You can start from our
[example template](https://github.com/coder/coder/tree/main/examples/templates/kubernetes).
From there, add
[template parameters](../templates/extending-templates/parameters.md) to allow
developers to pick their desired cluster.

```tf
# main.tf

data "coder_parameter" "kube_context" {
  name         = "kube_context"
  display_name = "Cluster"
  default      = "workspaces-us-central1-a"
  mutable      = false
  option {
    name  = "US Central"
    icon  = "/emojis/1f33d.png"
    value = "workspaces-us-central1-a"
  }
  option {
    name  = "Europe West"
    icon  = "/emojis/1f482.png"
    value = "workspaces-europe-west2-c"
  }
}

provider "kubernetes" {
  config_path    = "~/.kube/config" # or /mnt/secrets/kube/config for Kubernetes
  config_context = data.coder_parameter.kube_context.value
}
```

## Option 2) Kubernetes ServiceAccounts

Alternatively, you can authenticate with remote clusters with ServiceAccount
tokens. Coder can store these secrets on your behalf with
[managed Terraform variables](../templates/extending-templates/variables.md).

Alternatively, these could also be fetched from Kubernetes secrets or even
[Hashicorp Vault](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/generic_secret).

This guide assumes you have a `coder-workspaces` namespace on your remote
cluster. Change the namespace accordingly.

### Create a ServiceAccount

Run this command against your remote cluster to create a ServiceAccount, Role,
RoleBinding, and token:

```shell
kubectl apply -n coder-workspaces -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: coder-v2
---
apiVersion: v1
kind: Secret
metadata:
  name: coder-v2
  annotations:
    kubernetes.io/service-account.name: coder-v2
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: coder-v2
rules:
  - apiGroups: ["", "apps", "networking.k8s.io"]
    resources: ["persistentvolumeclaims", "pods", "deployments", "services", "secrets", "pods/exec","pods/log", "events", "networkpolicies", "serviceaccounts"]
    verbs: ["create", "get", "list", "watch", "update", "patch", "delete", "deletecollection"]
  - apiGroups: ["metrics.k8s.io", "storage.k8s.io"]
    resources: ["pods", "storageclasses"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: coder-v2
subjects:
  - kind: ServiceAccount
    name: coder-v2
roleRef:
  kind: Role
  name: coder-v2
  apiGroup: rbac.authorization.k8s.io
EOF
```

The output should be similar to:

```text
serviceaccount/coder-v2 created
secret/coder-v2 created
role.rbac.authorization.k8s.io/coder-v2 created
rolebinding.rbac.authorization.k8s.io/coder-v2 created
```

### 2. Modify the Kubernetes template

You can start from our
[example template](https://github.com/coder/coder/tree/main/examples/templates/kubernetes).

```tf
variable "host" {
  description = "Cluster host address"
  sensitive   = true
}

variable "cluster_ca_certificate" {
  description = "Cluster CA certificate (base64 encoded)"
  sensitive   = true
}

variable "token" {
  description = "Cluster CA token (base64 encoded)"
  sensitive   = true
}

variable "namespace" {
  description = "Namespace"
}

provider "kubernetes" {
  host                   = var.host
  cluster_ca_certificate = base64decode(var.cluster_ca_certificate)
  token                  = base64decode(var.token)
}
```

### Create Coder template with managed variables

Fetch the values from the secret and pass them to Coder. This should work on
macOS and Linux.

To get the cluster address:

```shell
kubectl cluster-info
Kubernetes control plane is running at https://example.domain:6443

export CLUSTER_ADDRESS=https://example.domain:6443
```

To fetch the CA certificate and token:

```shell
export CLUSTER_CA_CERTIFICATE=$(kubectl get secrets coder-v2 -n coder-workspaces -o jsonpath="{.data.ca\.crt}")

export CLUSTER_SERVICEACCOUNT_TOKEN=$(kubectl get secrets coder-v2 -n coder-workspaces -o jsonpath="{.data.token}")
```

Create the template with these values:

```shell
coder templates push \
    --variable host=$CLUSTER_ADDRESS \
    --variable cluster_ca_certificate=$CLUSTER_CA_CERTIFICATE \
    --variable token=$CLUSTER_SERVICEACCOUNT_TOKEN \
    --variable namespace=coder-workspaces
```

If you're on a Windows machine (or if one of the commands fail), try grabbing
the values manually:

```shell
# Get cluster API address
kubectl cluster-info

# Get cluster CA and token (base64 encoded)
kubectl get secrets coder-service-account-token -n coder-workspaces -o jsonpath="{.data}"

coder templates push \
    --variable host=API_ADDRESS \
    --variable cluster_ca_certificate=CLUSTER_CA_CERTIFICATE \
    --variable token=CLUSTER_SERVICEACCOUNT_TOKEN \
    --variable namespace=coder-workspaces
```

---

# JFrog Artifactory

Source: https://coder.com/docs/admin/integrations/jfrog-artifactory

# JFrog Artifactory Integration

Use Coder and JFrog Artifactory together to secure your development environments
without disturbing your developers' existing workflows.

This guide will demonstrate how to use JFrog Artifactory as a package registry
within a workspace.

## Requirements

- A JFrog Artifactory instance
- 1:1 mapping of users in Coder to users in Artifactory by email address or
  username
- Repositories configured in Artifactory for each package manager you want to
  use

## Provisioner Authentication

The most straight-forward way to authenticate your template with Artifactory is
by using our official Coder [modules](https://registry.coder.com). We publish
two type of modules that automate the JFrog Artifactory and Coder integration.

1. [JFrog-OAuth](https://registry.coder.com/modules/jfrog-oauth)
1. [JFrog-Token](https://registry.coder.com/modules/jfrog-token)

### JFrog-OAuth

This module is usable by JFrog self-hosted (on-premises) Artifactory as it
requires configuring a custom integration. This integration benefits from Coder's [external-auth](../external-auth/index.md) feature allows each user to authenticate with Artifactory using an OAuth flow and issues user-scoped tokens to each user.

To set this up, follow these steps:

1. Add the following to your Helm chart `values.yaml` for JFrog Artifactory. Replace `CODER_URL` with your JFrog Artifactory base URL:

   ```yaml
   artifactory:
     enabled: true
     frontend:
     extraEnvironmentVariables:
       - name: JF_FRONTEND_FEATURETOGGLER_ACCESSINTEGRATION
         value: "true"
     access:
     accessConfig:
       integrations-enabled: true
       integration-templates:
         - id: "1"
           name: "CODER"
           redirect-uri: "https://CODER_URL/external-auth/jfrog/callback"
           scope: "applied-permissions/user"
   ```

1. Create a new Application Integration by going to
   `https://JFROG_URL/ui/admin/configuration/integrations/app-integrations/new` and select the
   Application Type as the integration you created in step 1 or `Custom Integration` if you are using SaaS instance i.e. example.jfrog.io.

1. Add a new [external authentication](../external-auth/index.md) to Coder by setting these
   environment variables in a manner consistent with your Coder deployment. Replace `JFROG_URL` with your JFrog Artifactory base URL:

   ```env
   # JFrog Artifactory External Auth
   CODER_EXTERNAL_AUTH_1_ID="jfrog"
   CODER_EXTERNAL_AUTH_1_TYPE="jfrog"
   CODER_EXTERNAL_AUTH_1_CLIENT_ID="YYYYYYYYYYYYYYY"
   CODER_EXTERNAL_AUTH_1_CLIENT_SECRET="XXXXXXXXXXXXXXXXXXX"
   CODER_EXTERNAL_AUTH_1_DISPLAY_NAME="JFrog Artifactory"
   CODER_EXTERNAL_AUTH_1_DISPLAY_ICON="/icon/jfrog.svg"
   CODER_EXTERNAL_AUTH_1_AUTH_URL="https://JFROG_URL/ui/authorization"
   CODER_EXTERNAL_AUTH_1_SCOPES="applied-permissions/user"
   ```

1. Create or edit a Coder template and use the [JFrog-OAuth](https://registry.coder.com/modules/jfrog-oauth) module to configure the integration:

   ```tf
   module "jfrog" {
     count          = data.coder_workspace.me.start_count
     source         = "registry.coder.com/modules/jfrog-oauth/coder"
     version        = "1.0.19"
     agent_id       = coder_agent.example.id
     jfrog_url      = "https://example.jfrog.io"
     username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"

     package_managers = {
       npm    = ["npm", "@scoped:npm-scoped"]
       go     = ["go", "another-go-repo"]
       pypi   = ["pypi", "extra-index-pypi"]
       docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"]
     }
   }
   ```

### JFrog-Token

This module makes use of the [Artifactory terraform
provider](https://registry.terraform.io/providers/jfrog/artifactory/latest/docs) and an admin-scoped token to create
user-scoped tokens for each user by matching their Coder email or username with
Artifactory. This can be used for both SaaS and self-hosted (on-premises)
Artifactory instances.

To set this up, follow these steps:

1. Get a JFrog access token from your Artifactory instance. The token must be an [admin token](https://registry.terraform.io/providers/jfrog/artifactory/latest/docs#access-token) with scope `applied-permissions/admin`.

1. Create or edit a Coder template and use the [JFrog-Token](https://registry.coder.com/modules/jfrog-token) module to configure the integration and pass the admin token. It is recommended to store the token in a sensitive Terraform variable to prevent it from being displayed in plain text in the terraform state:

   ```tf
   variable "artifactory_access_token" {
     type      = string
     sensitive = true
   }

   module "jfrog" {
     source                   = "registry.coder.com/modules/jfrog-token/coder"
     version                  = "1.0.30"
     agent_id                 = coder_agent.example.id
     jfrog_url                = "https://XXXX.jfrog.io"
     artifactory_access_token = var.artifactory_access_token
     package_managers = {
       npm    = ["npm", "@scoped:npm-scoped"]
       go     = ["go", "another-go-repo"]
       pypi   = ["pypi", "extra-index-pypi"]
       docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"]
     }
   }
   ```

> [!NOTE]
> The admin-level access token is used to provision user tokens and is never exposed to developers or stored in workspaces.

If you don't want to use the official modules, you can read through the [example template](https://github.com/coder/coder/tree/main/examples/jfrog/docker), which uses Docker as the underlying compute. The
same concepts apply to all compute types.

## Air-Gapped Deployments

See the [air-gapped deployments](../templates/extending-templates/modules.md#offline-installations) section for instructions on how to use Coder modules in an offline environment with Artifactory.

## Next Steps

- See the [full example Docker template](https://github.com/coder/coder/tree/main/examples/jfrog/docker).

- To serve extensions from your own VS Code Marketplace, check out
  [code-marketplace](https://github.com/coder/code-marketplace#artifactory-storage).

---

# Island Secure Browser

Source: https://coder.com/docs/admin/integrations/island

# Island Browser Integration

<div>
  <a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Eric Paulsen</span>
  </a>
</div>
April 24, 2024

---

[Island](https://www.island.io/) is an enterprise-grade browser, offering a Chromium-based experience
similar to popular web browsers like Chrome and Edge. It includes built-in
security features for corporate applications and data, aiming to bridge the gap
between consumer-focused browsers and the security needs of the enterprise.

Coder natively integrates with Island's feature set, which include data
loss protection (DLP), application awareness, browser session recording, and
single sign-on (SSO). This guide intends to document these feature categories
and how they apply to your Coder deployment.

## General Configuration

### Create an Application Group for Coder

We recommend creating an Application Group specific to Coder in the Island
Management console. This Application Group object will be referenced when
creating browser policies.

[See the Island documentation for creating an Application Group](https://documentation.island.io/docs/create-and-configure-an-application-group-object).

## Advanced Data Loss Protection

Integrate Island's advanced data loss prevention (DLP) capabilities with
Coder's cloud development environment (CDE), enabling you to control the
"last mile" between developers' CDE and their local devices,
ensuring that sensitive IP remains in your centralized environment.

### Block cut, copy, paste, printing, screen share

1. [Create a Data Sandbox Profile](https://documentation.island.io/docs/create-and-configure-a-data-sandbox-profile).

1. Configure the following actions to allow/block (based on your security
   requirements).

   - Screenshot and Screen Share
   - Printing
   - Save Page
   - Clipboard Limitations

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Data Sandbox Profile.

1. Define the Coder Application group as the Destination Object.

1. Define the Data Sandbox Profile as the Action in the Last Mile Protection
   section.

### Conditionally allow copy on Coder's CLI authentication page

1. [Create a URL Object](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) with the following configuration.

   - **Include**
   - **URL type**: Wildcard
   - **URL address**: `coder.example.com/cli-auth`
   - **Casing**: Insensitive

1. [Create a Data Sandbox Profile](https://documentation.island.io/docs/create-and-configure-a-data-sandbox-profile).

1. Configure action to allow copy/paste.

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Data Sandbox Profile.

1. Define the URL Object you created as the Destination Object.

1. Define the Data Sandbox Profile as the Action in the Last Mile Protection
   section.

### Prevent file upload/download from the browser

1. Create a Protection Profiles for both upload/download.

   - [Upload documentation](https://documentation.island.io/docs/create-and-configure-an-upload-protection-profile)
   - [Download documentation](https://documentation.island.io/v1/docs/en/create-and-configure-a-download-protection-profile)

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Protection Profiles.

1. Define the Coder Application group as the Destination Object.

1. Define the applicable Protection Profile as the Action in the Data Protection
   section.

### Scan files for sensitive data

1. [Create a Data Loss Prevention scanner](https://documentation.island.io/docs/create-a-data-loss-prevention-scanner).

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the DLP Scanner.

1. Define the Coder Application group as the Destination Object.

1. Define the DLP Scanner as the Action in the Data Protection section.

## Application Awareness and Boundaries

Ensure that Coder is only accessed through the Island browser, guaranteeing that
your browser-level DLP policies are always enforced, and developers can't
sidestep such policies simply by using another browser.

### Configure browser enforcement, conditional access policies

Create a conditional access policy for your configured identity provider.

Note that the configured IdP must be the same for both Coder and Island.

- [Azure Active Directory/Entra ID](https://documentation.island.io/docs/configure-browser-enforcement-for-island-with-azure-ad#create-and-apply-a-conditional-access-policy)
- [Okta](https://documentation.island.io/docs/configure-browser-enforcement-for-island-with-okta)
- [Google](https://documentation.island.io/docs/configure-browser-enforcement-for-island-with-google-enterprise)

## Browser Activity Logging

Govern and audit in-browser terminal and IDE sessions using Island, such as
screenshots, mouse clicks, and keystrokes.

### Activity Logging Module

1. [Create an Activity Logging Profile](https://documentation.island.io/docs/create-and-configure-an-activity-logging-profile). Supported browser
   events include:

   - Web Navigation
   - File Download
   - File Upload
   - Clipboard/Drag & Drop
   - Print
   - Save As
   - Screenshots
   - Mouse Clicks
   - Keystrokes

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Activity Logging Profile.

1. Define the Coder Application group as the Destination Object.

1. Define the Activity Logging Profile as the Action in the Security &
   Visibility section.

## Identity-aware logins (SSO)

Integrate Island's identity management system with Coder's
authentication mechanisms to enable identity-aware logins.

### Configure single sign-on (SSO) seamless authentication between Coder and Island

Configure the same identity provider (IdP) for both your Island and Coder
deployment. Upon initial login to the Island browser, the user's session
token will automatically be passed to Coder and authenticate their Coder
session.

---

# DX PlatformX

Source: https://coder.com/docs/admin/integrations/platformx

# DX PlatformX

[DX](https://getdx.com) is a developer intelligence platform used by engineering
leaders and platform engineers. Coder notifications can be transformed to
[PlatformX](https://getdx.com/platformx) events, allowing platform engineers to
measure activity and send pulse surveys to subsets of Coder users to understand
their experience.

![PlatformX Events in Coder](../../images/integrations/platformx-screenshot.png)

## Requirements

You'll need:

- Coder v2.19+
- A PlatformX subscription from [DX](https://getdx.com/)
- A platform to host the integration, such as:
  - AWS Lambda
  - Google Cloud Run
  - Heroku
  - Kubernetes
  - Or any other platform that can run Python web applications

## coder-platformx-events-middleware

Coder sends [notifications](../monitoring/notifications/index.md) via webhooks
to coder-platformx-events-middleware, which processes and reformats the payload
into a structure compatible with [PlatformX by DX](https://help.getdx.com/en/articles/7880779-getting-started).

For more information about coder-platformx-events-middleware and how to
integrate it with your Coder deployment and PlatformX events, refer to the
[coder-platformx-notifications](https://github.com/coder/coder-platformx-notifications)
repository.

### Supported Notification Types

coder-platformx-events-middleware supports the following [Coder notifications](../monitoring/notifications/index.md):

- Workspace Created
- Workspace Manually Updated
- User Account Created
- User Account Suspended
- User Account Activated

### Environment Variables

The application expects the following environment variables when started.
For local development, create a `.env` file in the project root with the following variables.
A `.env.sample` file is included:

| Variable         | Description                                | Example                                      |
|------------------|--------------------------------------------|----------------------------------------------|
| `LOG_LEVEL`      | Logging level (`DEBUG`, `INFO`, `WARNING`) | `INFO`                                       |
| `GETDX_API_KEY`  | API key for PlatformX                      | `your-api-key`                               |
| `EVENTS_TRACKED` | Comma-separated list of tracked events     | `"Workspace Created,User Account Suspended"` |

### Logging

Logs are printed to the console and can be adjusted using the `LOG_LEVEL` variable. The available levels are:

| Level     | Description                           |
|-----------|---------------------------------------|
| `DEBUG`   | Most verbose, useful for debugging    |
| `INFO`    | Standard logging for normal operation |
| `WARNING` | Logs only warnings and errors         |

### API Endpoints

- `GET /` - Health check endpoint
- `POST /` - Webhook receiver

---

# DX Data Cloud

Source: https://coder.com/docs/admin/integrations/dx-data-cloud

# DX

[DX](https://getdx.com) is a developer intelligence platform used by engineering
leaders and platform engineers.

DX uses metadata attributes to assign information to individual users.
While it's common to segment users by `role`, `level`, or `geo`, it’s become increasingly
common to use DX attributes to better understand usage and adoption of tools.

You can create a `Coder` attribute in DX to segment and analyze the impact of Coder usage on a developer’s work, including:

- Understanding the needs of power users or low Coder usage across the org
- Correlate Coder usage with qualitative and quantitative engineering metrics,
  such as PR throughput, deployment frequency, deep work, dev environment toil, and more.
- Personalize user experiences

## Requirements

- A DX subscription
- Access to Coder user data through the Coder CLI, Coder API, an IdP, or an existing Coder-DX integration
- Coordination with your DX Customer Success Manager

## Extract Your Coder User List

<div class="tabs">

You can use the Coder CLI, Coder API, or your Identity Provider (IdP) to extract your list of users.

If your organization already uses the Coder-DX integration, you can find a list of active Coder users directly within DX.

### CLI

Use `users list` to export the list of users to a CSV file:

```shell
coder users list > users.csv
```

Visit the [users list](../../reference/cli/users_list.md) documentation for more options.

### API

Use [get users](../../reference/api/users.md#get-users):

```bash
curl -X GET http://coder-server:8080/api/v2/users \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

To export the results to a CSV file, you can use the `jq` tool to process the JSON response:

```bash
curl -X GET http://coder-server:8080/api/v2/users \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY' | \
  jq -r '.users | (map(keys) | add | unique) as $cols | $cols, (.[] | [.[$cols[]]] | @csv)' > users.csv
```

Visit the [get users](../../reference/api/users.md#get-users) documentation for more options.

### IdP

If your organization uses a centralized IdP to manage user accounts, you can extract user data directly from your IdP.

This is particularly useful if you need additional user attributes managed within your IdP.

</div>

## Contact your DX Customer Success Manager

Provide the file to your dedicated DX Customer Success Manager (CSM).

Your CSM will import the CSV of individuals using Coder, as well as usage frequency (if applicable) into DX to create a `Coder` attribute.

After the attribute is uploaded, you'll have a Coder filter option within your DX reports allowing you to:

- Perform cohort analysis (Coder user vs non-user)
- Understand unique behaviors and patterns across your Coder users
- Run a [study](https://getdx.com/studies/) or setup a [PlatformX](https://getdx.com/platformx/) event for deeper analysis

## Related Resources

- [DX Data Cloud Documentation](https://help.getdx.com/en/)
- [Coder CLI](../../reference/cli/users.md)
- [Coder API](../../reference/api/users.md)
- [PlatformX Integration](./platformx.md)

---

# Hashicorp Vault

Source: https://coder.com/docs/admin/integrations/vault

# Integrating HashiCorp Vault with Coder

<div>
  <a href="https://github.com/matifali" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Muhammad Atif Ali</span>
  </a>
</div>
August 05, 2024

---

This guide describes the process of integrating [HashiCorp Vault](https://www.vaultproject.io/) into Coder workspaces.

Coder makes it easy to integrate HashiCorp Vault with your workspaces by
providing official Terraform modules to integrate Vault with Coder. This guide
will show you how to use these modules to integrate HashiCorp Vault with Coder.

## The `vault-github` module

The [`vault-github`](https://registry.coder.com/modules/vault-github) module is a Terraform module that allows you to
authenticate with Vault using a GitHub token. This module uses the existing
GitHub [external authentication](../external-auth/index.md) to get the token and authenticate with Vault.

To use this module, add the following code to your Terraform configuration.

```tf
module "vault" {
  source               = "registry.coder.com/modules/vault-github/coder"
  version              = "1.0.7"
  agent_id             = coder_agent.example.id
  vault_addr           = "https://vault.example.com"
  coder_github_auth_id = "my-github-auth-id"
}
```

This module installs and authenticates the `vault` CLI in your Coder workspace.

Users then can use the `vault` CLI to interact with Vault; for example, to fetch
a secret stored in the KV backend.

```shell
vault kv get -namespace=YOUR_NAMESPACE -mount=MOUNT_NAME SECRET_NAME
```

---

# OAuth2 Provider

Source: https://coder.com/docs/admin/integrations/oauth2-provider

# OAuth2 Provider (Experimental)

> [!WARNING]
> The OAuth2 provider functionality is currently **experimental and unstable**. This feature:
>
> - Is subject to breaking changes without notice
> - May have incomplete functionality
> - Is not recommended for production use
> - Requires the `oauth2` experiment flag to be enabled
>
> Use this feature for development and testing purposes only.

Coder can act as an OAuth2 authorization server, allowing third-party applications to authenticate users through Coder and access the Coder API on their behalf. This enables integrations where external applications can leverage Coder's authentication and user management.

## Requirements

- Admin privileges in Coder
- OAuth2 experiment flag enabled
- HTTPS recommended for production deployments

## Enable OAuth2 Provider

Add the `oauth2` experiment flag to your Coder server:

```bash
coder server --experiments oauth2
```

Or set the environment variable:

```env
CODER_EXPERIMENTS=oauth2
```

## Creating OAuth2 Applications

### Method 1: Web UI

1. Navigate to **Deployment Settings** → **OAuth2 Applications**
2. Click **Create Application**
3. Fill in the application details:
   - **Name**: Your application name
   - **Callback URL**: `https://yourapp.example.com/callback` (web) or `myapp://callback` (native/desktop)
   - **Icon**: Optional icon URL

### Method 2: Management API

Create an application using the Coder API:

```bash
curl -X POST \
  -H "Authorization: Bearer $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Application",
    "callback_url": "https://myapp.example.com/callback",
    "icon": "https://myapp.example.com/icon.png"
  }' \
  "$CODER_URL/api/v2/oauth2-provider/apps"
```

Generate a client secret:

```bash
curl -X POST \
  -H "Authorization: Bearer $CODER_SESSION_TOKEN" \
  "$CODER_URL/api/v2/oauth2-provider/apps/$APP_ID/secrets"
```

## Integration Patterns

### Client Authentication Methods

Coder supports the following OAuth2 client authentication methods at the token endpoint (`/oauth2/tokens`):

- `client_secret_basic` (recommended): HTTP Basic authentication (RFC 6749 §2.3.1). The username is `client_id` and the password is `client_secret`.
- `client_secret_post`: Form-based authentication where `client_id` and `client_secret` are sent in the request body.

Coder supports both methods for compatibility; existing integrations using `client_secret_post` do not need to change.

If you use Dynamic Client Registration (RFC 7591) and omit `token_endpoint_auth_method`, clients default to `client_secret_basic`. To request `client_secret_post`, set `token_endpoint_auth_method` to `client_secret_post` in the registration request.

If client authentication fails, the token endpoint returns **HTTP 401** with an OAuth2 `invalid_client` error and a `WWW-Authenticate: Basic realm="coder"` response header.

### Standard OAuth2 Flow

1. **Authorization Request**: Redirect users to Coder's authorization endpoint:

   ```url
   https://coder.example.com/oauth2/authorize?
     client_id=your-client-id&
     response_type=code&
     redirect_uri=https://yourapp.example.com/callback&
     state=random-string
   ```

2. **Token Exchange**: Exchange the authorization code for an access token.

   **Option A: HTTP Basic authentication (`client_secret_basic`, recommended)**

   ```bash
   curl -X POST \
     -u "$CLIENT_ID:$CLIENT_SECRET" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=authorization_code" \
     -d "code=$AUTH_CODE" \
     -d "redirect_uri=https://yourapp.example.com/callback" \
     "$CODER_URL/oauth2/tokens"
   ```

   **Option B: Form parameters (`client_secret_post`)**

   ```bash
   curl -X POST \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=authorization_code" \
     -d "code=$AUTH_CODE" \
     -d "client_id=$CLIENT_ID" \
     -d "client_secret=$CLIENT_SECRET" \
     -d "redirect_uri=https://yourapp.example.com/callback" \
     "$CODER_URL/oauth2/tokens"
   ```

3. **API Access**: Use the access token to call Coder's API:

   ```bash
   curl -H "Authorization: Bearer $ACCESS_TOKEN" \
     "$CODER_URL/api/v2/users/me"
   ```

> [!NOTE]
> The PKCE flow below is the **required** integration path. The example
> above is shown for reference but omits the mandatory `code_challenge`
> parameter. See [PKCE Flow](#pkce-flow-required) for the complete flow.

### PKCE Flow (Required)

PKCE is **required** for all OAuth2 authorization code flows. Coder enforces
PKCE in compliance with the OAuth 2.1 specification. Both public and
confidential clients must include PKCE parameters:

1. Generate a code verifier and challenge:

   ```bash
   CODE_VERIFIER=$(openssl rand -base64 96 | tr -d "=+/" | cut -c1-128)
   CODE_CHALLENGE=$(echo -n $CODE_VERIFIER | openssl dgst -sha256 -binary | base64 | tr -d "=+/" | cut -c1-43)
   ```

2. Include PKCE parameters in the authorization request:

   ```url
   https://coder.example.com/oauth2/authorize?
     client_id=your-client-id&
     response_type=code&
     code_challenge=$CODE_CHALLENGE&
     code_challenge_method=S256&
     redirect_uri=https://yourapp.example.com/callback
   ```

3. Include the code verifier in the token exchange (see [Client Authentication Methods](#client-authentication-methods)):

   ```bash
   curl -X POST \
     -u "$CLIENT_ID:$CLIENT_SECRET" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=authorization_code" \
     -d "code=$AUTH_CODE" \
     -d "code_verifier=$CODE_VERIFIER" \
     -d "redirect_uri=https://yourapp.example.com/callback" \
     "$CODER_URL/oauth2/tokens"
   ```

## Discovery Endpoints

Coder provides OAuth2 discovery endpoints for programmatic integration:

- **Authorization Server Metadata**: `GET /.well-known/oauth-authorization-server`
- **Protected Resource Metadata**: `GET /.well-known/oauth-protected-resource`

These endpoints return server capabilities and endpoint URLs according to [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) and [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728).

## Token Management

### Refresh Tokens

Refresh an expired access token.

**Option A: HTTP Basic authentication (`client_secret_basic`)**

```bash
curl -X POST \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=$REFRESH_TOKEN" \
  "$CODER_URL/oauth2/tokens"
```

**Option B: Form parameters (`client_secret_post`)**

```bash
curl -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=$REFRESH_TOKEN" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  "$CODER_URL/oauth2/tokens"
```

### Revoke Access

Revoke all tokens for an application:

```bash
curl -X DELETE \
  -H "Authorization: Bearer $CODER_SESSION_TOKEN" \
  "$CODER_URL/oauth2/tokens?client_id=$CLIENT_ID"
```

## Testing and Development

Coder provides comprehensive test scripts for OAuth2 development:

```bash
# Navigate to the OAuth2 test scripts
cd scripts/oauth2/

# Run the full automated test suite
./test-mcp-oauth2.sh

# Create a test application for manual testing
eval $(./setup-test-app.sh)

# Run an interactive browser-based test
./test-manual-flow.sh

# Clean up when done
./cleanup-test-app.sh
```

For more details on testing, see the [OAuth2 test scripts README](../../../scripts/oauth2/README.md).

## Common Issues

### "OAuth2 experiment not enabled"

Add `oauth2` to your experiment flags: `coder server --experiments oauth2`

### "Invalid redirect_uri"

Ensure the redirect URI in your request exactly matches the one registered for your application.

### "Invalid Callback URL" on the consent page

If you see this error when authorizing, the registered callback URL uses a
blocked scheme (`javascript:`, `data:`, `file:`, or `ftp:`). Update the
application's callback URL to a valid scheme (see
[Callback URL schemes](#callback-url-schemes)).

### "PKCE verification failed"

Verify that the `code_verifier` used in the token request matches the one used to generate the `code_challenge`.

## Callback URL schemes

Custom URI schemes (`myapp://`, `vscode://`, `jetbrains://`, etc.) are fully supported for native and desktop applications. The OS routes the redirect back to the registered application without requiring a running HTTP server.

The following schemes are blocked for security reasons: `javascript:`, `data:`, `file:`, `ftp:`.

## Security Considerations

- **Use HTTPS**: Always use HTTPS in production to protect tokens in transit
- **Implement PKCE**: PKCE is mandatory for all authorization code clients
  (public and confidential)
- **Validate redirect URLs**: Only register trusted redirect URIs. Dangerous
  schemes (`javascript:`, `data:`, `file:`, `ftp:`) are blocked by the server,
  but custom URI schemes for native apps (`myapp://`) are permitted
- **Rotate secrets**: Periodically rotate client secrets using the management API

## Limitations

As an experimental feature, the current implementation has limitations:

- No scope system - all tokens have full API access
- No client credentials grant support
- Implicit grant (`response_type=token`) is not supported; OAuth 2.1
  deprecated this flow due to token leakage risks, and requests return
  `unsupported_response_type`
- Limited to opaque access tokens (no JWT support)

## Standards Compliance

This implementation follows established OAuth2 standards including
[RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) (OAuth2 core),
[RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636) (PKCE), and the
[OAuth 2.1 draft](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12).
Coder enforces OAuth 2.1 requirements including mandatory PKCE for all
authorization code grants, exact redirect URI string matching, rejection
of the implicit grant, and CSRF protections on consent pages.

## Next Steps

- Review the [API Reference](../../reference/api/index.md) for complete endpoint documentation
- Check [External Authentication](../external-auth/index.md) for configuring Coder as an OAuth2 client
- See [Security Best Practices](../security/index.md) for deployment security guidance

## Feedback

This is an experimental feature under active development. Please report issues and feedback through [GitHub Issues](https://github.com/coder/coder/issues) with the `oauth2` label.

---

# Dev Containers

Source: https://coder.com/docs/admin/integrations/devcontainers

# Dev Containers

Dev containers allow developers to define their development environment
as code using the [Dev Container specification](https://containers.dev/).
Configuration lives in a `devcontainer.json` file alongside source code,
enabling consistent, reproducible environments.

By adopting dev containers, organizations can:

- **Standardize environments**: Eliminate "works on my machine" issues while
  still allowing developers to customize their tools within approved boundaries.
- **Scale efficiently**: Let developers maintain their own environment
  definitions, reducing the burden on platform teams.
- **Improve security**: Use hardened base images and controlled package
  registries to enforce security policies while enabling developer self-service.

Coder supports two approaches for running dev containers. Choose based on your
infrastructure and workflow requirements.

## Dev Containers Integration

The Dev Containers Integration uses the standard `@devcontainers/cli` and Docker
to run containers inside your workspace. This is the recommended approach for
most use cases.

**Best for:**

- Workspaces with Docker available (Docker-in-Docker or mounted socket)
- Dev container management in the Coder dashboard (discovery, status, rebuild)
- Multiple dev containers per workspace

[Configure Dev Containers Integration](./integration.md)

For user documentation, see the
[Dev Containers user guide](../../../user-guides/devcontainers/index.md).

## Envbuilder

Envbuilder transforms the workspace image itself from a `devcontainer.json`,
rather than running containers inside the workspace. It does not require
a Docker daemon.

**Best for:**

- Environments where Docker is unavailable or restricted
- Infrastructure-level control over image builds, caching, and security scanning
- Kubernetes-native deployments without privileged containers

[Configure Envbuilder](./envbuilder/index.md)

---

# Dev Containers Integration

Source: https://coder.com/docs/admin/integrations/devcontainers/integration

# Configure a template for Dev Containers

This guide covers the Dev Containers Integration, which uses Docker. For
environments without Docker, see [Envbuilder](./envbuilder/index.md) as an
alternative.

To enable Dev Containers in workspaces, configure your template with the Dev Containers
modules and configurations outlined in this doc.

Dev Containers are currently not supported in Windows or macOS workspaces.

## Configuration Modes

There are two approaches to configuring Dev Containers in Coder:

### Manual Configuration

Use the [`coder_devcontainer`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/devcontainer) Terraform resource to explicitly define which Dev
Containers should be started in your workspace. This approach provides:

- Predictable behavior and explicit control
- Clear template configuration
- Easier troubleshooting
- Better for production environments

This is the recommended approach for most use cases.

### Project Discovery

Alternatively, enable automatic discovery of Dev Containers in Git repositories.
The agent scans for `devcontainer.json` files and surfaces them in the Coder UI.
See [Environment Variables](#environment-variables) for configuration options.

This approach is useful when developers frequently switch between repositories
or work with many projects, as it reduces template maintenance overhead.

## Install the Dev Containers CLI

Use the
[devcontainers-cli](https://registry.coder.com/modules/devcontainers-cli) module
to ensure the `@devcontainers/cli` is installed in your workspace:

```terraform
module "devcontainers-cli" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/devcontainers-cli/coder"
  agent_id = coder_agent.dev.id
}
```

Alternatively, install the devcontainer CLI manually in your base image.

## Configure Automatic Dev Container Startup

The
[`coder_devcontainer`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/devcontainer)
resource automatically starts a Dev Container in your workspace, ensuring it's
ready when you access the workspace:

```terraform
resource "coder_devcontainer" "my-repository" {
  count            = data.coder_workspace.me.start_count
  agent_id         = coder_agent.dev.id
  workspace_folder = "/home/coder/my-repository"
}
```

The `workspace_folder` attribute must point to a valid project folder containing
a `devcontainer.json` file. Consider using the
[`git-clone`](https://registry.coder.com/modules/git-clone) module to ensure
your repository is cloned and ready for automatic startup.

For multi-repo workspaces, define multiple `coder_devcontainer` resources, each
pointing to a different repository. Each one runs as a separate sub-agent with
its own terminal and apps in the dashboard.

## Enable Dev Containers Integration

Dev Containers integration is **enabled by default** in Coder 2.24.0 and later.
You don't need to set any environment variables unless you want to change the
default behavior.

If you need to explicitly disable Dev Containers, set the
`CODER_AGENT_DEVCONTAINERS_ENABLE` environment variable to `false`:

```terraform
resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = "codercom/oss-dogfood:latest"
  env = [
    "CODER_AGENT_DEVCONTAINERS_ENABLE=false",  # Explicitly disable
    # ... Other environment variables.
  ]
  # ... Other container configuration.
}
```

See the [Environment Variables](#environment-variables) section below for more
details on available configuration options.

## Environment Variables

The following environment variables control Dev Container behavior in your
workspace. Both `CODER_AGENT_DEVCONTAINERS_ENABLE` and
`CODER_AGENT_DEVCONTAINERS_PROJECT_DISCOVERY_ENABLE` are **enabled by default**,
so you typically don't need to set them unless you want to explicitly disable
the feature.

### CODER_AGENT_DEVCONTAINERS_ENABLE

**Default: `true`** • **Added in: v2.24.0**

Enables the Dev Containers integration in the Coder agent.

The Dev Containers feature is enabled by default. You can explicitly disable it
by setting this to `false`.

### CODER_AGENT_DEVCONTAINERS_PROJECT_DISCOVERY_ENABLE

**Default: `true`** • **Added in: v2.25.0**

Enables automatic discovery of Dev Containers in Git repositories.

When enabled, the agent scans the configured working directory (set via the
`directory` attribute in `coder_agent`, typically the user's home directory) for
Git repositories. If the directory itself is a Git repository, it searches that
project. Otherwise, it searches immediate subdirectories for Git repositories.

For each repository found, the agent looks for `devcontainer.json` files in the
[standard locations](../../../user-guides/devcontainers/index.md#add-a-devcontainerjson)
and surfaces discovered Dev Containers in the Coder UI. Discovery respects
`.gitignore` patterns.

Set to `false` if you prefer explicit configuration via `coder_devcontainer`.

### CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE

**Default: `false`** • **Added in: v2.25.0**

Automatically starts Dev Containers discovered via project discovery.

When enabled, discovered Dev Containers will be automatically built and started
during workspace initialization. This only applies to Dev Containers found via
project discovery. Dev Containers defined with the `coder_devcontainer` resource
always auto-start regardless of this setting.

## Attach Resources to Dev Containers

You can attach
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app),
[`coder_script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script),
and [`coder_env`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/env)
resources to a `coder_devcontainer` by referencing its `subagent_id` attribute
as the `agent_id`:

```terraform
resource "coder_devcontainer" "my-repository" {
  count            = data.coder_workspace.me.start_count
  agent_id         = coder_agent.dev.id
  workspace_folder = "/home/coder/my-repository"
}

resource "coder_app" "code-server" {
  count        = data.coder_workspace.me.start_count
  agent_id     = coder_devcontainer.my-repository[0].subagent_id
  # ...
}

resource "coder_script" "dev-setup" {
  count        = data.coder_workspace.me.start_count
  agent_id     = coder_devcontainer.my-repository[0].subagent_id
  # ...
}

resource "coder_env" "my-var" {
  count    = data.coder_workspace.me.start_count
  agent_id = coder_devcontainer.my-repository[0].subagent_id
  # ...
}
```

This also enables using [Coder registry](https://registry.coder.com) modules
that depend on these resources inside dev containers, by passing the
`subagent_id` as the module's `agent_id`.

### Terraform-managed dev containers

When a `coder_devcontainer` has any `coder_app`, `coder_script`, or `coder_env`
resource attached, it becomes a **terraform-managed** dev container. This
changes how Coder handles the sub-agent:

- The sub-agent is pre-defined during Terraform provisioning rather than created
  dynamically.
- On dev container configuration changes, Coder updates the sub-agent in-place
  instead of deleting and recreating it.

### Interaction with devcontainer.json customizations

Terraform-defined resources and
[`devcontainer.json` customizations](../../../user-guides/devcontainers/customizing-dev-containers.md)
work together with some limitations. The `displayApps` settings from
`devcontainer.json` are applied to terraform-managed dev containers, so you can
control built-in app visibility (e.g., hide VS Code Insiders) via
`devcontainer.json` even when using Terraform resources.

However, custom `apps` defined in `devcontainer.json` are **not applied** to
terraform-managed dev containers. If you need custom apps, define them as
`coder_app` resources in Terraform instead.

## Per-Container Customizations

Developers can customize individual dev containers using the `customizations.coder`
block in their `devcontainer.json` file. Available options include:

- `ignore` — Hide a dev container from Coder completely
- `autoStart` — Control whether the container starts automatically (requires
  `CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE` to be enabled)
- `name` — Set a custom agent name
- `displayApps` — Control which built-in apps appear
- `apps` — Define custom applications

For the full reference, see
[Customizing dev containers](../../../user-guides/devcontainers/customizing-dev-containers.md).

## Complete Template Example

Here's a simplified template example that uses Dev Containers with manual
configuration:

```terraform
terraform {
  required_providers {
    coder  = { source = "coder/coder" }
    docker = { source = "kreuzwerker/docker" }
  }
}

provider "coder" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

resource "coder_agent" "dev" {
  arch                    = "amd64"
  os                      = "linux"
  startup_script_behavior = "blocking"
  startup_script          = "sudo service docker start"
  shutdown_script         = "sudo service docker stop"
  # ...
}

module "devcontainers-cli" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/devcontainers-cli/coder"
  agent_id = coder_agent.dev.id
}

resource "coder_devcontainer" "my-repository" {
  count            = data.coder_workspace.me.start_count
  agent_id         = coder_agent.dev.id
  workspace_folder = "/home/coder/my-repository"
}

# Attaching resources to dev containers is optional. By attaching
# this resource to the dev container, we are changing how the dev
# container will be treated by Coder. This limits the ability to
# customize the injected agent via the devcontainer.json file.
resource "coder_env" "env" {
  count    = data.coder_workspace.me.start_count
  agent_id = coder_devcontainer.my-repository[0].subagent_id
  name     = "MY_VAR"
  value    = "my-value"
}
```

### Alternative: Project Discovery with Autostart

By default, discovered containers appear in the dashboard but developers must
manually start them. To have them start automatically, enable autostart:

```terraform
resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = "codercom/oss-dogfood:latest"
  env = [
    # Project discovery is enabled by default, but autostart is not.
    # Enable autostart to automatically build and start discovered containers:
    "CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE=true",
    # ... Other environment variables.
  ]
  # ... Other container configuration.
}
```

With autostart enabled:

- Discovered containers automatically build and start during workspace
  initialization
- The `coder_devcontainer` resource is not required
- Developers can work with multiple projects seamlessly

> [!NOTE]
>
> When using project discovery, you still need to install the devcontainers CLI
> using the module or in your base image.

## Example Template

The [Docker (Dev Containers)](https://github.com/coder/coder/tree/main/examples/templates/docker-devcontainer)
starter template demonstrates Dev Containers integration using Docker-in-Docker.
It includes the `devcontainers-cli` module, `git-clone` module, and the
`coder_devcontainer` resource.

## Next Steps

- [Dev Containers Integration](../../../user-guides/devcontainers/index.md)
- [Customizing Dev Containers](../../../user-guides/devcontainers/customizing-dev-containers.md)
- [Working with Dev Containers](../../../user-guides/devcontainers/working-with-dev-containers.md)
- [Troubleshooting Dev Containers](../../../user-guides/devcontainers/troubleshooting-dev-containers.md)

---

# Envbuilder

Source: https://coder.com/docs/admin/integrations/devcontainers/envbuilder

# Envbuilder

Envbuilder is an open-source tool that builds development environments from
[dev container](https://containers.dev/implementors/spec/) configuration files.
Unlike the [Dev Containers integration](../integration.md),
Envbuilder transforms the workspace image itself rather than running containers
inside the workspace.

Envbuilder is well-suited for Kubernetes-native deployments without privileged
containers, environments where Docker is unavailable or restricted, and
workflows where administrators need infrastructure-level control over image
builds, caching, and security scanning. For workspaces with Docker available,
the [Dev Containers Integration](../integration.md) offers container management
with dashboard visibility and multi-container support.

Dev containers provide developers with increased autonomy and control over their
Coder cloud development environments.

By using dev containers, developers can customize their workspaces with tools
pre-approved by platform teams in registries like
[JFrog Artifactory](../../jfrog-artifactory.md). This simplifies
workflows, reduces the need for tickets and approvals, and promotes greater
independence for developers.

## Prerequisites

An administrator should construct or choose a base image and create a template
that includes a `devcontainer_builder` image before a developer team configures
dev containers.

## Devcontainer Features

[Dev container Features](https://containers.dev/implementors/features/) allow
owners of a project to specify self-contained units of code and runtime
configuration that can be composed together on top of an existing base image.
This is a good place to install project-specific tools, such as
language-specific runtimes and compilers.

## Coder Envbuilder

[Envbuilder](https://github.com/coder/envbuilder/) is an open-source project
maintained by Coder that runs dev containers via Coder templates and your
underlying infrastructure. Envbuilder can run on Docker or Kubernetes.

It is independently packaged and versioned from the centralized Coder
open-source project. This means that Envbuilder can be used with Coder, but it
is not required. It also means that dev container builds can scale independently
of the Coder control plane and even run within a CI/CD pipeline.

## Next steps

- [Add an Envbuilder template](./add-envbuilder.md)

---

# Add an Envbuilder template

Source: https://coder.com/docs/admin/integrations/devcontainers/envbuilder/add-envbuilder

# Add an Envbuilder template

A Coder administrator adds an Envbuilder-compatible template to Coder. This
allows the template to prompt the developer for their dev container repository's
URL as a [parameter](../../../templates/extending-templates/parameters.md) when they create
their workspace. Envbuilder clones the repo and builds a container from the
`devcontainer.json` specified in the repo.

You can create template files through the Coder dashboard, CLI, or you can
choose a template from the
[Coder registry](https://registry.coder.com/templates):

<div class="tabs">

## Dashboard

1. In the Coder dashboard, select **Templates** then **Create Template**.
1. Use a
   [starter template](https://github.com/coder/coder/tree/main/examples/templates)
   or create a new template:

   - Starter template:

     1. Select **Choose a starter template**.
     1. Choose a template from the list or select **Devcontainer** from the
        sidebar to display only dev container-compatible templates.
     1. Select **Use template**, enter the details, then select **Create
        template**.

   - To create a new template, select **From scratch** and enter the templates
     details, then select **Create template**.

1. Edit the template files to fit your deployment.

## CLI

1. Use the `template init` command to initialize your choice of image:

   ```shell
   coder template init --id kubernetes-devcontainer
   ```

   A list of available templates is shown in the
   [templates_init](../../../../reference/cli/templates.md) reference.

1. `cd` into the directory and push the template to your Coder deployment:

   ```shell
   cd kubernetes-devcontainer && coder templates push
   ```

   You can also edit the files or make changes to the files before you push them
   to Coder.

## Registry

1. Go to the [Coder registry](https://registry.coder.com/templates) and select a
   dev container-compatible template.

1. Copy the files to your local device, then edit them to fit your needs.

1. Upload them to Coder through the CLI or dashboard:

   - CLI:

   ```shell
   coder templates push <template-name> -d <path to folder containing main.tf>
   ```

   - Dashboard:

   1. Create a `.zip` of the template files:

      - On Mac or Windows, highlight the files and then right click. A
        "compress" option is available through the right-click context menu.

      - To zip the files through the command line:

        ```shell
        zip templates.zip Dockerfile main.tf
        ```

   1. Select **Templates**.
   1. Select **Create Template**, then **Upload template**:

      ![Upload template](../../../../images/templates/upload-create-your-first-template.png)

   1. Drag the `.zip` file into the **Upload template** section and fill out the
      details, then select **Create template**.

      ![Upload the template files](../../../../images/templates/upload-create-template-form.png)

</div>

To set variables such as the namespace, go to the template in your Coder
dashboard and select **Settings** from the **⋮** (vertical ellipsis) menu:

<Image height="255px" src="../../../../images/templates/template-menu-settings.png" alt="Choose Settings from the template's menu" align="center" />

## Envbuilder Terraform provider

When using the
[Envbuilder Terraform provider](https://registry.terraform.io/providers/coder/envbuilder/latest/docs),
a previously built and cached image can be reused directly, allowing dev
containers to start instantaneously.

Developers can edit the `devcontainer.json` in their workspace to customize
their development environments:

```json
# …
{
  "features": {
      "ghcr.io/devcontainers/features/common-utils:2": {}
  }
}
# …
```

## Example templates

| Template                                                                                                            | Description                                                                                                                                                         |
|---------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Docker dev containers](https://github.com/coder/coder/tree/main/examples/templates/docker-devcontainer)            | Docker provisions a development container.                                                                                                                          |
| [Kubernetes dev containers](https://github.com/coder/coder/tree/main/examples/templates/kubernetes-devcontainer)    | Provisions a development container on the Kubernetes cluster.                                                                                                       |
| [Google Compute Engine dev container](https://github.com/coder/coder/tree/main/examples/templates/gcp-devcontainer) | Runs a development container inside a single GCP instance. It also mounts the Docker socket from the VM inside the container to enable Docker inside the workspace. |
| [AWS EC2 dev container](https://github.com/coder/coder/tree/main/examples/templates/aws-devcontainer)               | Runs a development container inside a single EC2 instance. It also mounts the Docker socket from the VM inside the container to enable Docker inside the workspace. |

Your template can prompt the user for a repo URL with
[parameters](../../../templates/extending-templates/parameters.md):

![Dev container parameter screen](../../../../images/templates/devcontainers.png)

## Dev container lifecycle scripts

The `onCreateCommand`, `updateContentCommand`, `postCreateCommand`, and
`postStartCommand` lifecycle scripts are run each time the container is started.
This could be used, for example, to fetch or update project dependencies before
a user begins using the workspace.

Lifecycle scripts are managed by project developers.

## Next steps

- [Envbuilder security and caching](./envbuilder-security-caching.md)

---

# Security and caching

Source: https://coder.com/docs/admin/integrations/devcontainers/envbuilder/envbuilder-security-caching

# Envbuilder security and caching

Ensure Envbuilder can only pull pre-approved images and artifacts by configuring
it with your existing HTTP proxies, firewalls, and artifact managers.

## Configure registry authentication

You may need to authenticate to your container registry, such as Artifactory, or
Git provider such as GitLab, to use Envbuilder. See the
[Envbuilder documentation](https://github.com/coder/envbuilder/blob/main/docs/container-registry-auth.md)
for more information.

## Layer and image caching

To improve build times, dev containers can be cached. There are two main forms
of caching:

- **Layer caching**

  - Caches individual layers and pushes them to a remote registry. When building
    the image, Envbuilder will check the remote registry for pre-existing layers
    These will be fetched and extracted to disk instead of building the layers
    from scratch.

- **Image caching**

  - Caches the entire image, skipping the build process completely (except for
    post-build
    [lifecycle scripts](./add-envbuilder.md#dev-container-lifecycle-scripts)).

Note that caching requires push access to a registry, and may require approval
from relevant infrastructure team(s).

Refer to the
[Envbuilder documentation](https://github.com/coder/envbuilder/blob/main/docs/caching.md)
for more information about Envbuilder and caching.

Visit the
[speed up templates](../../../../tutorials/best-practices/speed-up-templates.md)
best practice documentation for more ways that you can speed up build times.

### Image caching

To support resuming from a cached image, use the
[Envbuilder Terraform Provider](https://github.com/coder/terraform-provider-envbuilder)
in your template. The provider will:

1. Clone the remote Git repository,
1. Perform a "dry-run" build of the dev container in the same manner as
   Envbuilder would,
1. Check for the presence of a previously built image in the provided cache
   repository,
1. Output the image remote reference in SHA256 form, if it finds one.

The example templates listed above will use the provider if a remote cache
repository is provided.

If you are building your own Dev container template, you can consult the
[provider documentation](https://registry.terraform.io/providers/coder/envbuilder/latest/docs/resources/cached_image).
You may also wish to consult a
[documented example usage of the `envbuilder_cached_image` resource](https://github.com/coder/terraform-provider-envbuilder/blob/main/examples/resources/envbuilder_cached_image/envbuilder_cached_image_resource.tf).

## Next steps

- [Envbuilder releases and known issues](./envbuilder-releases-known-issues.md)
- [Dotfiles](../../../../user-guides/workspace-dotfiles.md)

---

# Releases and known issues

Source: https://coder.com/docs/admin/integrations/devcontainers/envbuilder/envbuilder-releases-known-issues

# Envbuilder releases and known issues

## Release channels

Envbuilder provides two release channels:

- **Stable**
  - Available at
    [`ghcr.io/coder/envbuilder`](https://github.com/coder/envbuilder/pkgs/container/envbuilder).
    Tags `>=1.0.0` are considered stable.
- **Preview**
  - Available at
    [`ghcr.io/coder/envbuilder-preview`](https://github.com/coder/envbuilder/pkgs/container/envbuilder-preview).
    Built from the tip of `main`, and should be considered experimental and
    prone to breaking changes.

Refer to the
[Envbuilder GitHub repository](https://github.com/coder/envbuilder/) for more
information and to submit feature requests or bug reports.

## Known issues

Visit the
[Envbuilder repository](https://github.com/coder/envbuilder/blob/main/docs/devcontainer-spec-support.md)
for a full list of supported features and known issues.

---

# Networking

Source: https://coder.com/docs/admin/networking

# Networking

Coder's network topology has three types of nodes: workspaces, coder servers,
and users.

The coder server must have an inbound address reachable by users and workspaces,
but otherwise, all topologies _just work_ with Coder.

When possible, we establish direct connections between users and workspaces.
Direct connections are as fast as connecting to the workspace outside of Coder.
When NAT traversal fails, connections are relayed through the coder server. All
user-workspace connections are end-to-end encrypted.

[Tailscale's open source](https://tailscale.com) backs our websocket/HTTPS
networking logic.

## Requirements

In order for clients and workspaces to be able to connect:

> [!NOTE]
> We strongly recommend that clients connect to Coder and their
> workspaces over a good quality, broadband network connection. The following
> are minimum requirements:
>
> - better than 400ms round-trip latency to the Coder server and to their
>   workspace
> - better than 0.5% random packet loss

- All clients and agents must be able to establish a connection to the Coder
  server (`CODER_ACCESS_URL`) over HTTP/HTTPS.
- Any reverse proxy or ingress between the Coder control plane and
  clients/agents must support WebSockets.

In order for clients to be able to establish direct connections:

> [!NOTE]
> Direct connections via the web browser are not supported. To improve
> latency for browser-based applications running inside Coder workspaces in
> regions far from the Coder control plane, consider deploying one or more
> [workspace proxies](./workspace-proxies.md).

- The client is connecting using the CLI (e.g. `coder ssh` or
  `coder port-forward`). Note that the
  [VSCode extension](https://marketplace.visualstudio.com/items?itemName=coder.coder-remote)
  and [JetBrains Plugin](https://plugins.jetbrains.com/plugin/19620-coder/), and
  [`ssh coder.<workspace>`](../../reference/cli/config-ssh.md) all utilize the
  CLI to establish a workspace connection.
- Either the client or workspace agent are able to discover a reachable
  `ip:port` of their counterpart. If the agent and client are able to
  communicate with each other using their locally assigned IP addresses, then a
  direct connection can be established immediately. Otherwise, the client and
  agent will contact
  [the configured STUN servers](../../reference/cli/server.md#--derp-server-stun-addresses)
  to try and determine which `ip:port` can be used to communicate with their
  counterpart. See [STUN and NAT](./stun.md) for more details on how this
  process works.
- All outbound UDP traffic must be allowed for both the client and the agent on
  **all ports** to each others' respective networks.
  - To establish a direct connection, both agent and client use STUN. This
    involves sending UDP packets outbound on `udp/3478` to the configured
    [STUN server](../../reference/cli/server.md#--derp-server-stun-addresses).
    If either the agent or the client are unable to send and receive UDP packets
    to a STUN server, then direct connections will not be possible.
  - Both agents and clients will then establish a
    [WireGuard](https://www.wireguard.com/)️ tunnel and send UDP traffic on
    ephemeral (high) ports. If a firewall between the client and the agent
    blocks this UDP traffic, direct connections will not be possible.

## coder server

Workspaces connect to the coder server via the server's external address, set
via [`ACCESS_URL`](../../admin/setup/index.md#access-url). There must not be a
NAT between workspaces and coder server.

Users connect to the coder server's dashboard and API through its `ACCESS_URL`
as well. There must not be a NAT between users and the coder server.

Template admins can overwrite the site-wide access URL at the template level by
leveraging the `url` argument when
[defining the Coder provider](https://registry.terraform.io/providers/coder/coder/latest/docs#url-1):

```terraform
provider "coder" {
  url = "https://coder.namespace.svc.cluster.local"
}
```

This is useful when debugging connectivity issues between the workspace agent
and the Coder server.

## Web Apps

The coder servers relays dashboard-initiated connections between the user and
the workspace. Web terminal <-> workspace connections are an exception and may
be direct.

In general, [port forwarded](./port-forwarding.md) web apps are faster than
dashboard-accessed web apps.

## 🌎 Geo-distribution

### Direct connections

Direct connections are a straight line between the user and workspace, so there
is no special geo-distribution configuration. To speed up direct connections,
move the user and workspace closer together.

Establishing a direct connection can be an involved process because both the
client and workspace agent will likely be behind at least one level of NAT,
meaning that we need to use STUN to learn the IP address and port under which
the client and agent can both contact each other. See [STUN and NAT](./stun.md)
for more information on how this process works.

If a direct connection is not available (e.g. client or server is behind NAT),
Coder will use a relayed connection. By default,
[Coder uses Google's public STUN server](../../reference/cli/server.md#--derp-server-stun-addresses),
but this can be disabled or changed for
[Air-gapped deployments](../../install/airgap.md).

### Relayed connections

By default, your Coder server also runs a built-in DERP relay which can be used
for both public and [Air-gapped deployments](../../install/airgap.md).

However, Tailscale maintains a global fleet of [DERP relays](https://tailscale.com/kb/1118/custom-derp-servers/#what-are-derp-servers) intended for their product, and has allowed Coder to access and use them.
You can launch `coder server` with Tailscale's DERPs like so:

```bash
coder server --derp-config-url https://controlplane.tailscale.com/derpmap/default
```

#### Custom Relays

If you want lower latency than what Tailscale offers or want additional DERP
relays for air-gapped deployments, you may run custom DERP servers. Refer to
[Tailscale's documentation](https://tailscale.com/kb/1118/custom-derp-servers/#why-run-your-own-derp-server)
to learn how to set them up.

After you have custom DERP servers, you can launch Coder with them like so:

```json
# derpmap.json
{
  "Regions": {
    "1": {
      "RegionID": 1,
      "RegionCode": "myderp",
      "RegionName": "My DERP",
      "Nodes": [
        {
          "Name": "1",
          "RegionID": 1,
          "HostName": "your-hostname.com"
        }
      ]
    }
  }
}
```

```bash
coder server --derp-config-path derpmap.json
```

### Dashboard connections

The dashboard (and web apps opened through the dashboard) are served from the
coder server, so they can only be geo-distributed with High Availability mode in
our Premium Edition. [Reach out to Sales](https://coder.com/contact) to learn
more.

## Browser-only connections

> [!NOTE]
> Browser-only connections is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Some Coder deployments require that all access is through the browser to comply
with security policies. In these cases, pass the `--browser-only` flag to
`coder server` or set `CODER_BROWSER_ONLY=true`.

With browser-only connections, developers can only connect to their workspaces
via the web terminal and
[web IDEs](../../user-guides/workspace-access/web-ides.md).

### Workspace Proxies

> [!NOTE]
> Workspace proxies are a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Workspace proxies are a Coder Premium feature that allows you to provide
low-latency browser experiences for geo-distributed teams.

To learn more, see [Workspace Proxies](./workspace-proxies.md).

## Latency

Coder measures and reports several types of latency, providing insights into the performance of your deployment. Understanding these metrics can help you diagnose issues and optimize the user experience.

There are three main types of latency metrics for your Coder deployment:

- Dashboard-to-server latency:

  The Coder UI measures round-trip time to the Coder server or workspace proxy using built-in browser timing capabilities.

  This appears in the user interface next to your username, showing how responsive the dashboard is.

- Workspace connection latency:

  The latency shown on the workspace dashboard measures the round-trip time between the workspace agent and its DERP relay server.

  This metric is displayed in milliseconds on the workspace dashboard and specifically shows the agent-to-relay latency, not direct P2P connections.

  To estimate the total end-to-end latency experienced by a user, add the dashboard-to-server latency to this agent-to-relay latency.

- Database latency:

  For administrators, Coder monitors and reports database query performance in the health dashboard.

### How latency is classified

Latency measurements are color-coded in the dashboard:

- **Green** (<150ms): Good performance.
- **Yellow** (150-300ms): Moderate latency that might affect user experience.
- **Red** (>300ms): High latency that will noticeably affect user experience.

### View latency information

- **Dashboard**: The global latency indicator appears in the top navigation bar.
- **Workspace list**: Each workspace shows its connection latency.
- **Health dashboard**: Administrators can view advanced metrics including database latency.
- **CLI**: Use `coder ping <workspace>` to measure and analyze latency from the command line.

### Factors that affect latency

- **Geographic distance**: Physical distance between users, Coder server, and workspaces.
- **Network connectivity**: Quality of internet connections and routing.
- **Infrastructure**: Cloud provider regions and network optimization.
- **P2P connectivity**: Whether direct connections can be established or relays are needed.

### How to optimize latency

To improve latency and user experience:

- **Deploy workspace proxies**: Place [proxies](./workspace-proxies.md) in regions closer to users, connecting back to your single Coder server deployment.
- **Use P2P connections**: Ensure network configurations permit direct connections.
- **Strategic placement**: Deploy your Coder server in a region where most users work.
- **Network configuration**: Optimize routing between users and workspaces.
- **Check firewall rules**: Ensure they don't block necessary Coder connections.

For help troubleshooting connection issues, including latency problems, refer to the [networking troubleshooting guide](./troubleshooting.md).

## External Network Access

By default, Coder will access some external network endpoints in order to download dependencies and send usage data. However, all of these features can be disabled. Learn how to configure Coder for [air-gapped environments](../../install/airgap.md).

## Up next

- Learn about [Port Forwarding](./port-forwarding.md)
- Troubleshoot [Networking Issues](./troubleshooting.md)

---

# Port Forwarding

Source: https://coder.com/docs/admin/networking/port-forwarding

# Port Forwarding

Port forwarding lets developers securely access processes on their Coder
workspace from a local machine. A common use case is testing web applications in
a browser.

There are three ways to forward ports in Coder:

- The `coder port-forward` command
- Dashboard
- SSH

The `coder port-forward` command is generally more performant than:

1. The Dashboard which proxies traffic through the Coder control plane versus
   peer-to-peer which is possible with the Coder CLI
1. `sshd` which does double encryption of traffic with both Wireguard and SSH

## The `coder port-forward` command

This command can be used to forward TCP or UDP ports from the remote workspace
so they can be accessed locally. Both the TCP and UDP command line flags
(`--tcp` and `--udp`) can be given once or multiple times.

The supported syntax variations for the `--tcp` and `--udp` flag are:

- Single port with optional remote port: `local_port[:remote_port]`
- Comma separation `local_port1,local_port2`
- Port ranges `start_port-end_port`
- Any combination of the above

### Examples

Forward the remote TCP port `8080` to local port `8000`:

```console
coder port-forward myworkspace --tcp 8000:8080
```

Forward the remote TCP port `3000` and all ports from `9990` to `9999` to their
respective local ports.

```console
coder port-forward myworkspace --tcp 3000,9990-9999
```

Forward the remote TCP port `3000` and all ports from `9990` to `9999` to their
respective local ports to the `agent` in your Workspace (typically main or dev).
This is needed when you have multiple agents in your workspace.

```console
coder port-forward myworkspace.agent --tcp 3000,9990-9999
```

For more examples, see `coder port-forward --help`.

## Dashboard

To enable port forwarding via the dashboard, Coder must be configured with a
[wildcard access URL](../../admin/setup/index.md#wildcard-access-url). If an
access URL is not specified, Coder will create
[a publicly accessible URL](../../admin/setup/index.md#tunnel) to reverse
proxy the deployment, and port forwarding will work.

There is a
[DNS limitation](https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.1)
where each segment of hostnames must not exceed 63 characters. If your app
name, agent name, workspace name and username exceed 63 characters in the
hostname, port forwarding via the dashboard will not work.

### From an coder_app resource

One way to port forward is to configure a `coder_app` resource in the
workspace's template. This approach shows a visual application icon in the
dashboard. See the following `coder_app` example for a Node React app and note
the `subdomain` and `share` settings:

```tf
# node app
resource "coder_app" "node-react-app" {
  agent_id  = coder_agent.dev.id
  slug      = "node-react-app"
  icon      = "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg"
  url       = "http://localhost:3000"
  subdomain = true
  share     = "authenticated"

  healthcheck {
    url       = "http://localhost:3000/healthz"
    interval  = 10
    threshold = 30
  }

}
```

Valid `share` values include `owner` - private to the user, `authenticated` -
accessible by any user authenticated to the Coder deployment, and `public` -
accessible by users outside of the Coder deployment.

![Port forwarding from an app in the UI](../../images/networking/portforwarddashboard.png)

## Accessing workspace ports

Another way to port forward in the dashboard is to use the "Open Ports" button
to specify an arbitrary port. Coder will also detect if apps inside the
workspace are listening on ports, and list them below the port input (this is
only supported on Windows and Linux workspace agents).

![Port forwarding in the UI](../../images/networking/listeningports.png)

### Sharing ports

We allow developers to share ports as URLs, either with other authenticated
coder users or publicly. Using the open ports interface, developers can assign a
sharing levels that match our `coder_app`’s share option in
[Coder terraform provider](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#share-1).

- `owner` (Default): The implicit sharing level for all listening ports, only
  visible to the workspace owner
- `authenticated`: Accessible by other authenticated Coder users on the same
  deployment.
- `public`: Accessible by any user with the associated URL.

Once a port is shared at either `authenticated` or `public` levels, it will stay
pinned in the open ports UI for better accessibility regardless of whether or
not it is still accessible.

![Annotated port controls in the UI](../../images/networking/annotatedports.png)

The sharing level is limited by the maximum level enforced in the template
settings in premium deployments, and not restricted in OSS deployments.

This can also be used to change the sharing level of `coder_app`s by entering
their port number in the sharable ports UI. The `share` attribute on `coder_app`
resource uses a different method of authentication and **is not impacted by the
template's maximum sharing level**, nor the level of a shared port that points
to the app.

### Configure maximum port sharing level

> [!NOTE]
> Configuring port sharing level is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Premium-licensed template admins can control the maximum port sharing level for
workspaces under a given template in the template settings. By default, the
maximum sharing level is set to `Owner`, meaning port sharing is disabled for
end-users. OSS deployments allow all workspaces to share ports at both the
`authenticated` and `public` levels.

![Max port sharing level in the UI](../../images/networking/portsharingmax.png)

### Configuring port protocol

Both listening and shared ports can be configured to use either `HTTP` or
`HTTPS` to connect to the port. For listening ports the protocol selector
applies to any port you input or select from the menu. Shared ports have
protocol configuration for each shared port individually.

You can access any port on the workspace and can configure the port protocol
manually by appending a `s` to the port in the URL.

```text
# Uses HTTP
https://33295--agent--workspace--user--apps.example.com/
# Uses HTTPS
https://33295s--agent--workspace--user--apps.example.com/
```

### Cross-origin resource sharing (CORS)

When forwarding via the dashboard, Coder automatically sets headers that allow
requests between separately forwarded applications belonging to the same user.

When forwarding through other methods the application itself will need to set
its own CORS headers if they are being forwarded through different origins since
Coder does not intercept these cases. See below for the required headers.

#### Authentication

Since ports forwarded through the dashboard are private, cross-origin requests
must include credentials (set `credentials: "include"` if using `fetch`) or the
requests cannot be authenticated and you will see an error resembling the
following:

```text
Access to fetch at
'<https://coder.example.com/api/v2/applications/auth-redirect>' from origin
'<https://8000--dev--user--apps.coder.example.com>' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's mode to
'no-cors' to fetch the resource with CORS disabled.
```

#### Headers

Below is a list of the cross-origin headers Coder sets with example values:

```text
access-control-allow-credentials: true
access-control-allow-methods: PUT
access-control-allow-headers: X-Custom-Header
access-control-allow-origin: https://8000--dev--user--apps.coder.example.com
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
```

The allowed origin will be set to the origin provided by the browser if the
users are identical. Credentials are allowed and the allowed methods and headers
will echo whatever the request sends.

#### Configuration

These cross-origin headers are not configurable by administrative settings.

If applications set any of the above headers they will be stripped from the
response except for `Vary` headers that are set to a value other than the ones
listed above.

In other words, CORS behavior through the dashboard is not currently
configurable by either admins or users.

#### Allowed by default

<table class="tg">
<thead>
  <tr>
    <th class="tg-0pky" rowspan="2"></th>
    <th class="tg-0pky" rowspan="3"></th>
    <th class="tg-0pky">From</th>
    <th class="tg-0pky" colspan="3">Alice</th>
    <th class="tg-0pky">Bob</th>
  </tr>
  <tr>
    <th class="tg-0pky" rowspan="2"></th>
    <th class="tg-0pky">Workspace 1</th>
    <th class="tg-0pky" colspan="2">Workspace 2</th>
    <th class="tg-0pky">Workspace 3</th>
  </tr>
  <tr>
    <th class="tg-0pky">To</th>
    <th class="tg-0pky">App A</th>
    <th class="tg-0pky">App B</th>
    <th class="tg-0pky">App C</th>
    <th class="tg-0pky">App D</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td class="tg-0pky" rowspan="3">Alice</td>
    <td class="tg-0pky" rowspan="2">Workspace 1</td>
    <td class="tg-0pky">App A</td>
    <td class="tg-0pky">✅</td>
    <td class="tg-0pky">✅<span style="font-weight:400;font-style:normal">*</span></td>
    <td class="tg-0pky">✅<span style="font-weight:400;font-style:normal">*</span></td>
    <td class="tg-0pky">❌</td>
  </tr>
  <tr>
    <td class="tg-0pky">App B</td>
    <td class="tg-0pky">✅*</td>
    <td class="tg-0pky">✅</td>
    <td class="tg-0pky">✅<span style="font-weight:400;font-style:normal">*</span></td>
    <td class="tg-0pky">❌</td>
  </tr>
  <tr>
    <td class="tg-0pky">Workspace 2</td>
    <td class="tg-0pky">App C</td>
    <td class="tg-0pky">✅<span style="font-weight:400;font-style:normal">*</span></td>
    <td class="tg-0pky">✅<span style="font-weight:400;font-style:normal">*</span></td>
    <td class="tg-0pky">✅</td>
    <td class="tg-0pky">❌</td>
  </tr>
  <tr>
    <td class="tg-0pky">Bob</td>
    <td class="tg-0pky">Workspace 3</td>
    <td class="tg-0pky">App D</td>
    <td class="tg-0pky">❌</td>
    <td class="tg-0pky">❌</td>
    <td class="tg-0pky">❌</td>
    <td class="tg-0pky">✅</td>
  </tr>
</tbody>
</table>

> '\*' means `credentials: "include"` is required

## SSH

First,
[configure SSH](../../user-guides/workspace-access/index.md#configure-ssh) on
your local machine. Then, use `ssh` to forward like so:

```console
ssh -L 8080:localhost:8000 coder.myworkspace
```

You can read more on SSH port forwarding
[here](https://www.ssh.com/academy/ssh/tunneling/example).

---

# STUN and NAT

Source: https://coder.com/docs/admin/networking/stun

# STUN and NAT

[Session Traversal Utilities for NAT (STUN)](https://www.rfc-editor.org/rfc/rfc8489.html)
is a protocol used to assist applications in establishing peer-to-peer
communications across Network Address Translations (NATs) or firewalls.

[Network Address Translation (NAT)](https://en.wikipedia.org/wiki/Network_address_translation)
is commonly used in private networks to allow multiple devices to share a
single public IP address. The vast majority of home and corporate internet
connections use at least one level of NAT.

## Overview

In order for one application to connect to another across a network, the
connecting application needs to know the IP address and port under which the
target application is reachable. If both applications reside on the same
network, then they can most likely connect directly to each other. In the
context of a Coder workspace agent and client, this is generally not the case,
as both agent and client will most likely be running in different _private_
networks (e.g. `192.168.1.0/24`). In this case, at least one of the two will
need to know an IP address and port under which they can reach their
counterpart.

This problem is often referred to as NAT traversal, and Coder uses a standard
protocol named STUN to address this.

Inside of that network, packets from the agent or client will show up as having
source address `192.168.1.X:12345`. However, outside of this private network,
the source address will show up differently (for example, `12.3.4.56:54321`). In
order for the Coder client and agent to establish a direct connection with each
other, one of them needs to know the `ip:port` pair under which their
counterpart can be reached. Once communication succeeds in one direction, we can
inspect the source address of the received packet to determine the return
address.

> [!TIP]
> The below glosses over a lot of the complexity of traversing NATs.
> For a more in-depth technical explanation, see
> [How NAT traversal works (tailscale.com)](https://tailscale.com/blog/how-nat-traversal-works).

At a high level, STUN works like this:

- **Discovery:** Both the client and agent will send UDP traffic to one or more
  configured STUN servers. These STUN servers are generally located on the
  public internet, and respond with the public IP address and port from which
  the request came.
- **Coordination:** The client and agent then exchange this information through
  the Coder server. They will then construct packets that should be able to
  successfully traverse their counterpart's NATs successfully.
- **NAT Traversal:** The client and agent then send these crafted packets to
  their counterpart's public addresses. If all goes well, the NATs on the other
  end should route these packets to the correct internal address.
- **Connection:** Once the packets reach the other side, they send a response
  back to the source `ip:port` from the packet. Again, the NATs should recognize
  these responses as belonging to an ongoing communication, and forward them
  accordingly.

At this point, both the client and agent should be able to send traffic directly
to each other.

## Examples

### 1. Direct connections without NAT or STUN

In this example, both the client and agent are located on the network
`192.168.21.0/24`. Assuming no firewalls are blocking packets in either
direction, both client and agent are able to communicate directly with each
other's locally assigned IP address.

![Diagram of a workspace agent and client in the same network](../../images/networking/stun1.png)

### 2. Direct connections with one layer of NAT

In this example, client and agent are located on different networks and connect
to each other over the public Internet. Both client and agent connect to a
configured STUN server located on the public Internet to determine the public IP
address and port on which they can be reached.

![Diagram of a workspace agent and client in separate networks](../../images/networking/stun2.1.png)

They then exchange this information through Coder server, and can then
communicate directly with each other through their respective NATs.

![Diagram of a workspace agent and client in separate networks](../../images/networking/stun2.2.png)

### 3. Direct connections with VPN and NAT hairpinning

In this example, the client workstation must use a VPN to connect to the
corporate network. All traffic from the client will enter through the VPN entry
node and exit at the VPN exit node inside the corporate network. Traffic from
the client inside the corporate network will appear to be coming from the IP
address of the VPN exit node `172.16.1.2`. Traffic from the client to the public
internet will appear to have the public IP address of the corporate router
`12.34.56.7`.

The workspace agent is running on a Kubernetes cluster inside the corporate
network, which is behind its own layer of NAT. To anyone inside the corporate
network but outside the cluster network, its traffic will appear to be coming
from `172.16.1.254`. However, traffic from the agent to services on the public
Internet will also see traffic originating from the public IP address assigned
to the corporate router. Additionally, the corporate router will most likely
have a firewall configured to block traffic from the internet to the corporate
network.

If the client and agent both use the public STUN server, the addresses
discovered by STUN will both be the public IP address of the corporate router.
To correctly route the traffic backwards, the corporate router must correctly
route both:

- Traffic sent from the client to the external IP of the corporate router back
  to the cluster router, and
- Traffic sent from the agent to the external IP of the corporate router to the
  VPN exit node.

This behaviour is known as "hairpinning", and may not be supported in all
network configurations.

If hairpinning is not supported, deploying an internal STUN server can aid
establishing direct connections between client and agent. When the agent and
client query this internal STUN server, they will be able to determine the
addresses on the corporate network from which their traffic appears to
originate. Using these internal addresses is much more likely to result in a
successful direct connection.

![Diagram of a workspace agent and client over VPN](../../images/networking/stun3.png)

## Hard NAT

Some NATs are known to use a different port when forwarding requests to the STUN
server and when forwarding probe packets to peers. In that case, the address a
peer discovers over the STUN protocol will have the correct IP address, but the
wrong port. Tailscale refers to this as "hard" NAT in
[How NAT traversal works (tailscale.com)](https://tailscale.com/blog/how-nat-traversal-works).

If both peers are behind a "hard" NAT, direct connections may take longer to
establish or will not be established at all. If one peer is behind a "hard" NAT
and the other is running a firewall (including Windows Defender Firewall), the
firewall may block direct connections.

In both cases, peers fallback to DERP connections if they cannot establish a
direct connection.

If your workspaces are behind a "hard" NAT, you can:

1. Ensure clients are not also behind a "hard" NAT. You may have limited ability
   to control this if end users connect from their homes.
2. Ensure firewalls on client devices (e.g. Windows Defender Firewall) have an
   inbound policy allowing all UDP ports either to the `coder` or `coder.exe`
   CLI binary, or from the IP addresses of your workspace NATs.
3. Reconfigure your workspace network's NAT connection to the public internet to
   be an "easy" NAT. See below for specific examples.

### AWS NAT Gateway

The
[AWS NAT Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)
is a known "hard" NAT. You can use a
[NAT Instance](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_NAT_Instance.html)
instead of a NAT Gateway, and configure it to use the same port assignment for
all UDP traffic from a particular source IP:port combination (Tailscale calls
this "easy" NAT). Linux `MASQUERADE` rules work well for this.

### AWS Elastic Kubernetes Service (EKS)

The default configuration of AWS Elastic Kubernetes Service (EKS) includes the
[Amazon VPC CNI Driver](https://github.com/aws/amazon-vpc-cni-k8s), which by
default randomizes the public port for different outgoing UDP connections. This
makes it act as a "hard" NAT, even if the EKS nodes are on a public subnet (and
thus do not need to use the AWS NAT Gateway to reach the Internet).

This behavior can be disabled by setting the environment variable
`AWS_VPC_K8S_CNI_RANDOMIZESNAT=none` in the `aws-node` DaemonSet. Note, however,
if your nodes are on a private subnet, they will still need NAT to reach the
public Internet, meaning that issues with the
[AWS NAT Gateway](#aws-nat-gateway) might affect you.

---

# Workspace Proxies

Source: https://coder.com/docs/admin/networking/workspace-proxies

# Workspace Proxies

Workspace proxies provide low-latency experiences for geo-distributed teams.

Coder's networking does a best effort to make direct connections to a workspace.
In situations where this is not possible, such as connections via the web
terminal and
[web IDEs](../../user-guides/workspace-access/index.md#other-web-ides),
workspace proxies are able to reduce the amount of distance the network traffic
needs to travel.

A workspace proxy is a relay connection a developer can choose to use when
connecting with their workspace over SSH, a workspace app, port forwarding, etc.
Dashboard connections and API calls (e.g. the workspaces list) are not served
over workspace proxies.

## Deploy a workspace proxy

Each workspace proxy should be a unique instance. At no point should two
workspace proxy instances share the same authentication token. They only require
port 443 to be open and are expected to have network connectivity to the coderd
dashboard. Workspace proxies **do not** make any database connections.

Workspace proxies can be used in the browser by navigating to the user
`Account -> Workspace Proxy`

## Requirements

- The [Coder CLI](../../reference/cli/index.md) must be installed and
  authenticated as a user with the Owner role.

## Step 1: Create the proxy

Create the workspace proxy and make sure to save the returned authentication
token for said proxy. This is the token the workspace proxy will use to
authenticate back to primary coderd.

```bash
$ coder wsproxy create --name=newyork --display-name="USA East" --icon="/emojis/2194.png"
Workspace Proxy "newyork" created successfully. Save this token, it will not be shown again.
Token: 2fb6500b-bb47-4783-a0db-dedde895b865:05271b4ef9432bac14c02b3c56b5a2d7f05453718a1f85ba7e772c0a096c7175
```

To verify it was created.

```bash
$ coder wsproxy ls
NAME         URL                    STATUS STATUS
newyork                             unregistered
```

## Step 2: Deploy the proxy

Deploying the workspace proxy will also register the proxy with coderd and make
the workspace proxy usable. If the proxy deployment is successful,
`coder wsproxy ls` will show an `ok` status code:

```shell
$ coder wsproxy ls
NAME              URL                         STATUS STATUS
primary           https://dev.coder.com        ok
brazil-saopaulo   https://brazil.example.com   ok
europe-frankfurt  https://europe.example.com   ok
sydney            https://sydney.example.com   ok
```

Other Status codes:

- `unregistered` : The workspace proxy was created, and not yet deployed
- `unreachable` : The workspace proxy was registered, but is not responding.
  Likely the proxy went offline.
- `unhealthy` : The workspace proxy is reachable, but has some issue that is
  preventing the proxy from being used. `coder wsproxy ls` should show the error
  message.
- `ok` : The workspace proxy is healthy and working properly!

### Configuration

Workspace proxy configuration overlaps with a subset of the coderd
configuration. To see the full list of configuration options:
`coder wsproxy server --help`

```bash
# Proxy specific configuration. These are REQUIRED
# Example: https://coderd.example.com
CODER_PRIMARY_ACCESS_URL="https://<url_of_coderd_dashboard>"
CODER_PROXY_SESSION_TOKEN="<session_token_from_proxy_create>"

# Runtime variables for "coder start".
CODER_HTTP_ADDRESS=0.0.0.0:80
CODER_TLS_ADDRESS=0.0.0.0:443
# Example: https://east.coderd.example.com
CODER_ACCESS_URL="https://<access_url_of_proxy>"
# Example: *.east.coderd.example.com
CODER_WILDCARD_ACCESS_URL="*.<app_hostname_of_proxy>"

CODER_TLS_ENABLE=true
CODER_TLS_CLIENT_AUTH=none
CODER_TLS_CERT_FILE="<cert_file_location>"
CODER_TLS_KEY_FILE="<key_file_location>"

# Additional configuration options are available.
```

### Running on Kubernetes

Make a `values-wsproxy.yaml` with the workspace proxy configuration.

Notice the `workspaceProxy` configuration which is `false` by default in the
Coder Helm chart:

```yaml
coder:
  env:
    - name: CODER_PRIMARY_ACCESS_URL
      value: "https://<url_of_coderd_dashboard>"
    - name: CODER_PROXY_SESSION_TOKEN
      value: "<session_token_from_proxy_create>"
    # Example: https://east.coderd.example.com
    - name: CODER_ACCESS_URL
      value: "https://<access_url_of_proxy>"
    # Example: *.east.coderd.example.com
    - name: CODER_WILDCARD_ACCESS_URL
      value: "*.<app_hostname_of_proxy>"

  tls:
    secretNames:
      - kubernetes-wsproxy-secret

  # enable workspace proxy
  workspaceProxy: true
```

Using Helm, install the workspace proxy chart

```bash
helm install coder coder-v2/coder --namespace <your workspace proxy namespace> -f ./values-wsproxy.yaml
```

Test that the workspace proxy is reachable with `curl -vvv`. If for some reason,
the Coder dashboard still shows the workspace proxy is `UNHEALTHY`, scale down
and up the deployment's replicas.

### Running on a VM

```bash
# Set configuration options via environment variables, a config file, or cmd flags
coder wsproxy server
```

### Running as a system service

If you've installed Coder via a [system package](../../install/index.md), you
can configure the workspace proxy by settings in
`/etc/coder.d/coder-workspace-proxy.env`

To run workspace proxy as a system service on the host:

```bash
# Use systemd to start workspace proxy now and on reboot
sudo systemctl enable --now coder-workspace-proxy

# View the logs to ensure a successful start
journalctl -u coder-workspace-proxy.service -b
```

To restart workspace proxy after applying system changes:

```shell
sudo systemctl restart coder-workspace-proxy
```

### Running in Docker

Modify the default entrypoint to run a workspace proxy server instead of a
regular Coder server.

#### Docker Compose

Change the provided
[`compose.yml`](https://github.com/coder/coder/blob/main/compose.yaml)
file to include a custom entrypoint:

```diff
  image: ghcr.io/coder/coder:${CODER_VERSION:-latest}
+ entrypoint: /opt/coder wsproxy server
```

#### Docker run

```bash
docker run --rm -it --entrypoint /opt/coder ghcr.io/coder/coder:latest wsproxy server
```

#### Custom Dockerfile

```Dockerfile
FROM ghcr.io/coder/coder:latest
ENTRYPOINT ["/opt/coder", "wsproxy", "server"]
```

### Selecting a proxy

Users can select a workspace proxy at the top-right of the browser-based Coder
dashboard. Workspace proxy preferences are cached by the web browser. If a proxy
goes offline, the session will fall back to the primary proxy. This could take
up to 60 seconds.

![Workspace proxy picker](../../images/admin/networking/workspace-proxies/ws-proxy-picker.png)

## Multiple workspace proxies

When multiple workspace proxies are deployed:

- The browser measures latency to each available proxy independently.
- Users can select their preferred proxy from the dashboard.
- The system can automatically select the lowest-latency proxy.
- The dashboard latency indicator shows latency to the currently selected proxy.

## Observability

Coder workspace proxy exports metrics via the HTTP endpoint, which can be
enabled using either the environment variable `CODER_PROMETHEUS_ENABLE` or the
flag `--prometheus-enable`.

The Prometheus endpoint address is `http://localhost:2112/` by default. You can
use either the environment variable `CODER_PROMETHEUS_ADDRESS` or the flag
`--prometheus-address <network-interface>:<port>` to select a different listen
address.

---

# High Availability

Source: https://coder.com/docs/admin/networking/high-availability

# High Availability

High Availability (HA) mode solves for horizontal scalability and automatic
failover within a single region. When in HA mode, Coder continues using a single
Postgres endpoint.
[GCP](https://cloud.google.com/sql/docs/postgres/high-availability),
[AWS](https://docs.aws.amazon.com/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/availability.html),
and other cloud vendors offer fully-managed HA Postgres services that pair
nicely with Coder.

For Coder to operate correctly, Coderd instances should have low-latency
connections to each other so that they can effectively relay traffic between
users and workspaces no matter which Coderd instance users or workspaces connect
to. We make a best-effort attempt to warn the user when inter-Coderd latency is
too high, but if requests start dropping, this is one metric to investigate.

We also recommend that you deploy all Coderd instances such that they have
low-latency connections to Postgres. Coderd often makes several database
round-trips while processing a single API request, so prioritizing low-latency
between Coderd and Postgres is more important than low-latency between users and
Coderd.

Note that this latency requirement applies _only_ to Coder services. Coder will
operate correctly even with few seconds of latency on workspace <-> Coder and
user <-> Coder connections.

## Setup

Coder automatically enters HA mode when multiple instances simultaneously
connect to the same Postgres endpoint.

> [!NOTE]
> When upgrading HA deployments, database migrations may require special
> handling to avoid lock contention. See
> [Upgrading Best Practices](../../install/upgrade-best-practices.md) for
> recommended procedures.

HA brings one configuration variable to set in each Coderd node:
`CODER_DERP_SERVER_RELAY_URL`. The HA nodes use these URLs to communicate with
each other. Inter-node communication is only required while using the embedded
relay (default). If you're using [custom relays](./index.md#custom-relays),
Coder ignores `CODER_DERP_SERVER_RELAY_URL` since Postgres is the sole
rendezvous for the Coder nodes.

`CODER_DERP_SERVER_RELAY_URL` will never be `CODER_ACCESS_URL` because
`CODER_ACCESS_URL` is a load balancer to all Coder nodes.

Here's an example 3-node network configuration setup:

| Name      | `CODER_HTTP_ADDRESS` | `CODER_DERP_SERVER_RELAY_URL` | `CODER_ACCESS_URL`       |
|-----------|----------------------|-------------------------------|--------------------------|
| `coder-1` | `*:80`               | `http://10.0.0.1:80`          | `https://coder.big.corp` |
| `coder-2` | `*:80`               | `http://10.0.0.2:80`          | `https://coder.big.corp` |
| `coder-3` | `*:80`               | `http://10.0.0.3:80`          | `https://coder.big.corp` |

## Kubernetes

If you installed Coder via
[our Helm Chart](../../install/kubernetes.md#4-install-coder-with-helm), just
increase `coder.replicaCount` in `values.yaml`.

If you installed Coder into Kubernetes by some other means, insert the relay URL
via the environment like so:

```yaml
env:
  - name: POD_IP
    valueFrom:
      fieldRef:
        fieldPath: status.podIP
  - name: CODER_DERP_SERVER_RELAY_URL
    value: http://$(POD_IP)
```

Then, increase the number of pods.

## Up next

- [Read more on Coder's networking stack](./index.md)
- [Install on Kubernetes](../../install/kubernetes.md)

---

# Wildcard Access URL

Source: https://coder.com/docs/admin/networking/wildcard-access-url

# Wildcard Access URLs

Wildcard access URLs unlock Coder's full potential for modern development workflows. While optional for basic SSH usage, this feature becomes essential when teams need web applications, development previews, or browser-based tools. **Wildcard access URLs are essential for many development workflows in Coder** - Web IDEs (code-server, VS Code Web, JupyterLab) and some development frameworks work significantly better with subdomain-based access rather than path-based URLs.

## Why configure wildcard access URLs?

### Key benefits

- **Enables port access**: Each application gets a unique subdomain with [port support](https://coder.com/docs/user-guides/workspace-access/port-forwarding#dashboard) (e.g. `8080--main--myworkspace--john.coder.example.com`).
- **Enhanced security**: Applications run in isolated subdomains with separate browser security contexts and prevents access to the Coder API from malicious JavaScript
- **Better compatibility**: Most applications are designed to work at the root of a hostname rather than at a subpath, making subdomain access more reliable

### Applications that require subdomain access

The following tools require wildcard access URL:

- **Vite dev server**: Hot module replacement and asset serving issues with path-based routing
- **React dev server**: Similar issues with hot reloading and absolute path references
- **Next.js development server**: Asset serving and routing conflicts with path-based access
- **JupyterLab**: More complex template configuration and security risks when using path-based routing
- **RStudio**: More complex template configuration and security risks when using path-based routing

## Configuration

`CODER_WILDCARD_ACCESS_URL` is necessary for [port forwarding](port-forwarding.md#dashboard) via the dashboard or running [coder_apps](../templates/index.md) on an absolute path. Set this to a wildcard subdomain that resolves to Coder (e.g. `*.coder.example.com`).

```bash
export CODER_WILDCARD_ACCESS_URL="*.coder.example.com"
coder server
```

### TLS Certificate Setup

Wildcard access URLs require a TLS certificate that covers the wildcard domain. You have several options:

> [!TIP]
> You can use a single certificate for both the access URL and wildcard access URL. The certificate CN or SANs must match the wildcard domain, such as `*.coder.example.com`.

#### Direct TLS Configuration

Configure Coder to handle TLS directly using the wildcard certificate:

```bash
export CODER_TLS_ENABLE=true
export CODER_TLS_CERT_FILE=/path/to/wildcard.crt
export CODER_TLS_KEY_FILE=/path/to/wildcard.key
```

See [TLS & Reverse Proxy](../setup/index.md#tls--reverse-proxy) for detailed configuration options.

#### Reverse Proxy with Let's Encrypt

Use a reverse proxy to handle TLS termination with automatic certificate management:

- [NGINX with Let's Encrypt](../../tutorials/reverse-proxy-nginx.md)
- [Apache with Let's Encrypt](../../tutorials/reverse-proxy-apache.md)
- [Caddy reverse proxy](../../tutorials/reverse-proxy-caddy.md)

### DNS Setup

You'll need to configure DNS to point wildcard subdomains to your Coder server:

> [!NOTE]
> We do not recommend using a top-level-domain for Coder wildcard access
> (for example `*.workspaces`), even on private networks with split-DNS. Some
> browsers consider these "public" domains and will refuse Coder's cookies,
> which are vital to the proper operation of this feature.

```text
*.coder.example.com    A    <your-coder-server-ip>
```

Or alternatively, using a CNAME record:

```text
*.coder.example.com    CNAME    coder.example.com
```

### Workspace Proxies

If you're using [workspace proxies](workspace-proxies.md) for geo-distributed teams, each proxy requires its own wildcard access URL configuration:

```bash
# Main Coder server
export CODER_WILDCARD_ACCESS_URL="*.coder.example.com"

# Sydney workspace proxy
export CODER_WILDCARD_ACCESS_URL="*.sydney.coder.example.com"

# London workspace proxy
export CODER_WILDCARD_ACCESS_URL="*.london.coder.example.com"
```

Each proxy's wildcard domain must have corresponding DNS records:

```text
*.sydney.coder.example.com    A    <sydney-proxy-ip>
*.london.coder.example.com    A    <london-proxy-ip>
```

## Template Configuration

In your Coder templates, enable subdomain applications using the `subdomain` parameter:

```hcl
resource "coder_app" "code-server" {
  agent_id     = coder_agent.main.id
  slug         = "code-server"
  display_name = "VS Code"
  url          = "http://localhost:8080"
  icon         = "/icon/code.svg"
  subdomain    = true
  share        = "owner"
}
```

## Troubleshooting

### Applications not accessible

If workspace applications are not working:

1. Verify the `CODER_WILDCARD_ACCESS_URL` environment variable is configured correctly:
   - Check the deployment settings in the Coder dashboard (Settings > Deployment)
   - Ensure it matches your wildcard domain (e.g., `*.coder.example.com`)
   - Restart the Coder server if you made changes to the environment variable
2. Check DNS resolution for wildcard subdomains:

   ```bash
   dig test.coder.example.com
   nslookup test.coder.example.com
   ```

3. Ensure TLS certificates cover the wildcard domain
4. Confirm template `coder_app` resources have `subdomain = true`

## See also

- [Workspace Proxies](workspace-proxies.md) - Improve performance for geo-distributed teams using wildcard URLs

---

# Troubleshooting

Source: https://coder.com/docs/admin/networking/troubleshooting

# Troubleshooting

`coder ping <workspace>` will ping the workspace agent and print diagnostics on
the state of the connection. These diagnostics are created by inspecting both
the client and agent network configurations, and provide insights into why a
direct connection may be impeded, or why the quality of one might be degraded.

The `-v/--verbose` flag can be appended to the command to print client debug
logs.

```console
$ coder ping dev
pong from workspace proxied via  DERP(Council Bluffs, Iowa)  in 42ms
pong from workspace proxied via  DERP(Council Bluffs, Iowa)  in 41ms
pong from workspace proxied via  DERP(Council Bluffs, Iowa)  in 39ms
✔ preferred DERP region: 999 (Council Bluffs, Iowa)
✔ sent local data to Coder networking coordinator
✔ received remote agent data from Coder networking coordinator
    preferred DERP region: 999 (Council Bluffs, Iowa)
    endpoints: x.x.x.x:46433, x.x.x.x:46433, x.x.x.x:46433
✔ Wireguard handshake 11s ago

❗ You are connected via a DERP relay, not directly (p2p)
Possible client-side issues with direct connection:
 - Network interface utun0 has MTU 1280, (less than 1378), which may degrade the quality of direct connections

Possible agent-side issues with direct connection:
 - Agent is potentially behind a hard NAT, as multiple endpoints were retrieved from different STUN servers
 - Agent IP address is within an AWS range (AWS uses hard NAT)
```

## Common Problems with Direct Connections

### Disabled Deployment-wide

Direct connections can be disabled at the deployment level by setting the
`CODER_BLOCK_DIRECT` environment variable or the `--block-direct-connections`
flag on the server. When set, this will be reflected in the output of
`coder ping`.

### UDP Blocked

Some corporate firewalls block UDP traffic. Direct connections require UDP
traffic to be allowed between the client and agent, as well as between the
client/agent and STUN servers in most cases. `coder ping` will indicate if
either the Coder agent or client had issues sending or receiving UDP packets to
STUN servers.

If this is the case, you may need to add exceptions to the firewall to allow UDP
for Coder workspaces, clients, and STUN servers.

### Endpoint-Dependent NAT (Hard NAT)

Hard NATs prevent public endpoints gathered from STUN servers from being used by
the peer to establish a direct connection. Typically, if only one side of the
connection is behind a hard NAT, direct connections can still be established
easily. However, if both sides are behind hard NATs, direct connections may take
longer to establish or may not be possible at all.

`coder ping` will indicate if it's possible the client or agent is behind a hard
NAT.

Learn more about [STUN and NAT](./stun.md).

### No STUN Servers

If there are no STUN servers available within a deployment's DERP MAP, direct
connections may not be possible. Notable exceptions are if the client and agent
are on the same network, or if either is able to use UPnP instead of STUN to
resolve the public IP of the other. `coder ping` will indicate if no STUN
servers were found.

### Endpoint Firewalls

Direct connections may also be impeded if one side is behind a hard NAT and the
other is running a firewall that blocks ingress traffic from unknown 5-tuples
(Protocol, Source IP, Source Port, Destination IP, Destination Port).

If this is suspected, you may need to add an exception for Coder to the
firewall, or reconfigure the hard NAT.

### VPNs

If a VPN is the default route for all IP traffic, it may interfere with the
ability for clients and agents to form direct connections. This happens if the
NAT does not permit traffic to be
['hairpinned'](./stun.md#3-direct-connections-with-vpn-and-nat-hairpinning) from
the public IP address of the NAT (determined via STUN) to the internal IP
address of the agent.

If this is the case, you may need to add exceptions to the VPN for Coder, modify
the NAT configuration, or deploy an internal STUN server.

### Low MTU

If a network interface on the side of either the client or agent has an MTU
smaller than 1378, any direct connections form may have degraded quality or
might hang entirely.

Use `coder ping` to check for MTU issues, as it inspects
network interfaces on both the client and the workspace agent:

```console
$ coder ping my-workspace
...
Possible client-side issues with direct connection:

 - Network interface utun0 has MTU 1280 (less than 1378), which may degrade the quality of direct connections or render them unusable.
```

If another interface cannot be used, and the MTU cannot be changed, you should
disable direct connections and relay all traffic via DERP instead, which
will not be affected by the low MTU.

To disable direct connections, set the
[`--block-direct-connections`](../../reference/cli/server.md#--block-direct-connections)
flag or `CODER_BLOCK_DIRECT` environment variable on the Coder server.

## Throughput

The `coder speedtest <workspace>` command measures the throughput between the
client and the workspace agent.

```console
$ coder speedtest workspace
29ms via coder
Starting a 5s download test...
INTERVAL       TRANSFER         BANDWIDTH
0.00-1.00 sec  630.7840 MBits   630.7404 Mbits/sec
1.00-2.00 sec  913.9200 MBits   913.8106 Mbits/sec
2.00-3.00 sec  943.1040 MBits   943.0399 Mbits/sec
3.00-4.00 sec  933.3760 MBits   933.2143 Mbits/sec
4.00-5.00 sec  848.8960 MBits   848.7019 Mbits/sec
5.00-5.02 sec  13.5680 MBits    828.8189 Mbits/sec
----------------------------------------------------
0.00-5.02 sec  4283.6480 MBits  853.8217 Mbits/sec
```

---

# Monitoring

Source: https://coder.com/docs/admin/monitoring

# Monitoring Coder

Learn about our the tools, techniques, and best practices to monitor your Coder
deployment.

## Quick Start: Observability Helm Chart

Deploy Prometheus, Grafana, Alert Manager, and pre-built dashboards on your
Kubernetes cluster to monitor the Coder control plane, provisioners, and
workspaces.

![Grafana Dashboard](../../images/admin/monitoring/grafana-dashboard.png)

Learn how to install & read the docs on the
[Observability Helm Chart GitHub](https://github.com/coder/observability)

## Table of Contents

- [Logs](./logs.md): Learn how to access to Coder server logs, agent logs, and
  even how to expose Kubernetes pod scheduling logs.
- [Metrics](./metrics.md): Learn about the valuable metrics to measure on a
  Coder deployment, regardless of your monitoring stack.
- [Health Check](./health-check.md): Learn about the periodic health check and
  error codes that run on Coder deployments.
- [Connection Logs](./connection-logs.md): Monitor connections to workspaces.

---

# Logs

Source: https://coder.com/docs/admin/monitoring/logs

# Logs

All Coder services log to standard output, which can be critical for identifying
errors and monitoring Coder's deployment health. Like any service, logs can be
captured via Splunk, Datadog, Grafana Loki, or other ingestion tools.

## `coderd` Logs

By default, the Coder server exports human-readable logs to standard output. You
can access these logs via `kubectl logs deployment/coder -n <coder-namespace>`
on Kubernetes or `journalctl -u coder` if you deployed Coder on a host
machine/VM.

- To change the log format/location, you can set
  [`CODER_LOGGING_HUMAN`](../../reference/cli/server.md#--log-human) and
  [`CODER_LOGGING_JSON`](../../reference/cli/server.md#--log-json) server config.
  options.
- To only display certain types of logs, use
  the[`CODER_LOG_FILTER`](../../reference/cli/server.md#-l---log-filter) server
  config. Using `.*` will result in the `DEBUG` log level being used.

Events such as server errors, audit logs, user activities, and SSO & OpenID
Connect logs are all captured in the `coderd` logs.

## `provisionerd` Logs

Logs for [external provisioners](../provisioners/index.md) are structured
[and configured](../../reference/cli/provisioner_start.md#--log-human) similarly
to `coderd` logs. Use these logs to troubleshoot and monitor the Terraform
operations behind workspaces and templates.

## Workspace Logs

The [Coder agent](../infrastructure/architecture.md#agents) inside workspaces
provides useful logs around workspace-to-server and client-to-workspace
connections. For Kubernetes workspaces, these are typically the pod logs as the
agent runs via the container entrypoint.

Agent logs are also stored in the workspace filesystem by default:

- macOS/Linux: `/tmp/coder-agent.log`
- Windows: Refer to the template code (e.g.
  [azure-windows](https://github.com/coder/coder/blob/2cfadad023cb7f4f85710cff0b21ac46bdb5a845/examples/templates/azure-windows/Initialize.ps1.tftpl#L64))
  to see where logs are stored.

> [!NOTE]
> Logs are truncated once they reach 5MB in size.

Startup script logs are also stored in the temporary directory of macOS and
Linux workspaces.

## Kubernetes Event Logs

Sometimes, a workspace may take a while to start or even fail to start due to
underlying events on the Kubernetes cluster such as a node being out of
resources or a missing image. You can install
[coder-logstream-kube](../integrations/kubernetes-logs.md) to stream Kubernetes
events to the Coder UI.

![Kubernetes logs in Coder dashboard](../../images/admin/monitoring/logstream-kube.png)

---

# Metrics

Source: https://coder.com/docs/admin/monitoring/metrics

# Deployment Metrics

Coder exposes many metrics which give insight into the current state of a live
Coder deployment. Our metrics are designed to be consumed by a
[Prometheus server](https://prometheus.io/).

If you don't have an Prometheus server installed, you can follow the Prometheus
[Getting started](https://prometheus.io/docs/prometheus/latest/getting_started/)
guide.

## Setting up metrics

To set up metrics monitoring, please read our
[Prometheus integration guide](../integrations/prometheus.md). The following
links point to relevant sections there.

- [Enable Prometheus metrics](../integrations/prometheus.md#enable-prometheus-metrics)
  in the control plane
- [Enable the Prometheus endpoint in Helm](../integrations/prometheus.md#kubernetes-deployment)
  (Kubernetes users only)
- [Configure Prometheus to scrape Coder metrics](../integrations/prometheus.md#prometheus-configuration)
- [See the list of available metrics](../integrations/prometheus.md#available-metrics)

---

# Health Check

Source: https://coder.com/docs/admin/monitoring/health-check

# Deployment Health

Coder includes an operator-friendly deployment health page that provides a
number of details about the health of your Coder deployment.

![Health check in Coder Dashboard](../../images/admin/monitoring/health-check.png)

You can view it at `https://${CODER_URL}/health`, or you can alternatively view
the
[JSON response directly](../../reference/api/debug.md#debug-info-deployment-health).

The deployment health page is broken up into the following sections:

## Access URL

The Access URL section shows checks related to Coder's
[access URL](../setup/index.md#access-url).

Coder will periodically send a GET request to `${CODER_ACCESS_URL}/healthz` and
validate that the response is `200 OK`. The expected response body is also the
string `OK`.

If there is an issue, you may see one of the following errors reported:

### EACS01

### Access URL not set

**Problem:** no access URL has been configured.

**Solution:** configure an [access URL](../setup/index.md#access-url) for Coder.

### EACS02

#### Access URL invalid

**Problem:** `${CODER_ACCESS_URL}/healthz` is not a valid URL.

**Solution:** Ensure that the access URL is a valid URL accepted by
[`url.Parse`](https://pkg.go.dev/net/url#Parse). Example:
`https://dev.coder.com/`.

You can use [the Go playground](https://go.dev/play/p/CabcJZyTwt9) for additional testing.

### EACS03

#### Failed to fetch `/healthz`

**Problem:** Coder was unable to execute a GET request to
`${CODER_ACCESS_URL}/healthz`.

This could be due to a number of reasons, including but not limited to:

- DNS lookup failure
- A misconfigured firewall
- A misconfigured reverse proxy
- Invalid or expired SSL certificates

**Solution:** Investigate and resolve the root cause of the connection issue.

To troubleshoot further, you can log into the machine running Coder and attempt
to run the following command:

```shell
curl -v ${CODER_ACCESS_URL}/healthz
# Expected output:
# *   Trying XXX.XXX.XXX.XXX:443
# * Connected to https://coder.company.com (XXX.XXX.XXX.XXX) port 443 (#0)
# [...]
# OK
```

The output of this command should aid further diagnosis.

### EACS04

#### /healthz did not return 200 OK

**Problem:** Coder was able to execute a GET request to
`${CODER_ACCESS_URL}/healthz`, but the response code was not `200 OK` as
expected.

This could mean, for instance, that:

- The request did not actually hit your Coder instance (potentially an incorrect
  DNS entry)
- The request hit your Coder instance, but on an unexpected path (potentially a
  misconfigured reverse proxy)

**Solution:** Inspect the `HealthzResponse` in the health check output. This
should give you a good indication of the root cause.

## Database

Coder continuously executes a short database query to validate that it can reach
its configured database, and also measures the median latency over 5 attempts.

### EDB01

#### Database Ping Failed

**Problem:** This error code is returned if any attempt to execute this database
query fails.

**Solution:** Investigate the health of the database.

### EDB02

#### Database Latency High

**Problem:** This code is returned if the median latency is higher than the
[configured threshold](../../reference/cli/server.md#--health-check-threshold-database).
This may not be an error as such, but is an indication of a potential issue.

**Solution:** Investigate the sizing of the configured database with regard to
Coder's current activity and usage. It may be necessary to increase the
resources allocated to Coder's database. Alternatively, you can raise the
configured threshold to a higher value (this will not address the root cause).

> [!TIP]
> You can enable
> [detailed database metrics](../../reference/cli/server.md#--prometheus-collect-db-metrics)
> in Coder's Prometheus endpoint. If you have
> [tracing enabled](../../reference/cli/server.md#--trace), these traces may also
> contain useful information regarding Coder's database activity.

## DERP

Coder workspace agents may use
[DERP (Designated Encrypted Relay for Packets)](https://tailscale.com/blog/how-tailscale-works/#encrypted-tcp-relays-derp)
to communicate with Coder. This requires connectivity to a number of configured
[DERP servers](../../reference/cli/server.md#--derp-config-path) which are used
to relay traffic between Coder and workspace agents. Coder periodically queries
the health of its configured DERP servers and may return one or more of the
following:

### EDERP01

#### DERP Node Uses Websocket

**Problem:** When Coder attempts to establish a connection to one or more DERP
servers, it sends a specific `Upgrade: derp` HTTP header. Some load balancers
may block this header, in which case Coder will fall back to
`Upgrade: websocket`.

This is not necessarily a fatal error, but a possible indication of a
misconfigured reverse HTTP proxy. Additionally, while workspace users should
still be able to reach their workspaces, connection performance may be degraded.

> [!NOTE]
> This may also be shown if you have
> [forced websocket connections for DERP](../../reference/cli/server.md#--derp-force-websockets).

**Solution:** ensure that any proxies you use allow connection upgrade with the
`Upgrade: derp` header.

### EDERP02

#### One or more DERP nodes are unhealthy

**Problem:** This is shown if Coder is unable to reach one or more configured
DERP servers. Clients will fall back to use the remaining DERP servers, but
performance may be impacted for clients closest to the unhealthy DERP server.

**Solution:** Ensure that the DERP server is available and reachable over the
network, for example:

```shell
curl -v "https://coder.company.com/derp"
# Expected output:
# *   Trying XXX.XXX.XXX.XXX
# * Connected to https://coder.company.com (XXX.XXX.XXX.XXX) port 443 (#0)
# DERP requires connection upgrade
```

### EDERP03

#### No DERP servers available

**Problem:** This is shown when Coder's effective DERP map does not contain
any DERP servers. Without at least one working DERP server, workspace
networking may not work.

This can happen if the built-in DERP server is disabled and no external DERP
map is configured, or if workspace proxies are expected to provide DERP but no
healthy DERP-enabled proxy is currently available.

**Solution:** Ensure that at least one DERP server is available to the
deployment. For example:

- Restart `coderd` with the built-in DERP server enabled
- Restart `coderd` with an external DERP map configured
- Make sure a workspace proxy with DERP server enabled is running and healthy

### ESTUN01

#### No STUN servers available

**Problem:** This is shown if no STUN servers are available. Coder will use STUN
to establish [direct connections](../networking/stun.md). Without at least one
working STUN server, direct connections may not be possible.

**Solution:** Ensure that the
[configured STUN severs](../../reference/cli/server.md#--derp-server-stun-addresses)
are reachable from Coder and that UDP traffic can be sent/received on the
configured port.

### ESTUN02

#### STUN returned different addresses; you may be behind a hard NAT

**Problem:** This is a warning shown when multiple attempts to determine our
public IP address/port via STUN resulted in different `ip:port` combinations.
This is a sign that you are behind a "hard NAT", and may result in difficulty
establishing direct connections. However, it does not mean that direct
connections are impossible.

**Solution:** Engage with your network administrator.

## Websocket

Coder makes heavy use of [WebSockets](https://datatracker.ietf.org/doc/rfc6455/)
for long-lived connections:

- Between users interacting with Coder's Web UI (for example, the built-in
  terminal, or VSCode Web),
- Between workspace agents and `coderd`,
- Between Coder [workspace proxies](../networking/workspace-proxies.md) and
  `coderd`.

Any issues causing failures to establish WebSocket connections will result in
**severe** impairment of functionality for users. To validate this
functionality, Coder will periodically attempt to establish a WebSocket
connection with itself using the configured [Access URL](#access-url), send a
message over the connection, and attempt to read back that same message.

### EWS01

#### Failed to establish a WebSocket connection

**Problem:** Coder was unable to establish a WebSocket connection over its own
Access URL.

**Solution:** There are multiple possible causes of this problem:

1. Ensure that Coder's configured Access URL can be reached from the server
   running Coder, using standard troubleshooting tools like `curl`:

   ```shell
   curl -v "https://coder.company.com"
   ```

2. Ensure that any reverse proxy that is serving Coder's configured access URL
   allows connection upgrade with the header `Upgrade: websocket`.

### EWS02

#### Failed to echo a WebSocket message

**Problem:** Coder was able to establish a WebSocket connection, but was unable
to write a message.

**Solution:** There are multiple possible causes of this problem:

1. Validate that any reverse proxy servers in front of Coder's configured access
   URL are not prematurely closing the connection.
2. Validate that the network link between Coder and the workspace proxy is
   stable, e.g. by using `ping`.
3. Validate that any internal network infrastructure (for example, firewalls,
   proxies, VPNs) do not interfere with WebSocket connections.

## Workspace Proxy

If you have configured [Workspace Proxies](../networking/workspace-proxies.md),
Coder will periodically query their availability and show their status here.

### EWP01

#### Error Updating Workspace Proxy Health

**Problem:** Coder was unable to query the connected workspace proxies for their
health status.

**Solution:** This may be a transient issue. If it persists, it could signify a
connectivity issue.

### EWP02

#### Error Fetching Workspace Proxies

**Problem:** Coder was unable to fetch the stored workspace proxy health data
from the database.

**Solution:** This may be a transient issue. If it persists, it could signify an
issue with Coder's configured database.

### EWP04

#### One or more Workspace Proxies Unhealthy

**Problem:** One or more workspace proxies are not reachable.

**Solution:** Ensure that Coder can establish a connection to the configured
workspace proxies.

### EPD01

#### No Provisioner Daemons Available

**Problem:** No provisioner daemons are registered with Coder. No workspaces can
be built until there is at least one provisioner daemon running.

**Solution:**

If you are using
[External Provisioner Daemons](../provisioners/index.md#external-provisioners), ensure
that they are able to successfully connect to Coder. Otherwise, ensure
[`--provisioner-daemons`](../../reference/cli/server.md#--provisioner-daemons)
is set to a value greater than 0.

> [!NOTE]
> This may be a transient issue if you are currently in the process of updating your deployment.

### EPD02

#### Provisioner Daemon Version Mismatch

**Problem:** One or more provisioner daemons are more than one major or minor
version out of date with the main deployment. It is important that provisioner
daemons are updated at the same time as the main deployment to minimize the risk
of API incompatibility.

**Solution:** Update the provisioner daemon to match the currently running
version of Coder.

> [!NOTE]
> This may be a transient issue if you are currently in the process of updating your deployment.

### EPD03

#### Provisioner Daemon API Version Mismatch

**Problem:** One or more provisioner daemons are using APIs that are marked as
deprecated. These deprecated APIs may be removed in a future release of Coder,
at which point the affected provisioner daemons will no longer be able to
connect to Coder.

**Solution:** Update the provisioner daemon to match the currently running
version of Coder.

> [!NOTE]
> This may be a transient issue if you are currently in the process of updating your deployment.

### EUNKNOWN

#### Unknown Error

**Problem:** This error is shown when an unexpected error occurred evaluating
deployment health. It may resolve on its own.

**Solution:** This may be a bug.
[File a GitHub issue](https://github.com/coder/coder/issues/new)!

---

# Connection Logs

Source: https://coder.com/docs/admin/monitoring/connection-logs

# Connection Logs

> [!NOTE]
> Connection logs require a
> [Premium license](https://coder.com/pricing#compare-plans).
> For more details, [contact your account team](https://coder.com/contact).

The **Connection Log** page in the dashboard allows Auditors to monitor workspace agent connections.

## Workspace App Connections

The connection log contains a complete record of all workspace app connections.
These originate from within the Coder deployment, and thus the connection log
is a source of truth for these events.

## Browser Port Forwarding

The connection log contains a complete record of all workspace port forwarding
performed via the dashboard.

## SSH and IDE Sessions

The connection log aims to capture a record of all workspace SSH and IDE sessions.
These events are reported by workspace agents, and their receipt by the server
is not guaranteed.

## How to Filter Connection Logs

You can filter connection logs by the following parameters:

- `organization` - The name or ID of the organization of the workspace being
     connected to.
- `workspace_owner` - The username of the owner of the workspace being connected
    to.
- `type` - The type of the connection, such as SSH, VS Code, or workspace app.
    For more connection types, refer to the
    [CoderSDK documentation](https://pkg.go.dev/github.com/coder/coder/v2/codersdk#ConnectionType).
- `username`: The name of the user who initiated the connection.
   Results will not include SSH or IDE sessions.
- `user_email`: The email of the user who initiated the connection.
   Results will not include SSH or IDE sessions.
- `connected_after`: The time after which the connection started.
   Uses the RFC3339Nano format.
- `connected_before`: The time before which the connection started.
   Uses the RFC3339Nano format.
- `workspace_id`: The ID of the workspace being connected to.
- `connection_id`: The ID of the connection.
- `status`: The status of the connection, either `ongoing` or `completed`.
     Some events are neither ongoing nor completed, such as the opening of a
     workspace app.

## Capturing/Exporting Connection Logs

In addition to the Coder dashboard, there are multiple ways to consume or query
connection events.

### REST API

You can retrieve connection logs via the Coder API.
Visit the
[`get-connection-logs` endpoint documentation](../../reference/api/enterprise.md#get-connection-logs)
for details.

### Service Logs

Connection events are also dispatched as service logs and can be captured and
categorized using any log management tool such as [Splunk](https://splunk.com).

Example of a [JSON formatted](../../reference/cli/server.md#--log-json)
connection log entry, when an SSH connection is made:

```json
{
    "ts": "2025-07-03T05:09:41.929840747Z",
    "level": "INFO",
    "msg": "connection_log",
    "caller": "/home/coder/coder/enterprise/audit/backends/slog.go:38",
    "func": "github.com/coder/coder/v2/enterprise/audit/backends.(*SlogExporter).ExportStruct",
    "logger_names": ["coderd"],
    "fields": {
        "request_id": "916ad077-e120-4861-8640-f449d56d2bae",
        "ID": "ca5dfc63-dc43-463a-bb3e-38526866fd4b",
        "OrganizationID": "1a2bb67e-0117-4168-92e0-58138989a7f5",
        "WorkspaceOwnerID": "fe8f4bab-3128-41f1-8fec-1cc0755affe5",
        "WorkspaceID": "05567e23-31e2-4c00-bd05-4d499d437347",
        "WorkspaceName": "dev",
        "AgentName": "main",
        "Type": "ssh",
        "Code": null,
        "Ip": "fd7a:115c:a1e0:4b86:9046:80e:6c70:33b7",
        "UserAgent": "",
        "UserID": null,
        "SlugOrPort": "",
        "ConnectionID": "7a6fafdc-e3d0-43cb-a1b7-1f19802d7908",
        "DisconnectReason": "",
        "Time": "2025-07-10T10:14:38.942776145Z",
        "ConnectionStatus": "connected"
    }
}
```

Example of a [human readable](../../reference/cli/server.md#--log-human)
connection log entry, when `code-server` is opened:

```console
[API] 2025-07-03 06:57:16.157 [info]  coderd: connection_log  request_id=de3f6004-6cc1-4880-a296-d7c6ca1abf75  ID=f0249951-d454-48f6-9504-e73340fa07b7  Time="2025-07-03T06:57:16.144719Z"  OrganizationID=0665a54f-0b77-4a58-94aa-59646fa38a74  WorkspaceOwnerID=6dea5f8c-ecec-4cf0-a5bd-bc2c63af2efa  WorkspaceID=3c0b37c8-e58c-4980-b9a1-2732410480a5  WorkspaceName=dev  AgentName=main  Type=workspace_app  Code=200  Ip=127.0.0.1  UserAgent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"  UserID=6dea5f8c-ecec-4cf0-a5bd-bc2c63af2efa  SlugOrPort=code-server  ConnectionID=<nil>  DisconnectReason=""  ConnectionStatus=connected
```

## Data Retention

Coder supports configurable retention policies that automatically purge old
Connection Logs. To enable automated purging, configure the
`--connection-logs-retention` flag or `CODER_CONNECTION_LOGS_RETENTION`
environment variable. For comprehensive configuration options, see
[Data Retention](../setup/data-retention.md).

## How to Enable Connection Logs

This feature is only available with a [Premium license](../licensing/index.md).

---

# Notifications

Source: https://coder.com/docs/admin/monitoring/notifications

# Notifications

Notifications are sent by Coder in response to specific internal events, such as
a workspace being deleted or a user being created.

Available events may differ between versions.
For a list of all events, visit your Coder deployment's
`https://coder.example.com/deployment/notifications`.

## Event Types

Notifications are sent in response to internal events, to alert the affected
user(s) of the event.

Coder supports the following list of events:

### Task Events

These notifications are sent to the owner of the workspace where the task is running:

- Task Idle
- Task Working

### Template Events

These notifications are sent to users with **template admin** roles:

- Report: Workspace builds failed for template
  - This notification is delivered as part of a weekly cron job and summarizes
    the failed builds for a given template.
- Template deleted
- Template deprecated

### User Events

These notifications are sent to users with **owner** and **user admin** roles:

- User account activated
- User account created
- User account deleted
- User account suspended

These notifications are sent to users themselves:

- User account suspended
- User account activated
- User password reset (One-time passcode)

### Workspace Events

These notifications are sent to the workspace owner:

- Workspace automatic build failure
- Workspace created
- Workspace deleted
- Workspace manual build failure
- Workspace manually updated
- Workspace marked as dormant
- Workspace marked for deletion
- Out of memory (OOM) / Out of disk (OOD)
  - Template admins can [configure OOM/OOD](#configure-oomood-notifications) notifications in the template `main.tf`.
- Workspace automatically updated

## Delivery Methods

Notifications can be delivered through the Coder dashboard Inbox and by SMTP or webhook.
OOM/OOD notifications can be delivered to users in VS Code.

You can configure:

- SMTP or webhooks globally with
[`CODER_NOTIFICATIONS_METHOD`](../../../reference/cli/server.md#--notifications-method)
(default: `smtp`).
- Coder dashboard Inbox with
[`CODER_NOTIFICATIONS_INBOX_ENABLED`](../../../reference/cli/server.md#--notifications-inbox-enabled)
(default: `true`).

Premium customers can configure which method to use for each of the supported
[Events](#workspace-events).
See the [Preferences](#delivery-preferences) section for more details.

## Configuration

You can modify the notification delivery behavior in your Coder deployment's
`https://coder.example.com/settings/notifications`, or with the following server flags:

| Required | CLI                                 | Env                                     | Type       | Description                                                                                                           | Default |
|:--------:|-------------------------------------|-----------------------------------------|------------|-----------------------------------------------------------------------------------------------------------------------|---------|
|    ✔️    | `--notifications-dispatch-timeout`  | `CODER_NOTIFICATIONS_DISPATCH_TIMEOUT`  | `duration` | How long to wait while a notification is being sent before giving up.                                                 | 1m      |
|    ✔️    | `--notifications-method`            | `CODER_NOTIFICATIONS_METHOD`            | `string`   | Which delivery method to use (available options: 'smtp', 'webhook'). See [Delivery Methods](#delivery-methods) below. | smtp    |
|    -️    | `--notifications-max-send-attempts` | `CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS` | `int`      | The upper limit of attempts to send a notification.                                                                   | 5       |
|    -️    | `--notifications-inbox-enabled`     | `CODER_NOTIFICATIONS_INBOX_ENABLED`     | `bool`     | Enable or disable inbox notifications in the Coder dashboard.                                                         | true    |

### Configure OOM/OOD notifications

You can monitor out of memory (OOM) and out of disk (OOD) errors and alert users
when they overutilize memory and disk.

This can help prevent agent disconnects due to OOM/OOD issues.

To enable OOM/OOD notifications on a template, follow the steps in the
[resource monitoring guide](../../templates/extending-templates/resource-monitoring.md).

## SMTP (Email)

Use the `smtp` method to deliver notifications by email to your users. Coder
does not ship with an SMTP server, so you will need to configure Coder to use an
existing one.

**Server Settings:**

| Required | CLI                 | Env                     | Type     | Description                                                       | Default   |
|:--------:|---------------------|-------------------------|----------|-------------------------------------------------------------------|-----------|
|    ✔️    | `--email-from`      | `CODER_EMAIL_FROM`      | `string` | The sender's address to use (e.g. `"Coder <coder@example.com>"`). |           |
|    ✔️    | `--email-smarthost` | `CODER_EMAIL_SMARTHOST` | `string` | The SMTP relay to send messages (format: `hostname:port`)         |           |
|    ✔️    | `--email-hello`     | `CODER_EMAIL_HELLO`     | `string` | The hostname identifying the SMTP server.                         | localhost |

**Authentication Settings:**

| Required | CLI                          | Env                              | Type     | Description                                                               |
|:--------:|------------------------------|----------------------------------|----------|---------------------------------------------------------------------------|
|    -     | `--email-auth-username`      | `CODER_EMAIL_AUTH_USERNAME`      | `string` | Username to use with PLAIN/LOGIN authentication.                          |
|    -     | `--email-auth-password`      | `CODER_EMAIL_AUTH_PASSWORD`      | `string` | Password to use with PLAIN/LOGIN authentication.                          |
|    -     | `--email-auth-password-file` | `CODER_EMAIL_AUTH_PASSWORD_FILE` | `string` | File from which to load password for use with PLAIN/LOGIN authentication. |
|    -     | `--email-auth-identity`      | `CODER_EMAIL_AUTH_IDENTITY`      | `string` | Identity to use with PLAIN authentication.                                |

**TLS Settings:**

| Required | CLI                         | Env                           | Type     | Description                                                                                                                                                        | Default |
|:--------:|-----------------------------|-------------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
|    -     | `--email-force-tls`         | `CODER_EMAIL_FORCE_TLS`       | `bool`   | Force a TLS connection to the configured SMTP smarthost. If port 465 is used, TLS will be forced. See <https://datatracker.ietf.org/doc/html/rfc8314#section-3.3>. | false   |
|    -     | `--email-tls-starttls`      | `CODER_EMAIL_TLS_STARTTLS`    | `bool`   | Enable STARTTLS to upgrade insecure SMTP connections using TLS. Ignored if `CODER_EMAIL_FORCE_TLS` is set.                                                         | false   |
|    -     | `--email-tls-skip-verify`   | `CODER_EMAIL_TLS_SKIPVERIFY`  | `bool`   | Skip verification of the target server's certificate (**insecure**).                                                                                               | false   |
|    -     | `--email-tls-server-name`   | `CODER_EMAIL_TLS_SERVERNAME`  | `string` | Server name to verify against the target certificate.                                                                                                              |         |
|    -     | `--email-tls-cert-file`     | `CODER_EMAIL_TLS_CERTFILE`    | `string` | Certificate file to use.                                                                                                                                           |         |
|    -     | `--email-tls-cert-key-file` | `CODER_EMAIL_TLS_CERTKEYFILE` | `string` | Certificate key file to use.                                                                                                                                       |         |

**NOTE:** you _MUST_ use `CODER_EMAIL_FORCE_TLS` if your smarthost supports TLS
on a port other than `465`.

### Send emails using G-Suite

After setting the required fields above:

1. Create an [App Password](https://myaccount.google.com/apppasswords) using the
   account you wish to send from.

1. Set the following configuration options:

   ```text
   CODER_EMAIL_SMARTHOST=smtp.gmail.com:465
   CODER_EMAIL_AUTH_USERNAME=<user>@<domain>
   CODER_EMAIL_AUTH_PASSWORD="<app password created above (no spaces)>"
   ```

   **Note:** The `CODER_EMAIL_AUTH_PASSWORD` must be entered without spaces.

See
[this help article from Google](https://support.google.com/a/answer/176600?hl=en)
for more options.

### Send emails using Outlook.com

After setting the required fields above:

1. Set up an account on Microsoft 365 or outlook.com
1. Set the following configuration options:

   ```text
   CODER_EMAIL_SMARTHOST=smtp-mail.outlook.com:587
   CODER_EMAIL_TLS_STARTTLS=true
   CODER_EMAIL_AUTH_USERNAME=<user>@<domain>
   CODER_EMAIL_AUTH_PASSWORD="<account password>"
   ```

See
[this help article from Microsoft](https://support.microsoft.com/en-us/office/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040)
for more options.

## Webhook

The webhook delivery method sends an HTTP POST request to the defined endpoint.
The purpose of webhook notifications is to enable integrations with other
systems.

**Settings**:

| Required | CLI                                | Env                                    | Type  | Description                             |
|:--------:|------------------------------------|----------------------------------------|-------|-----------------------------------------|
|    ✔️    | `--notifications-webhook-endpoint` | `CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT` | `url` | The endpoint to which to send webhooks. |

Here is an example payload for Coder's webhook notification:

```json
{
    "_version": "1.0",
    "msg_id": "88750cad-77d4-4663-8bc0-f46855f5019b",
    "payload": {
        "_version": "1.0",
        "notification_name": "Workspace Deleted",
        "user_id": "4ac34fcb-8155-44d5-8301-e3cd46e88b35",
        "user_email": "danny@coder.com",
        "user_name": "danny",
        "user_username": "danny",
        "actions": [
            {
                "label": "View workspaces",
                "url": "https://et23ntkhpueak.pit-1.try.coder.app/workspaces"
            },
            {
                "label": "View templates",
                "url": "https://et23ntkhpueak.pit-1.try.coder.app/templates"
            }
        ],
        "labels": {
            "initiator": "danny",
            "name": "my-workspace",
            "reason": "initiated by user"
        }
    },
    "title": "Workspace \"my-workspace\" deleted",
    "body": "Hi danny\n\nYour workspace my-workspace was deleted.\nThe specified reason was \"initiated by user (danny)\"."
}
```

The top-level object has these keys:

- `_version`: describes the version of this schema; follows semantic versioning
- `msg_id`: the UUID of the notification (matches the ID in the
  `notification_messages` table)
- `payload`: contains the specific details of the notification; described below
- `title`: the title of the notification message (equivalent to a subject in
  SMTP delivery)
- `body`: the body of the notification message (equivalent to the message body
  in SMTP delivery)

The `payload` object has these keys:

- `_version`: describes the version of this inner schema; follows semantic
  versioning
- `notification_name`: name of the event which triggered the notification
- `user_id`: Coder internal user identifier of the target user (UUID)
- `user_email`: email address of the target user
- `user_name`: name of the target user
- `user_username`: username of the target user
- `actions`: a list of CTAs (Call-To-Action); these are mainly relevant for SMTP
  delivery in which they're shown as buttons
- `labels`: dynamic map of zero or more string key-value pairs; these vary from
  event to event

## User Preferences

All users have the option to opt-out of any notifications. Go to **Account** ->
**Notifications** to turn notifications on or off. The delivery method for each
notification is indicated on the right hand side of this table.

![User Notification Preferences](../../../images/admin/monitoring/notifications/user-notification-preferences.png)

## Delivery Preferences

> [!NOTE]
> Delivery preferences is a Premium feature.
> [Learn more](https://coder.com/pricing#compare-plans).

Administrators can configure which delivery methods are used for each different
[event type](#event-types).

![preferences](../../../images/admin/monitoring/notifications/notification-admin-prefs.png)

You can find this page under
`https://$CODER_ACCESS_URL/deployment/notifications?tab=events`.

## Custom notifications

Custom notifications let you send an ad‑hoc notification to yourself using the Coder CLI.
These are useful for surfacing the result of long-running tasks or important state changes.
At this time, custom notifications can only be sent to the user making the request.

To send a custom notification, execute [`coder notifications custom <title> <message>`](../../../reference/cli/notifications_custom.md).

<!-- TODO(ssncferreira): Update when sending custom notifications to multiple users/roles is supported.
	 Explain deduplication behaviour for multiple users/roles.
	 See: https://github.com/coder/coder/issues/19768
-->
**Note:** The recipient is always the requesting user as targeting other users or groups isn’t supported yet.

### Examples

- Send yourself a quick update:

```shell
coder templates push -y && coder notifications custom "Template push complete" "Template version uploaded."
```

- Use in a script after a long-running task:

```shell
#!/usr/bin/env bash
set -o pipefail

if make test 2>&1 | tee test_output.log; then
  coder notifications custom "Tests Succeeded" $'Test results:\n  • ✅ success'
else
  failures=$(grep -Po '\d+(?=\s+failures)' test_output.log | tail -n1 || echo 0)
  coder notifications custom "Tests Failed" $'Test results:\n  • ❌ failed ('"$failures"' tests failed)'
  exit 1
fi
```

## Stop sending notifications

Administrators may wish to stop _all_ notifications across the deployment. We
support a killswitch in the CLI for these cases.

To pause sending notifications, execute
[`coder notifications pause`](../../../reference/cli/notifications_pause.md).

To resume sending notifications, execute
[`coder notifications resume`](../../../reference/cli/notifications_resume.md).

## Troubleshooting

If notifications are not being delivered, use the following methods to
troubleshoot:

1. Ensure notifications are being added to the `notification_messages` table.
1. Review any available error messages in the `status_reason` column
1. Review the logs. Search for the term `notifications` for diagnostic information.

   - If you do not see any relevant logs, set
    `CODER_LOG_FILTER=".*notifications.*"` to filter for notification-related logs.
1. If you are on version 2.15.x, notifications must be enabled using the
    `notifications`
    [experiment](../../../install/releases/feature-stages.md#early-access-features).

    Notifications are enabled by default in Coder v2.16.0 and later.

## Internals

The notification system is built to operate concurrently in a single- or
multi-replica Coder deployment, and has a built-in retry mechanism. It uses the
configured Postgres database to store notifications in a queue and facilitate
concurrency.

All messages are stored in the `notification_messages` table.

Messages older than seven days are deleted.

### Message States

![states](../../../images/admin/monitoring/notifications/notification-states.png)

_A notifier here refers to a Coder replica which is responsible for dispatching
the notification. All running replicas act as notifiers to process pending
messages._

- a message begins in `pending` state
- transitions to `leased` when a Coder replica acquires new messages from the
  database
  - new messages are checked for every `CODER_NOTIFICATIONS_FETCH_INTERVAL`
    (default: 15s)
- if a message is delivered successfully, it transitions to `sent` state
- if a message encounters a non-retryable error (e.g. misconfiguration), it
  transitions to `permanent_failure`
- if a message encounters a retryable error (e.g. temporary server outage), it
  transitions to `temporary_failure`
  - this message will be retried up to `CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS`
    (default: 5)
  - this message will transition back to `pending` state after
    `CODER_NOTIFICATIONS_RETRY_INTERVAL` (default: 5m) and be retried
  - after `CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS` is exceeded, it transitions to
    `permanent_failure`

See [Troubleshooting](#troubleshooting) above for more details.

---

# Slack Notifications

Source: https://coder.com/docs/admin/monitoring/notifications/slack

# Slack Notifications

[Slack](https://slack.com/) is a popular messaging platform designed for teams
and businesses, enabling real-time collaboration through channels, direct
messages, and integrations with external tools. With Coder's integration, you
can enable automated notifications directly within a self-hosted
[Slack app](https://api.slack.com/apps), keeping your team updated on key events
in your Coder environment.

Administrators can configure Coder to send notifications via an incoming webhook
endpoint. These notifications will be delivered as Slack messages direct to the
user. Routing is based on the user's email address, and this should be
consistent between Slack and their Coder login.

## Requirements

Before setting up Slack notifications, ensure that you have the following:

- Administrator access to the Slack platform to create apps
- Coder platform >=v2.16.0

## Create Slack Application

To integrate Slack with Coder, follow these steps to create a Slack application:

1. Go to the [Slack Apps](https://api.slack.com/apps) dashboard and create a new
   Slack App.

2. Under "Basic Information," you'll find a "Signing Secret." The Slack
   application uses it to
   [verify requests](https://api.slack.com/authentication/verifying-requests-from-slack)
   coming from Slack.

3. Under "OAuth & Permissions", add the following OAuth scopes:

   - `chat:write`: To send messages as the app.
   - `users:read`: To find the user details.
   - `users:read.email`: To find user emails.

4. Install the app to your workspace and note down the **Bot User OAuth Token**
   from the "OAuth & Permissions" section.

## Build a Webserver to Receive Webhooks

The Slack bot for Coder runs as a _Bolt application_, which is a framework
designed for building Slack apps using the Slack API.
[Bolt for JavaScript](https://github.com/slackapi/bolt-js) provides an
easy-to-use API for responding to events, commands, and interactions from Slack.

To build the server to receive webhooks and interact with Slack:

1. Initialize your project by running:

   ```bash
   npm init -y
   ```

2. Install the Bolt library:

   ```bash
   npm install @slack/bolt
   ```

3. Create and edit the `app.js` file. Below is an example of the basic
   structure:

   ```js
   const { App, LogLevel, ExpressReceiver } = require("@slack/bolt");
   const bodyParser = require("body-parser");

   const port = process.env.PORT || 6000;

   // Create a Bolt Receiver
   const receiver = new ExpressReceiver({
       signingSecret: process.env.SLACK_SIGNING_SECRET,
   });
   receiver.router.use(bodyParser.json());

   // Create the Bolt App, using the receiver
   const app = new App({
       token: process.env.SLACK_BOT_TOKEN,
       logLevel: LogLevel.DEBUG,
       receiver,
   });

   receiver.router.post("/v1/webhook", async (req, res) => {
       try {
           if (!req.body) {
               return res.status(400).send("Error: request body is missing");
           }

           const { title, body_markdown } = req.body;
              if (!title || !body_markdown) {
                  return res
                      .status(400)
                      .send('Error: missing fields: "title", or "body_markdown"');
           }

           const payload = req.body.payload;
           if (!payload) {
               return res.status(400).send('Error: missing "payload" field');
           }

           const { user_email, actions } = payload;
           if (!user_email || !actions) {
               return res
                   .status(400)
                   .send('Error: missing fields: "user_email", "actions"');
           }

           // Get the user ID using Slack API
           const userByEmail = await app.client.users.lookupByEmail({
               email: user_email,
           });

           const slackMessage = {
               channel: userByEmail.user.id,
               text: body_markdown,
               blocks: [
                   {
                       type: "header",
                       text: { type: "plain_text", text: title },
                   },
                   {
                       type: "section",
                       text: { type: "mrkdwn", text: body_markdown },
                   },
               ],
           };

           // Add action buttons if they exist
           if (actions && actions.length > 0) {
               slackMessage.blocks.push({
                   type: "actions",
                   elements: actions.map((action) => ({
                       type: "button",
                       text: { type: "plain_text", text: action.label },
                       url: action.url,
                   })),
               });
           }

           // Post message to the user on Slack
           await app.client.chat.postMessage(slackMessage);

           res.status(204).send();
       } catch (error) {
           console.error("Error sending message:", error);
           res.status(500).send();
       }
   });

   // Acknowledge clicks on link_button, otherwise Slack UI
   // complains about missing events.
   app.action("button_click", async ({ body, ack, say }) => {
       await ack(); // no specific action needed
   });

   // Start the Bolt app
   (async () => {
       await app.start(port);
       console.log("⚡️ Coder Slack bot is running!");
   })();
   ```

4. Set environment variables to identify the Slack app:

   ```bash
   export SLACK_BOT_TOKEN=xoxb-...
   export SLACK_SIGNING_SECRET=0da4b...
   ```

5. Start the web application by running:

   ```bash
   node app.js
   ```

## Enable Interactivity in Slack

Slack requires the bot to acknowledge when a user clicks on a URL action button.
This is handled by setting up interactivity.

Under "Interactivity & Shortcuts" in your Slack app settings, set the Request
URL to match the public URL of your web server's endpoint.

You can use any public endpoint that accepts and responds to POST requests with HTTP 200.
For temporary testing, you can set it to `https://httpbin.org/status/200`.

Once this is set, Slack will send interaction payloads to your server, which
must respond appropriately.

## Enable Webhook Integration in Coder

To enable webhook integration in Coder, define the POST webhook endpoint
matching the deployed Slack bot:

```bash
export CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT=http://localhost:6000/v1/webhook`
```

Finally, go to the **Notification Settings** in Coder and switch the notifier to
**Webhook**.

---

# Microsoft Teams Notifications

Source: https://coder.com/docs/admin/monitoring/notifications/teams

# Microsoft Teams Notifications

[Microsoft Teams](https://www.microsoft.com/en-us/microsoft-teams) is a widely
used collaboration platform, and with Coder's integration, you can enable
automated notifications directly within Teams using workflows and
[Adaptive Cards](https://adaptivecards.io/)

Administrators can configure Coder to send notifications via an incoming webhook
endpoint. These notifications appear as messages in Teams chats, either with the
Flow Bot or a specified user/service account.

## Requirements

Before setting up Microsoft Teams notifications, ensure that you have the
following:

- Administrator access to the Teams platform
- Coder platform >=v2.16.0

## Build Teams Workflow

The process of setting up a Teams workflow consists of three key steps:

1. Configure the Webhook Trigger.

   Begin by configuring the trigger: **"When a Teams webhook request is
   received"**.

   Ensure the trigger access level is set to **"Anyone"**.

1. Setup the JSON Parsing Action.

   Add the **"Parse JSON"** action, linking the content to the **"Body"** of the
   received webhook request. Use the following schema to parse the notification
   payload:

   ```json
   {
       "type": "object",
       "properties": {
           "_version": {
               "type": "string"
           },
           "payload": {
               "type": "object",
               "properties": {
                   "_version": {
                       "type": "string"
                   },
                   "user_email": {
                       "type": "string"
                   },
                   "actions": {
                       "type": "array",
                       "items": {
                           "type": "object",
                           "properties": {
                               "label": {
                                   "type": "string"
                               },
                               "url": {
                                   "type": "string"
                               }
                           },
                           "required": ["label", "url"]
                       }
                   }
               }
           },
           "title_markdown": {
               "type": "string"
           },
           "body_markdown": {
               "type": "string"
           }
       }
   }
   ```

   This action parses the notification's title, body, and the recipient's email
   address.

1. Configure the Adaptive Card Action.

   Finally, set up the **"Post Adaptive Card in a chat or channel"** action with
   the following recommended settings:

   **Post as**: Flow Bot

   **Post in**: Chat with Flow Bot

   **Recipient**: `user_email`

   Use the following _Adaptive Card_ template:

   ```json
   {
       "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
       "type": "AdaptiveCard",
       "version": "1.0",
       "body": [
           {
               "type": "Image",
               "url": "https://coder.com/coder-logo-horizontal.png",
               "height": "40px",
               "altText": "Coder",
               "horizontalAlignment": "center"
           },
           {
               "type": "TextBlock",
               "text": "**@{replace(body('Parse_JSON')?['title_markdown'], '"', '\"')}**"
           },
           {
               "type": "TextBlock",
               "text": "@{replace(body('Parse_JSON')?['body_markdown'], '"', '\"')}",
               "wrap": true
           },
           {
               "type": "ActionSet",
               "actions": [@{replace(replace(join(body('Parse_JSON')?['payload']?['actions'], ','), '{', '{"type": "Action.OpenUrl",'), '"label"', '"title"')}]
           }
       ]
   }
   ```

   _Notice_: The Coder `actions` format differs from the `ActionSet` schema, so
   its properties need to be modified: include `Action.OpenUrl` type, rename
   `label` to `title`. Unfortunately, there is no straightforward solution for
   `for-each` pattern.

   Feel free to customize the payload to modify the logo, notification title, or
   body content to suit your needs.

## Enable Webhook Integration

To enable webhook integration in Coder, define the POST webhook endpoint created
by your Teams workflow:

```bash
export CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT=https://prod-16.eastus.logic.azure.com:443/workflows/f8fbe3e8211e4b638...`
```

Finally, go to the **Notification Settings** in Coder and switch the notifier to
**Webhook**.

## Limitations

1. **Public Webhook Trigger**: The Teams webhook trigger must be open to the
   public (**"Anyone"** can send the payload). It's recommended to keep the
   endpoint secret and apply additional authorization layers to protect against
   unauthorized access.

2. **Markdown Support in Adaptive Cards**: Note that Adaptive Cards support a
   [limited set of Markdown tags](https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format?tabs=adaptive-md%2Cdesktop%2Cconnector-html).

---

# Security

Source: https://coder.com/docs/admin/security

# Security

<children></children>

For other security tips, visit our guide to
[security best practices](../../tutorials/best-practices/security-best-practices.md).

## Security Advisories

> [!CAUTION]
> If you discover a vulnerability in Coder, please do not hesitate to report it
> to us by following the [security policy](https://github.com/coder/coder/blob/main/SECURITY.md).

From time to time, Coder employees or other community members may discover
vulnerabilities in the product.

If a vulnerability requires an immediate upgrade to mitigate a potential
security risk, we will add it to the below table.

Click on the description links to view more details about each specific
vulnerability.

---

| Description                                                                                                                                   | Severity | Fix                                                            | Vulnerable Versions |
|-----------------------------------------------------------------------------------------------------------------------------------------------|----------|----------------------------------------------------------------|---------------------|
| [API tokens of deleted users not invalidated](https://github.com/coder/coder/blob/main/docs/admin/security/0001_user_apikeys_invalidation.md) | HIGH     | [v0.23.0](https://github.com/coder/coder/releases/tag/v0.23.0) | v0.8.25 - v0.22.2   |

---

# Audit Logs

Source: https://coder.com/docs/admin/security/audit-logs

# Audit Logs

**Audit Logs** allows Auditors to monitor user operations in their deployment.

> [!NOTE]
> Audit logs require a
> [Premium license](https://coder.com/pricing#compare-plans).
> For more details, [contact your account team](https://coder.com/contact).

## Tracked Events

We track the following resources:

<!-- Code generated by 'make docs/admin/security/audit-logs.md'. DO NOT EDIT -->

| <b>Resource<b>                                                  |                                                                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
|-----------------------------------------------------------------|----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| APIKey<br><i>login, logout, register, create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>allow_list</td><td>false</td></tr><tr><td>created_at</td><td>true</td></tr><tr><td>expires_at</td><td>true</td></tr><tr><td>hashed_secret</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>ip_address</td><td>false</td></tr><tr><td>last_used</td><td>true</td></tr><tr><td>lifetime_seconds</td><td>false</td></tr><tr><td>login_type</td><td>false</td></tr><tr><td>scopes</td><td>false</td></tr><tr><td>token_name</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| AiSeatState<br><i>create</i>                                    | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>first_used_at</td><td>true</td></tr><tr><td>last_event_description</td><td>true</td></tr><tr><td>last_event_type</td><td>true</td></tr><tr><td>last_used_at</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| AuditOAuthConvertState<br><i></i>                               | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>true</td></tr><tr><td>expires_at</td><td>true</td></tr><tr><td>from_login_type</td><td>true</td></tr><tr><td>to_login_type</td><td>true</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Group<br><i>create, write, delete</i>                           | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>avatar_url</td><td>true</td></tr><tr><td>chat_spend_limit_micros</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>members</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>quota_allowance</td><td>true</td></tr><tr><td>source</td><td>false</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| AuditableOrganizationMember<br><i></i>                          | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>roles</td><td>true</td></tr><tr><td>updated_at</td><td>true</td></tr><tr><td>user_id</td><td>true</td></tr><tr><td>username</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Chat<br><i>create, write</i>                                    | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>agent_id</td><td>false</td></tr><tr><td>archived</td><td>true</td></tr><tr><td>build_id</td><td>false</td></tr><tr><td>client_type</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>dynamic_tools</td><td>false</td></tr><tr><td>heartbeat_at</td><td>false</td></tr><tr><td>id</td><td>true</td></tr><tr><td>labels</td><td>true</td></tr><tr><td>last_error</td><td>false</td></tr><tr><td>last_injected_context</td><td>false</td></tr><tr><td>last_model_config_id</td><td>false</td></tr><tr><td>last_read_message_id</td><td>false</td></tr><tr><td>last_turn_summary</td><td>false</td></tr><tr><td>mcp_server_ids</td><td>true</td></tr><tr><td>mode</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>owner_id</td><td>true</td></tr><tr><td>parent_chat_id</td><td>false</td></tr><tr><td>pin_order</td><td>true</td></tr><tr><td>plan_mode</td><td>false</td></tr><tr><td>root_chat_id</td><td>false</td></tr><tr><td>started_at</td><td>false</td></tr><tr><td>status</td><td>false</td></tr><tr><td>title</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>worker_id</td><td>false</td></tr><tr><td>workspace_id</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| CustomRole<br><i></i>                                           | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>id</td><td>false</td></tr><tr><td>is_system</td><td>false</td></tr><tr><td>member_permissions</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>org_permissions</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>site_permissions</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_permissions</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| GitSSHKey<br><i>create</i>                                      | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>private_key</td><td>true</td></tr><tr><td>public_key</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| GroupSyncSettings<br><i></i>                                    | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>auto_create_missing_groups</td><td>true</td></tr><tr><td>field</td><td>true</td></tr><tr><td>legacy_group_name_mapping</td><td>false</td></tr><tr><td>mapping</td><td>true</td></tr><tr><td>regex_filter</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| HealthSettings<br><i></i>                                       | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>dismissed_healthchecks</td><td>true</td></tr><tr><td>id</td><td>false</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| License<br><i>create, delete</i>                                | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>exp</td><td>true</td></tr><tr><td>id</td><td>false</td></tr><tr><td>jwt</td><td>false</td></tr><tr><td>uploaded_at</td><td>true</td></tr><tr><td>uuid</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| NotificationTemplate<br><i></i>                                 | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>actions</td><td>true</td></tr><tr><td>body_template</td><td>true</td></tr><tr><td>enabled_by_default</td><td>true</td></tr><tr><td>group</td><td>true</td></tr><tr><td>id</td><td>false</td></tr><tr><td>kind</td><td>true</td></tr><tr><td>method</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>title_template</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| NotificationsSettings<br><i></i>                                | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>id</td><td>false</td></tr><tr><td>notifier_paused</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| OAuth2ProviderApp<br><i></i>                                    | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>callback_url</td><td>true</td></tr><tr><td>client_id_issued_at</td><td>false</td></tr><tr><td>client_secret_expires_at</td><td>true</td></tr><tr><td>client_type</td><td>true</td></tr><tr><td>client_uri</td><td>true</td></tr><tr><td>contacts</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>dynamically_registered</td><td>true</td></tr><tr><td>grant_types</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>false</td></tr><tr><td>jwks</td><td>true</td></tr><tr><td>jwks_uri</td><td>true</td></tr><tr><td>logo_uri</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>policy_uri</td><td>true</td></tr><tr><td>redirect_uris</td><td>true</td></tr><tr><td>registration_access_token</td><td>true</td></tr><tr><td>registration_client_uri</td><td>true</td></tr><tr><td>response_types</td><td>true</td></tr><tr><td>scope</td><td>true</td></tr><tr><td>software_id</td><td>true</td></tr><tr><td>software_version</td><td>true</td></tr><tr><td>token_endpoint_auth_method</td><td>true</td></tr><tr><td>tos_uri</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| OAuth2ProviderAppSecret<br><i></i>                              | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>app_id</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>display_secret</td><td>false</td></tr><tr><td>hashed_secret</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>last_used_at</td><td>false</td></tr><tr><td>secret_prefix</td><td>false</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Organization<br><i></i>                                         | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>true</td></tr><tr><td>description</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>false</td></tr><tr><td>is_default</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>shareable_workspace_owners</td><td>true</td></tr><tr><td>updated_at</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| OrganizationSyncSettings<br><i></i>                             | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>assign_default</td><td>true</td></tr><tr><td>field</td><td>true</td></tr><tr><td>mapping</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| PrebuildsSettings<br><i></i>                                    | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>id</td><td>false</td></tr><tr><td>reconciliation_paused</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| RoleSyncSettings<br><i></i>                                     | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>field</td><td>true</td></tr><tr><td>mapping</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| TaskTable<br><i></i>                                            | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>deleted_at</td><td>false</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>owner_id</td><td>true</td></tr><tr><td>prompt</td><td>true</td></tr><tr><td>template_parameters</td><td>true</td></tr><tr><td>template_version_id</td><td>true</td></tr><tr><td>workspace_id</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Template<br><i>write, delete</i>                                | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>active_version_id</td><td>true</td></tr><tr><td>activity_bump</td><td>true</td></tr><tr><td>allow_user_autostart</td><td>true</td></tr><tr><td>allow_user_autostop</td><td>true</td></tr><tr><td>allow_user_cancel_workspace_jobs</td><td>true</td></tr><tr><td>autostart_block_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_weeks</td><td>true</td></tr><tr><td>cors_behavior</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_name</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>default_ttl</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>deprecated</td><td>true</td></tr><tr><td>description</td><td>true</td></tr><tr><td>disable_module_cache</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>failure_ttl</td><td>true</td></tr><tr><td>group_acl</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>max_port_sharing_level</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_display_name</td><td>false</td></tr><tr><td>organization_icon</td><td>false</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>organization_name</td><td>false</td></tr><tr><td>provisioner</td><td>true</td></tr><tr><td>require_active_version</td><td>true</td></tr><tr><td>time_til_dormant</td><td>true</td></tr><tr><td>time_til_dormant_autodelete</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>use_classic_parameter_flow</td><td>true</td></tr><tr><td>user_acl</td><td>true</td></tr></tbody></table> |
| TemplateVersion<br><i>create, write</i>                         | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>archived</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_name</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>external_auth_providers</td><td>false</td></tr><tr><td>has_ai_task</td><td>false</td></tr><tr><td>has_external_agent</td><td>false</td></tr><tr><td>id</td><td>true</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>message</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>readme</td><td>true</td></tr><tr><td>source_example_id</td><td>false</td></tr><tr><td>template_id</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| User<br><i>create, write, delete</i>                            | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>avatar_url</td><td>false</td></tr><tr><td>chat_spend_limit_micros</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>true</td></tr><tr><td>email</td><td>true</td></tr><tr><td>github_com_user_id</td><td>false</td></tr><tr><td>hashed_one_time_passcode</td><td>false</td></tr><tr><td>hashed_password</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>is_service_account</td><td>true</td></tr><tr><td>is_system</td><td>true</td></tr><tr><td>last_seen_at</td><td>false</td></tr><tr><td>login_type</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>one_time_passcode_expires_at</td><td>true</td></tr><tr><td>quiet_hours_schedule</td><td>true</td></tr><tr><td>rbac_roles</td><td>true</td></tr><tr><td>status</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>username</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| UserSecret<br><i>create, write, delete</i>                      | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>description</td><td>true</td></tr><tr><td>env_name</td><td>true</td></tr><tr><td>file_path</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr><tr><td>value</td><td>true</td></tr><tr><td>value_key_id</td><td>false</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| WorkspaceBuild<br><i>start, stop</i>                            | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>build_number</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>daily_cost</td><td>false</td></tr><tr><td>deadline</td><td>false</td></tr><tr><td>has_ai_task</td><td>false</td></tr><tr><td>has_external_agent</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>initiator_by_avatar_url</td><td>false</td></tr><tr><td>initiator_by_name</td><td>false</td></tr><tr><td>initiator_by_username</td><td>false</td></tr><tr><td>initiator_id</td><td>false</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>max_deadline</td><td>false</td></tr><tr><td>reason</td><td>false</td></tr><tr><td>template_version_id</td><td>true</td></tr><tr><td>template_version_preset_id</td><td>false</td></tr><tr><td>transition</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>workspace_id</td><td>false</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| WorkspaceProxy<br><i></i>                                       | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>derp_enabled</td><td>true</td></tr><tr><td>derp_only</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>region_id</td><td>true</td></tr><tr><td>token_hashed_secret</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>url</td><td>true</td></tr><tr><td>version</td><td>true</td></tr><tr><td>wildcard_hostname</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| WorkspaceTable<br><i></i>                                       | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>automatic_updates</td><td>true</td></tr><tr><td>autostart_schedule</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>deleting_at</td><td>true</td></tr><tr><td>dormant_at</td><td>true</td></tr><tr><td>favorite</td><td>true</td></tr><tr><td>group_acl</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>last_used_at</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>next_start_at</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>owner_id</td><td>true</td></tr><tr><td>template_id</td><td>true</td></tr><tr><td>ttl</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_acl</td><td>true</td></tr></tbody></table>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |

<!-- End generated by 'make docs/admin/security/audit-logs.md'. -->

## How to Filter Audit Logs

You can filter audit logs by the following parameters:

- `resource_type` - The type of the resource, such as a workspace, template,
  or user. For more resource types, refer to the
  [CoderSDK package documentation](https://pkg.go.dev/github.com/coder/coder/v2/codersdk#ResourceType).
- `resource_id` - The ID of the resource.
- `resource_target` - The name of the resource. Can be used instead of
  `resource_id`.
- `action`- The action applied to a resource, such as `create` or `delete`.
  For more actions, refer to the
  [CoderSDK package documentation](https://pkg.go.dev/github.com/coder/coder/v2/codersdk#AuditAction).
- `username` - The username of the user who triggered the action. You can also
  use `me` as a convenient alias for the logged-in user.
- `email` - The email of the user who triggered the action.
- `date_from` - The inclusive start date with format `YYYY-MM-DD`.
- `date_to` - The inclusive end date with format `YYYY-MM-DD`.
- `build_reason` - The reason for the workspace build, if `resource_type` is
  `workspace_build`. Refer to the
  [CoderSDK package documentation](https://pkg.go.dev/github.com/coder/coder/v2/codersdk#BuildReason)
  for a list of valid build reasons.

## Capturing/Exporting Audit Logs

In addition to the Coder dashboard, there are multiple ways to consume or query
audit trails.

### REST API

You can retrieve audit logs via the Coder API.

Visit the
[`get-audit-logs` endpoint documentation](../../reference/api/audit.md#get-audit-logs)
for details.

### Service Logs

Audit trails are also dispatched as service logs and can be captured and
categorized using any log management tool such as [Splunk](https://splunk.com).

Example of a [JSON formatted](../../reference/cli/server.md#--log-json) audit
log entry:

```json
{
    "ts": "2023-06-13T03:45:37.294730279Z",
    "level": "INFO",
    "msg": "audit_log",
    "caller": "/home/coder/coder/enterprise/audit/backends/slog.go:38",
    "func": "github.com/coder/coder/v2/enterprise/audit/backends.(*SlogExporter).ExportStruct",
    "logger_names": ["coderd"],
    "fields": {
        "ID": "033a9ffa-b54d-4c10-8ec3-2aaf9e6d741a",
        "Time": "2023-06-13T03:45:37.288506Z",
        "UserID": "6c405053-27e3-484a-9ad7-bcb64e7bfde6",
        "OrganizationID": "00000000-0000-0000-0000-000000000000",
        "Ip": null,
        "UserAgent": null,
        "ResourceType": "workspace_build",
        "ResourceID": "ca5647e0-ef50-4202-a246-717e04447380",
        "ResourceTarget": "",
        "Action": "start",
        "Diff": {},
        "StatusCode": 200,
        "AdditionalFields": {
            "workspace_name": "linux-container",
            "build_number": "9",
            "build_reason": "initiator",
            "workspace_owner": ""
        },
        "RequestID": "bb791ac3-f6ee-4da8-8ec2-f54e87013e93",
        "ResourceIcon": ""
    }
}
```

Example of a [human readable](../../reference/cli/server.md#--log-human) audit
log entry:

```console
2023-06-13 03:43:29.233 [info]  coderd: audit_log  ID=95f7c392-da3e-480c-a579-8909f145fbe2  Time="2023-06-13T03:43:29.230422Z"  UserID=6c405053-27e3-484a-9ad7-bcb64e7bfde6  OrganizationID=00000000-0000-0000-0000-000000000000  Ip=<nil>  UserAgent=<nil>  ResourceType=workspace_build  ResourceID=988ae133-5b73-41e3-a55e-e1e9d3ef0b66  ResourceTarget=""  Action=start  Diff="{}"  StatusCode=200  AdditionalFields="{\"workspace_name\":\"linux-container\",\"build_number\":\"7\",\"build_reason\":\"initiator\",\"workspace_owner\":\"\"}"  RequestID=9682b1b5-7b9f-4bf2-9a39-9463f8e41cd6  ResourceIcon=""
```

## Purging Old Audit Logs

> [!WARNING]
> Audit Logs provide critical security and compliance information. Purging Audit Logs may impact your organization's ability
> to investigate security incidents or meet compliance requirements. Consult your security and compliance teams before purging any audit data.

### Data Retention

Coder supports configurable retention policies that automatically purge old
Audit Logs. To enable automated purging, configure the
`--audit-logs-retention` flag or `CODER_AUDIT_LOGS_RETENTION` environment
variable. For comprehensive configuration options, see
[Data Retention](../setup/data-retention.md).

### Manual Purging

Alternatively, you can purge Audit Logs manually by running SQL queries
directly against the database.

Audit Logs can account for a large amount of disk usage. Use the following
query to determine the amount of disk space used by the `audit_logs` table.

```sql
SELECT
    relname AS table_name,
    pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
    pg_size_pretty(pg_relation_size(relid)) AS table_size,
    pg_size_pretty(pg_indexes_size(relid)) AS indexes_size,
    (SELECT COUNT(*) FROM audit_logs) AS total_records
FROM pg_catalog.pg_statio_user_tables
WHERE relname = 'audit_logs'
ORDER BY pg_total_relation_size(relid) DESC;
```

Should you wish to purge these records, it is safe to do so. This can only be done by running SQL queries
directly against the `audit_logs` table in the database. We advise users to only purge old records (>1yr)
and in accordance with your compliance requirements.

### Maintenance Procedures for the Audit Logs Table

> [!NOTE]
> `VACUUM FULL` acquires an exclusive lock on the table, blocking all reads and writes. For more information, see the [PostgreSQL VACUUM documentation](https://www.postgresql.org/docs/current/sql-vacuum.html).

You may choose to run a `VACUUM` or `VACUUM FULL` operation on the audit logs table to reclaim disk space. If you choose to run the `FULL` operation, consider the following when doing so:

- **Run during a planned maintenance window** to ensure ample time for the operation to complete and minimize impact to users
- **Stop all running instances of `coderd`** to prevent connection errors while the table is locked. The actual steps for this will depend on your particular deployment setup. For example, if your `coderd` deployment is running on Kubernetes:

  ```bash
  kubectl scale deployment coder --replicas=0 -n coder
  ```

- **Terminate lingering connections** before running the `VACUUM` operation to ensure it starts immediately

  ```sql
  SELECT pg_terminate_backend(pg_stat_activity.pid)
  FROM pg_stat_activity
  WHERE pg_stat_activity.datname = 'coder' AND pid <> pg_backend_pid();
  ```

- **Only `coderd` needs to scale down** - external provisioner daemons, workspace proxies, and workspace agents don't connect to the database directly.

After the vacuum completes, scale coderd back up:

```bash
kubectl scale deployment coder --replicas= -n coder
```

### Backup/Archive

Consider exporting or archiving these records before deletion:

```sql
-- Export to CSV
COPY (SELECT * FROM audit_logs WHERE time < CURRENT_TIMESTAMP - INTERVAL '1 year')
TO '/path/to/audit_logs_archive.csv' DELIMITER ',' CSV HEADER;

-- Copy to archive table
CREATE TABLE audit_logs_archive AS
SELECT * FROM audit_logs WHERE time < CURRENT_TIMESTAMP - INTERVAL '1 year';
```

### Permanent Deletion

> [!NOTE]
> For large `audit_logs` tables, consider running the `DELETE` operation during maintenance windows as it may impact
> database performance. You can also batch the deletions to reduce lock time.

```sql
DELETE FROM audit_logs WHERE time < CURRENT_TIMESTAMP - INTERVAL '1 year';
-- Consider running `VACUUM VERBOSE audit_logs` afterwards for large datasets to reclaim disk space.
```

## How to Enable Audit Logs

This feature is only available with a [Premium license](../licensing/index.md), and is automatically enabled.

---

# Secrets

Source: https://coder.com/docs/admin/security/secrets

# Secrets

Coder is open-minded about how you get your secrets into your workspaces. For
more information about how to use secrets and other security tips, visit our
guide to
[security best practices](../../tutorials/best-practices/security-best-practices.md#secrets).

Use this guide to configure how templates make secrets available to Coder
workspaces. To authenticate workspace provisioners with Coder, see the
<a href="../provisioners/index.md#authentication">provisioners documentation</a>.
For secret values that developers manage themselves, see
[User secrets](../../user-guides/user-secrets.md).

## Before you begin

Your first attempt to use secrets with Coder should be your local method. You
can do everything you can locally and more with your Coder workspace, so
whatever workflow and tools you already use to manage secrets may be brought
over.

Often, this workflow is simply:

1. Give your users their secrets in advance
1. Your users write them to a persistent file after they've built their
   workspace

[Template parameters](../templates/extending-templates/parameters.md) are a
dangerous way to accept secrets. We show parameters in cleartext around the
product. Assume anyone with view access to a workspace can also see its
parameters.

## SSH Keys

Coder generates SSH key pairs for each user. This can be used as an
authentication mechanism for git providers or other tools. Within workspaces,
git will attempt to use this key within workspaces via the `$GIT_SSH_COMMAND`
environment variable.

Users can view their public key in their account settings:

![SSH keys in account settings](../../images/ssh-keys.png)

> [!NOTE]
> SSH keys are never stored in Coder workspaces, and are fetched only when
> SSH is invoked. The keys are held in-memory and never written to disk.

## User secrets (Early Access)

User secrets are developer-managed values that Coder injects at workspace start.
If a user secret targets the same environment variable name or file path as a
template-provided variable or file, Coder injects the user secret into that
workspace. See the [User secrets guide](../../user-guides/user-secrets.md).

## Dynamic Secrets

Dynamic secrets are attached to the workspace lifecycle and automatically
injected into the workspace. With a little bit of up front template work, they
make life simpler for both the end user and the security team.

This method is limited to
[services with Terraform providers](https://registry.terraform.io/browse/providers),
which excludes obscure API providers.

Dynamic secrets can be implemented in your template code like so:

```tf
resource "twilio_iam_api_key" "api_key" {
  account_sid   = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  friendly_name = "Test API Key"
}

resource "coder_agent" "main" {
  # ...
  env = {
    # Let users access the secret via $TWILIO_API_SECRET
    TWILIO_API_SECRET = "${twilio_iam_api_key.api_key.secret}"
  }
}
```

A catch-all variation of this approach is dynamically provisioning a cloud
service account (e.g
[GCP](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_key#private_key))
for each workspace and then making the relevant secrets available via the
cloud's secret management system.

## Displaying Secrets

While you can inject secrets into the workspace via environment variables, you
can also show them in the Workspace UI with
[`coder_metadata`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/metadata).

![Secrets UI](../../images/admin/secret-metadata.PNG)

Can be produced with

```tf
resource "twilio_iam_api_key" "api_key" {
  account_sid   = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  friendly_name = "Test API Key"
}


resource "coder_metadata" "twilio_key" {
  resource_id = twilio_iam_api_key.api_key.id
  item {
    key   = "Username"
    value = "Administrator"
  }
  item {
    key       = "Password"
    value     = twilio_iam_api_key.api_key.secret
    sensitive = true
  }
}
```

## Secrets Management

For more advanced secrets management, you can use a secrets management tool to
store and retrieve secrets in your workspace. For example, you can use
[HashiCorp Vault](https://www.vaultproject.io/) to inject secrets into your
workspace.

Refer to our [HashiCorp Vault Integration](../integrations/vault.md) guide for
more information on how to integrate HashiCorp Vault with Coder.

## Next steps

- [Security - best practices](../../tutorials/best-practices/security-best-practices.md)

---

# Database Encryption

Source: https://coder.com/docs/admin/security/database-encryption

# Database Encryption

By default, Coder stores external user tokens in plaintext in the database.
Database Encryption allows Coder administrators to encrypt these tokens at-rest,
preventing attackers with database access from using them to impersonate users.

## How it works

Coder allows administrators to specify
[external token encryption keys](../../reference/cli/server.md#--external-token-encryption-keys).
If configured, Coder will use these keys to encrypt external user tokens before
storing them in the database. The encryption algorithm used is AES-256-GCM with
a 32-byte key length.

Coder will use the first key provided for both encryption and decryption. If
additional keys are provided, Coder will use it for decryption only. This allows
administrators to rotate encryption keys without invalidating existing tokens.

The following database fields are currently encrypted:

- `user_links.oauth_access_token`
- `user_links.oauth_refresh_token`
- `external_auth_links.oauth_access_token`
- `external_auth_links.oauth_refresh_token`
- `crypto_keys.secret`
- `user_secrets.value`

Additional database fields may be encrypted in the future.

### Implementation notes

Each encrypted database column `$C` has a corresponding
`$C_key_id` column. This column is used to determine which encryption key was
used to encrypt the data. This allows Coder to rotate encryption keys without
invalidating existing tokens, and provides referential integrity for encrypted
data.

The `$C_key_id` column stores the first 7 bytes of the SHA-256 hash of the
encryption key used to encrypt the data.

Encryption keys in use are stored in `dbcrypt_keys`. This table stores a
record of all encryption keys that have been used to encrypt data. Active keys
have a null `revoked_key_id` column, and revoked keys have a non-null
`revoked_key_id` column. You cannot revoke a key until you have rotated all
values using that key to a new key.

## Enabling encryption

> [!NOTE]
> Enabling encryption does not encrypt all existing data. To encrypt
> existing data, see [rotating keys](#rotating-keys) below.

- Ensure you have a valid backup of your database. **Do not skip this step.** If
  you are using the built-in PostgreSQL database, you can run
  [`coder server postgres-builtin-url`](../../reference/cli/server_postgres-builtin-url.md)
  to get the connection URL.

- Generate a 32-byte random key and base64-encode it. For example:

```shell
dd if=/dev/urandom bs=32 count=1 | base64
```

- Store this key in a secure location (for example, a Kubernetes secret):

```shell
kubectl create secret generic coder-external-token-encryption-keys --from-literal=keys=<key>
```

- In your Coder configuration set `CODER_EXTERNAL_TOKEN_ENCRYPTION_KEYS` to a
  comma-separated list of base64-encoded keys. For example, in your Helm
  `values.yaml`:

```yaml
coder:
  env:
    [...]
    - name: CODER_EXTERNAL_TOKEN_ENCRYPTION_KEYS
      valueFrom:
        secretKeyRef:
          name: coder-external-token-encryption-keys
          key: keys
```

- Restart the Coder server. The server will now encrypt all new data with the
  provided key.

## Rotating keys

We recommend only having one active encryption key at a time normally. However,
if you need to rotate keys, you can perform the following procedure:

- Ensure you have a valid backup of your database. **Do not skip this step.**

- Generate a new encryption key following the same procedure as above.

- Add the above key to the list of
  [external token encryption keys](../../reference/cli/server.md#--external-token-encryption-keys).
  **The new key must appear first in the list**. For example, in the Kubernetes
  secret created above:

```yaml
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: coder-external-token-encryption-keys
  namespace: coder-namespace
data:
  keys: <new-key>,<old-key1>,<old-key2>,...
```

- After updating the configuration, restart the Coder server. The server will
  now encrypt all new data with the new key, but will be able to decrypt tokens
  encrypted with the old key(s).

- To re-encrypt all encrypted database fields with the new key, run
  [`coder server dbcrypt rotate`](../../reference/cli/server_dbcrypt_rotate.md).
  This command will re-encrypt all tokens with the specified new encryption key.
  We recommend performing this action during a maintenance window.

  This command requires direct access to the database.
  If you are using the built-in PostgreSQL database, you can run
  [`coder server postgres-builtin-url`](../../reference/cli/server_postgres-builtin-url.md)
  to get the connection URL.

- Once the above command completes successfully, remove the old encryption key
  from Coder's configuration and restart Coder once more. You can now safely
  delete the old key from your secret store.

## Disabling encryption

To disable encryption, perform the following actions:

- Ensure you have a valid backup of your database. **Do not skip this step.**

- Stop all active coderd instances. This will prevent new encrypted data from
  being written, which may cause the next step to fail.

- Run
  [`coder server dbcrypt decrypt`](../../reference/cli/server_dbcrypt_decrypt.md).
  This command will decrypt all encrypted user tokens and revoke all active
  encryption keys.

  > [!NOTE]
  > for `decrypt` command, the equivalent environment variable for
  > `--keys` is `CODER_EXTERNAL_TOKEN_ENCRYPTION_DECRYPT_KEYS` and not
  > `CODER_EXTERNAL_TOKEN_ENCRYPTION_KEYS`. This is explicitly named differently
  > to help prevent accidentally decrypting data.

- Remove all
  [external token encryption keys](../../reference/cli/server.md#--external-token-encryption-keys)
  from Coder's configuration.

- Start coderd. You can now safely delete the encryption keys from your secret
  store.

## Deleting Encrypted Data

> [!CAUTION]
> This is a destructive operation.

To delete all encrypted data from your database, perform the following actions:

- Ensure you have a valid backup of your database. **Do not skip this step.**

- Stop all active coderd instances. This will prevent new encrypted data from
  being written.

- Run
  [`coder server dbcrypt delete`](../../reference/cli/server_dbcrypt_delete.md).
  This command will delete all encrypted user tokens and revoke all active
  encryption keys.

- Remove all
  [external token encryption keys](../../reference/cli/server.md#--external-token-encryption-keys)
  from Coder's configuration.

- Start coderd. You can now safely delete the encryption keys from your secret
  store.

## Troubleshooting

- If Coder detects that the data stored in the database was not encrypted with
  any known keys, it will refuse to start. If you are seeing this behavior,
  ensure that the encryption keys provided are correct.
- If Coder detects that the data stored in the database was encrypted with a key
  that is no longer active, it will refuse to start. If you are seeing this
  behavior, ensure that the encryption keys provided are correct and that you
  have not revoked any keys that are still in use.
- Decryption may fail if newly encrypted data is written while decryption is in
  progress. If this happens, ensure that all active coder instances are stopped,
  and retry.

## Next steps

- [Security - best practices](../../tutorials/best-practices/security-best-practices.md)

---

# Licensing

Source: https://coder.com/docs/admin/licensing

# Licensing

Some features are only accessible with a Premium license or the [AI Governance Add-On](../../ai-coder/ai-governance.md). See our
[pricing page](https://coder.com/pricing) for more details. To try paid
features, you can [request a trial](https://coder.com/trial) or
[contact sales](https://coder.com/contact).

![Licenses screen shows license information and seat consumption](../../images/admin/licenses/licenses-screen.png)

## Offline license validation

Coder license keys are signed JWTs that are validated locally using cryptographic
signatures. No outbound connection to Coder's servers is required for license
validation. This means licenses work in
[air-gapped and offline deployments](../../install/airgap.md) without any
additional configuration.

## Adding your license key

There are two ways to add a license to a Coder deployment:

<div class="tabs">

### Coder UI

1. With an `Owner` account, go to **Admin settings** > **Deployment**.

1. Select **Licenses** from the sidebar, then **Add a license**:

   ![Add a license from the licenses screen](../../images/admin/licenses/licenses-nolicense.png)

1. On the **Add a license** screen, drag your `.jwt` license file into the
   **Upload Your License** section, or paste your license in the
   **Paste Your License** text box, then select **Upload License**:

   ![Add a license screen](../../images/admin/licenses/add-license-ui.png)

### Coder CLI

1. Ensure you have the [Coder CLI](../../install/cli.md) installed.
1. Save your license key to disk and make note of the path.
1. Open a terminal.
1. Log in to your Coder deployment:

   ```shell
   coder login <access url>
   ```

1. Run `coder licenses add`:

   - For a `.jwt` license file:

     ```shell
     coder licenses add -f <path to your license key>
     ```

   - For a text string:

     ```sh
     coder licenses add -l 1f5...765
     ```

</div>

## FAQ

### Find your deployment ID

You'll need your deployment ID to request a trial or license key.

From your Coder dashboard, select your user avatar, then select the **Copy to
clipboard** icon at the bottom:

![Copy the deployment ID from the bottom of the user avatar dropdown](../../images/admin/deployment-id-copy-clipboard.png)

### How we calculate license seat consumption

Licenses are consumed based on the status of user accounts.
Only users who have been active in the last 90 days consume license seats.

Consult the [user status documentation](../users/index.md#user-status) for more information about active, dormant, and suspended user statuses.

---

# Run AI Coding Agents in Coder

Source: https://coder.com/docs/ai-coder

# Run AI Coding Agents in Coder

Learn how to run & manage coding agents with Coder, both alongside existing
workspaces and for background task execution.

## Agents in the IDE

Coder [integrates with IDEs](../user-guides/workspace-access/index.md) such as
Cursor, Windsurf, and Zed that include built-in coding agents to work alongside
developers. Additionally, template admins can
[pre-install extensions](https://registry.coder.com/modules/coder/vscode-web)
for agents such as GitHub Copilot and Roo Code.

These agents work well inside existing Coder workspaces as they can simply be
enabled via an extension or are built-into the editor.

## Coder Agents

In cases where the IDE is secondary, such as prototyping, research, or
long-running background jobs, [Coder Agents](./agents/index.md) is the
recommended way to delegate development work to coding agents in your Coder
deployment.

Coder Agents is a native AI coding agent built into Coder. The agent loop runs
in the Coder control plane on your infrastructure rather than inside the
workspace, so workspaces can be completely network isolated. Developers
interact with agents through the web UI, the CLI (`coder agents`), or the
REST API.

![Coder Agents chat interface with git diff sidebar](../images/agents-hero-image.png)

[Learn more about Coder Agents](./agents/index.md) for architecture details,
supported LLM providers, and how to get started.

## Govern AI activity with the AI Governance Add-On

AI coding tools are quickly becoming core to how engineering teams ship
software. As adoption grows, platform teams want a clear picture of how AI is
being used, consistent guardrails across teams, and predictable cost controls
so they can confidently scale AI tooling to the whole organization.

The [AI Governance Add-On](./ai-governance.md) is a per-user license that adds
observability, management, and policy controls for AI tooling across your
Coder deployment. It includes:

- [AI Gateway](./ai-gateway/index.md) for centralized authentication, audit
  trails of prompts and tool invocations, and policy enforcement against
  upstream LLM providers.
- [Agent Firewall](./agent-firewall/index.md) for process-level network and
  command policies that restrict what agents can reach and do inside a
  workspace.
- Expanded Agent Workspace Build allowances for teams running AI-driven
  background work at scale.

[Learn more about the AI Governance Add-On](./ai-governance.md) for use cases,
entitlements, and how to enable it in your deployment.

---

# Best Practices

Source: https://coder.com/docs/ai-coder/best-practices

# Best Practices

This document includes a mix of cultural and technical best practices and guidelines for introducing AI agents into your organization.

## Identify Use Cases

To successfully implement AI coding agents, identify 3-5 practical use cases where AI tools can deliver real value. Additionally, find a target group of developers and projects that are the best candidates for each specific use case.

Below are common scenarios where AI coding agents provide the most impact, along with the right tools for each use case:

| Scenario                                       | Description                                                                                                               | Examples                                                                                                             | Tools                                                                                                        |
|------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| **Automating actions in the IDE**              | Supplement tedious development with agents                                                                                | Small refactors, generating unit tests, writing inline documentation, code search and navigation                     | [IDE Agents](./ide-agents.md) in Workspaces                                                                  |
| **Developer-led investigation and setup**      | Developers delegate research and initial implementation to AI, then take over in their preferred IDE to complete the work | Bug triage and analysis, exploring technical approaches, understanding legacy code, creating starter implementations | [Coder Agents](./agents/index.md), to a full IDE with [Workspaces](../user-guides/workspace-access/index.md) |
| **Prototyping & Business Applications**        | User-friendly interface for engineers and non-technical users to build and prototype within new or existing codebases     | Creating dashboards, building simple web apps, data analysis workflows, proof-of-concept development                 | [Coder Agents](./agents/index.md)                                                                            |
| **Full background jobs & long-running agents** | Agents that run independently without user interaction for extended periods of time                                       | Automated code reviews, scheduled data processing, continuous integration tasks, monitoring and alerting             | [Coder Agents API](../reference/api/chats.md)                                                                |
| **External agents and chat clients**           | External AI agents and chat clients that need access to Coder workspaces for development environments and code sandboxing | ChatGPT, Claude Desktop, custom enterprise agents running tests, performing development tasks, code analysis         | [MCP Server](./mcp-server.md)                                                                                |

## Provide Agents with Proper Context

While LLMs are trained on general knowledge, it's important to provide additional context to help agents understand your codebase and organization.

For [Coder Agents](./agents/index.md), context comes from a few complementary places. Platform admins configure a [system prompt](./agents/platform-controls/index.md) that applies to every chat and register [MCP servers](./agents/platform-controls/mcp-servers.md) once for the whole deployment. Repos and workspace templates can ship reusable [skills](./agents/extending-agents.md) under `.agents/skills/`, which the agent discovers automatically when it attaches to the workspace. Developers don't need to manage memory files or wire up tools themselves.

The rest of this section covers patterns for agents you run yourself inside a workspace, such as Claude Code or Codex.

### Memory

Coding Agents like Claude Code often refer to a [memory file](https://docs.anthropic.com/en/docs/claude-code/memory) in order to gain context about your repository or organization.

Look up the docs for the specific agent you're using to learn more about how to provide context to your agents.

### Tools (Model Context Protocol)

Agents can also use tools, often via [Model Context Protocol](https://modelcontextprotocol.io/introduction) to look up information or perform actions. A common example would be fetching style guidelines from an internal wiki, or looking up the documentation for a service within your catalog.

Look up the docs for the specific agent you're using to learn more about how to provide tools to your agents.

#### Our Favorite MCP Servers

In internal testing, we have seen significant improvements in agent performance when these tools are added via MCP.

- [Playwright](https://github.com/microsoft/playwright-mcp): Instruct your agent
  to open a browser, and check its work by viewing output and taking
  screenshots.
- [desktop-commander](https://github.com/wonderwhy-er/DesktopCommanderMCP):
  Instruct your agent to run long-running tasks (e.g. `npm run dev`) in the background instead of blocking the main thread.

## Security & Permissions

LLMs and agents can be dangerous if not run with proper boundaries. Be sure not to give agents full permissions on behalf of a user, and instead use separate identities with limited scope whenever interacting autonomously.

[Learn more about securing AI agents](./security.md)

## Keep it Simple

Today's LLMs and AI agents are not going to refactor entire codebases with production-grade code on their own! Using coding agents can be extremely fun and productive, but it is important to keep the scope of your use cases small and simple, and grow them over time.

---

# In the IDE

Source: https://coder.com/docs/ai-coder/ide-agents

Learn how to use Coder Workspaces with IDEs and plugins to run coding agents like Cursor, GitHub Copilot, Windsurf, RooCode, and more.

## How it works

Coder Workspaces are full development environments that run on your cloud infrastructure, such as Kubernetes or AWS EC2. Developers can connect with their favorite IDEs with pre-configured extensions and configuration for agentic coding.

![Workspace Page](../images/guides/ai-agents/workspace-page.png)

## Coder versus Local Development

Running coding agents in Coder workspaces provides several advantages over running them locally:

- **Fast, out-of-the-box setup**: LLMs, proxies, and MCP tools can be pre-configured for developers to use immediately, eliminating setup time and configuration hassles.
- **Consistent environments**: All developers use the same standardized environments, ensuring consistent access to tools and resources.
- **Resource optimization**: Leverage powerful cloud resources without taxing local machines.
- **Security and isolation**: Keep sensitive code, API keys, and secrets in controlled environments.

[Learn more about Coder](https://coder.com/cde/compare)

## IDE Support

Follow the Coder Documentation for [Connecting to Workspaces](../user-guides/workspace-access/index.md) to connect to your Coder Workspaces with your favorite IDEs.

## Pre-Configuring Extensions &amp; Plugins

Read our [VS Code module documentation](https://registry.coder.com/modules/coder/vscode-web) for examples on how to pre-install plugins like GitHub Copilot, RooCode, Sourcegraph Cody, and more in Coder workspaces.

---

# Coder Agents

Source: https://coder.com/docs/ai-coder/agents

# Coder Agents

Coder Agents is a chat interface and API for delegating development work and research to coding agents in your Coder deployment. Developers describe the work they want done, and Coder Agents handles selecting a template, provisioning a workspace, and executing the task.

Coder Agents includes its own self-hosted AI coding
agent that runs the agent loop directly within the Coder control plane.

No specialized software, API keys, or network access is required inside your workspace. The only requirement is network access between the control plane and external LLM providers.

<video autoplay playsinline loop>
  <source src="https://raw.githubusercontent.com/coder/coder/refs/heads/main/docs/images/guides/ai-agents/coder-agents-ui.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

## What Coder Agents is and isn't

It is a standalone agent written in Go that implements standard
agentic patterns — sub-agent delegation, context compaction, file editing, and
shell execution — and works with any LLM provider you configure.

It is not a wrapper around third-party agent tools like Claude Code
or Codex.

Coder Agents is not a replacement for your text editor or IDE. It is the
primary interface where developers work with and orchestrate coding agents.
Developers still connect to workspaces via VS Code, Cursor, JetBrains, or any
other editor to review, refine, and complete work that the agent produces.

## Who Coder Agents is for

Coder Agents is designed for organizations that need to self-host their AI
coding workflows and maintain full control over how agents operate. It is a
strong fit for:

- **Regulated industries** such as financial services, healthcare, and
  government, where AI tools must run on controlled infrastructure with
  auditable access and strict network boundaries.
- **Platform engineering teams** that want to provide developers with a
  high-quality AI coding experience without managing per-workspace agent
  installations, API key distribution, or third-party agent licensing.
- **Organizations with existing Coder deployments** that want to add agentic
  capabilities using their current templates, workspaces, and identity
  providers rather than adopting a separate SaaS product.

Coder Agents runs entirely self-hosted. There is no SaaS or managed component — the agent
loop, chat history, and all tool execution happen within your Coder deployment.

## How it works

The agent loop runs inside [the control plane](./architecture.md). When a user
submits a prompt, the control plane:

1. Sends the prompt to the configured LLM provider (Anthropic, OpenAI, Google,
   Azure, AWS Bedrock, or any OpenAI-compatible endpoint).
1. Receives the model's response, which may include tool calls such as reading
   files, writing code, or running shell commands.
1. Executes tool calls by connecting to a Coder workspace over the existing
   workspace connection — the same path used for web terminals, port
   forwarding, and IDE access.
1. Returns tool results to the model and continues the loop until the task is
   complete.

The workspace itself has no knowledge of AI. It is standard compute
infrastructure — there are no LLM API keys, no agent harnesses, and no special
software installed. All intelligence lives in the control plane.

<img src="../../images/guides/ai-agents/agent-loop.png" alt="Architecture diagram showing the control plane in the center, with arrows out to LLM providers and arrows to workspaces">

<small>The agent loop runs in the control plane. It makes outbound requests to LLM
providers and connects to workspaces only when tool execution is needed.</small>

### Automatic workspace provisioning

Not every chat requires a workspace. The agent runs in the control plane and can
answer questions, discuss architecture, or plan an approach without any
infrastructure. Workspaces are only provisioned when the agent needs to take
action — reading code, running commands, or editing files.

This means:

- **Faster responses** — conversations that don't require workspace access
  start immediately with no provisioning delay.
- **Lower infrastructure cost** — workspaces are only created when the agent
  needs to do real development work.

When a workspace _is_ needed, the agent reads the templates available to that user —
including their descriptions and parameters — selects the appropriate one, and
creates a workspace automatically. Template visibility is scoped to the user's role and permissions, so the agent can only select templates the user is authorized to use. Users can also manually choose which workspace is used when starting a new chat.

Platform teams control template routing by writing clear template descriptions.
For example, a description like "Use this template for Python backend services
in the payments repo" helps the agent select the correct infrastructure.

**Examples of what triggers workspace creation:**

| No workspace needed                                  | Workspace provisioned                                    |
|------------------------------------------------------|----------------------------------------------------------|
| "What are the tradeoffs between REST and gRPC?"      | "Find and fix the nil pointer crash in the auth service" |
| "Help me draft an RFC for adding a caching layer"    | "Run the test suite and fix any failures"                |
| "What's the best way to handle retry logic in Go?"   | "Refactor the handler to use the new SDK types"          |
| "Compare connection pooling strategies for Postgres" | "Read the config file and add the new feature flag"      |

### Sub-agents

Coder Agents supports sub-agent delegation. The root agent can spawn child
agents to work on independent tasks in parallel. Each sub-agent gets its own
context window, which keeps individual conversations focused and avoids the
quality degradation that occurs as context windows grow large.

For example, an agent tasked with "explore this repository and document its
structure" might spawn separate sub-agents to analyze the backend, frontend,
and infrastructure directories simultaneously.

### Chat persistence

All chat state is stored in the Coder database, not in the workspace. If a
workspace is stopped, deleted, or rebuilt, the full conversation history
survives. The agent can resume work by creating a new workspace with the same
template and continuing from the last known state, such as a git branch.

### Message queuing

Users can send follow-up messages while the agent is actively working. Messages
are queued and delivered when the agent completes its current step, so there is
no need to wait for a response before providing additional context or changing
direction.

### Image attachments

Users can attach images to chat messages by pasting from the clipboard, dragging
files into the input area, or using the attachment button. Supported formats are
PNG, JPEG, GIF, and WebP up to 10 MB per file. Images are sent to the model as
multimodal content alongside the text prompt.

This is useful for sharing screenshots of errors, UI mockups, terminal output,
or other visual context that helps the agent understand the task. Messages can
contain images alone or combined with text. Image attachments require a model
that supports vision input.

## Security benefits of the control plane architecture

Running the agent loop in the control plane rather than inside the developer
workspace is an architectural decision that directly addresses the primary
concerns regulated organizations have with AI coding tools: how do you give
developers access to coding agents without introducing unnecessary risk?

Traditionally, agents run inside the same compute where code
lives. This means the agent needs LLM API keys in the workspace, outbound
network access to model providers, and often elevated permissions. In a
regulated environment, this creates a surface area that is difficult to lock
down.

Coder Agents eliminates this by moving the agent loop out of the workspace
entirely:

- **No API keys in workspaces.** LLM provider credentials never enter the
  workspace. The control plane makes all outbound requests to model providers
  directly, so there is nothing for a developer or a compromised process to
  exfiltrate.
- **No agent software to manage.** Workspaces don't need Claude Code, Codex,
  or any agent harness installed. This eliminates a class of supply chain risk
  and removes the need to keep agent software up to date across all workspaces.
- **Network boundaries are simpler.** Because the workspace doesn't need access
  to LLM APIs, you can apply strict egress rules. An agent-only template might
  permit access to only your git provider (e.g., `github.com`) and nothing
  else. The workspace never needs to reach the internet for AI functionality.
- **Centralized, enforced control.** Platform teams configure models, system
  prompts, and tool permissions from the control plane. These settings are
  enforced server-side — they are not user preferences that developers can
  override.
- **User identity is always attached.** Every action the agent takes — PRs
  opened, code pushed, commands run — is tied to the user who submitted the
  prompt. There is no shared bot identity or anonymous execution.
- **No privilege escalation.** The agent operates with the exact same
  permissions as the user who submitted the prompt. If a developer cannot
  access a template, workspace, or resource through the Coder dashboard,
  the agent cannot access it either. There is no escalation of privileges
  and no shared service account.
- **Workspace isolation is preserved.** The agent can only access workspaces
  owned by the user who submitted the prompt. There is no cross-user
  workspace access — an agent running on behalf of one developer cannot
  read files, execute commands, or interact with another developer's
  workspaces.

> [!TIP]
> For highly sensitive environments, create a dedicated set of templates for
> agent workloads with stricter network policies than your standard developer
> templates. Because the AI comes from the control plane, these templates don't
> need any outbound access to LLM providers.

<!-- break between callouts -->

> [!WARNING]
> By default, agent workspaces have the same network access and permissions
> as any workspace the user creates manually. If your templates do not
> restrict outbound network access, the agent has full internet access from
> the workspace. See [Template Optimization](./platform-controls/template-optimization.md)
> for guidance on configuring network boundaries and scoping credentials for
> agent workloads.

## LLM provider support

Coder Agents works with any LLM provider. Administrators configure providers
and models from the Coder dashboard or API. Supported providers include:

| Provider          | Description                              |
|-------------------|------------------------------------------|
| Anthropic         | Claude models via Anthropic API          |
| OpenAI            | GPT and Codex models via OpenAI API      |
| Google            | Gemini models via Google AI API          |
| Azure OpenAI      | OpenAI models hosted on Azure            |
| AWS Bedrock       | Models available through AWS Bedrock     |
| OpenAI Compatible | Any endpoint implementing the OpenAI API |
| OpenRouter        | Multi-model routing via OpenRouter       |
| Vercel AI Gateway | Models via Vercel AI SDK                 |

Most providers support custom base URLs, which allows integration with
enterprise LLM proxies, self-hosted model endpoints, and internal gateways.

Administrators can configure multiple providers simultaneously and set a default
model. Developers select from enabled models when starting a chat.

<img src="../../images/guides/ai-agents/llm-providers.png" alt="Screenshot of the provider/model configuration in the Agents settings">

<small>The model configuration in the Agents settings panel.</small>

## Built-in tools

The agent has access to a set of workspace tools that it uses to accomplish
tasks:

| Tool                                        | Description                                                              |
|---------------------------------------------|--------------------------------------------------------------------------|
| `list_templates`                            | Browse available workspace templates                                     |
| `read_template`                             | Get template details and configurable parameters                         |
| `create_workspace`                          | Create a workspace from a template                                       |
| `start_workspace`                           | Start a stopped workspace for the current chat                           |
| `propose_plan`                              | Present a Markdown plan file for user review                             |
| `ask_user_question`                         | Ask the user structured clarification questions during plan mode         |
| `read_file`                                 | Read file contents from the workspace                                    |
| `write_file`                                | Write a file to the workspace                                            |
| `edit_files`                                | Perform search-and-replace edits across files                            |
| `execute`                                   | Run shell commands in the workspace                                      |
| `process_output`                            | Retrieve output from a background process                                |
| `process_list`                              | List all tracked processes in the workspace                              |
| `process_signal`                            | Send a signal (terminate/kill) to a tracked process                      |
| `attach_file`                               | Attach a workspace file to the chat as a durable downloadable attachment |
| `spawn_agent` (`type=general` or `explore`) | Delegate a task to a sub-agent running in parallel                       |
| `wait_agent`                                | Wait for a sub-agent to complete and collect its result                  |
| `message_agent`                             | Send a follow-up message to a running sub-agent                          |
| `close_agent`                               | Stop a running sub-agent                                                 |
| `spawn_agent` (`type=computer_use`)         | Spawn a sub-agent with desktop interaction (screenshot, mouse, keyboard) |
| `read_skill`                                | Read the instructions for a workspace skill by name                      |
| `read_skill_file`                           | Read a supporting file from a skill's directory                          |
| `web_search`                                | Search the internet (provider-native, when enabled)                      |

These tools connect to the workspace over the same secure connection used for
web terminals and IDE access. No additional ports or services are required in
the workspace.

Platform tools (`list_templates`, `read_template`, `create_workspace`,
`start_workspace`, `propose_plan`, `ask_user_question`) and orchestration tools (`spawn_agent`,
`wait_agent`, `message_agent`, `close_agent`)
are only available to root chats. Sub-agents do not have access to these
tools and cannot create workspaces or spawn further sub-agents.

`spawn_agent` with `type=computer_use` additionally requires an
Anthropic or OpenAI provider and the virtual desktop feature to be
enabled by an administrator.
`read_skill` and `read_skill_file` are available when the workspace contains
skills in its `.agents/skills/` directory.

`propose_plan` and `ask_user_question` are only available while plan mode is
active. In plan mode, the agent can still inspect the workspace and template
metadata, execute shell commands for exploration, and read process output.
`write_file` and `edit_files` remain available only for the chat-specific plan
file under `.coder/plans/`. MCP, dynamic, provider-native, and computer-use
tools are blocked.

## Plan mode

Plan mode lets you ask the agent to investigate first and present a plan before
implementation. Open the chat input menu and choose **Plan first** to enable it
for the current chat. After you enable it, later turns in that chat stay in
plan mode until you turn it off or click **Implement plan** after a proposed
plan. Because the mode is stored on the chat, reloading the page preserves the
current setting.

While plan mode is active:

- the agent can inspect repository files, workspace state, and available
  templates
- `write_file` and `edit_files` can only modify the chat-specific plan file
  under `.coder/plans/`
- `ask_user_question` can gather structured clarification from the user before
  a plan is proposed
- `propose_plan` snapshots the current plan file into the transcript so you can
  review it before implementation starts
- `execute` and `process_output` remain available for exploration, such as
  cloning repositories, searching code, and running inspection commands
- MCP tools, dynamic tools, provider-native tools, and computer-use tools are
  not available

This keeps planning turns focused on analysis and plan authoring rather than
implementation. Once you click **Implement plan**, the next turn runs in normal
mode again.

## Comparison to Coder Tasks

Coder Agents is a new approach that differs from
[Coder Tasks](../tasks.md) in several ways:

| Aspect              | Coder Agents                         | Coder Tasks                                                    |
|---------------------|--------------------------------------|----------------------------------------------------------------|
| Agent execution     | Runs in the control plane            | Runs inside the workspace                                      |
| Agent harness       | Built-in, no installation needed     | Requires Claude Code, Codex, or similar installed in workspace |
| API keys            | Stored in control plane only         | Injected into workspace environment                            |
| Chat state          | Persisted in database                | Stored in workspace                                            |
| Workspace selection | Automatic, based on task description | Manual, user selects template                                  |
| Sub-agents          | Built-in parallel delegation         | Not supported                                                  |
| Modern chat UI      | Native chat with diffs, queuing      | Terminal-based interface                                       |

## Product status

Coder Agents is in Beta. The feature is under active development and
available for evaluation.

---

# Getting Started

Source: https://coder.com/docs/ai-coder/agents/getting-started

# Getting Started

This guide walks platform teams and administrators through setting up Coder
Agents, preparing your deployment, and running your first Coder Agent.

> [!NOTE]
> Coder Agents is in Beta. APIs, behavior, and configuration may change
> between releases without notice; pin a release before broad rollout.
> Use **Coder version 2.33.1 or greater**.

## Prerequisites

Before you begin, confirm the following:

- **Coder deployment** running the latest release.
- **LLM provider credentials** — an API key for at least one
  [supported provider](./models.md) (Anthropic, OpenAI, Google, Azure OpenAI,
  AWS Bedrock, OpenAI Compatible, OpenRouter, or Vercel AI Gateway).
- **Network access** from the control plane to your LLM provider. Workspaces
  do not need LLM access — only the control plane does.
- **At least one template** with a
  [descriptive name and description](./platform-controls/template-optimization.md)
  for the agent to select when provisioning workspaces.
- **Admin access** to the Coder deployment for configuring providers.
- **Coder Agents User role** assigned to each user who needs to interact with Coder Agents.
  This role is granted **per organization**. Owners and organization admins can
  assign it from **Admin settings** > **Organizations** > _[your organization]_ >
  **Members**. See [Grant Coder Agents User](#step-2-grant-coder-agents-user)
  below.

## Step 1: Configure an LLM provider and model

> [!IMPORTANT]
> Configuring providers, models, and system prompts requires the
> **Owner** role (Coder administrator). Non-admin users cannot access the
> admin Settings panel or modify deployment-level Agents configuration.

To configure Coder Agents:

1. Navigate to the **Agents** page in the Coder dashboard.
1. Open **Settings** > **Manage Agents** and select the **Providers** tab.
   Pick a provider, enter your API key, and save.
1. Switch to the **Models** tab, click **Add**, and configure at least one
   model with its identifier, display name, and context limit.
1. Click the **star icon** next to a model to set it as the default.

Detailed instructions for each provider and model option are in the
[Models](./models.md) documentation.

> [!TIP]
> Start with a single frontier model to validate your setup before adding
> additional providers.

## Step 2: Grant Coder Agents User

The **Coder Agents User** role controls which users can interact with Coder
Agents. The role is assigned **per organization**, so a user must be granted
it in each organization where they need access. Members do not have it by
default.

Owners always have full access and do not need the role. Repeat the following
steps for each user who needs access in each organization.

**Dashboard (individual):**

1. Open **Admin settings** > **Organizations** in the Coder dashboard, then
   select the organization where you want to grant access.
1. The **Members** tab opens by default. Find the user in the table.
1. Click the **Roles** cell for that user to open the role editor.
1. Toggle on **Coder Agents User** and save.

> [!TIP]
> If your deployment has multiple organizations, repeat this for each
> organization where the user needs access.

**CLI (bulk, per organization):**

Granting the role via CLI is org-scoped. The `edit-roles` command **replaces**
the member's full set of org roles, so include every role you want them to
keep. To grant `agents-access` to a single user while preserving their
existing org roles:

```sh
ORG="my-org"
USER="alice"
ROLES=$(coder organizations members list -O "$ORG" -o json \
  | jq -r --arg user "$USER" \
      '.[] | select(.username == $user) | [.roles[].name, "agents-access"]
      | unique | join(" ")')
# shellcheck disable=SC2086
coder organizations members edit-roles "$USER" -O "$ORG" $ROLES
```

To grant the role to every member of an organization while preserving their
existing roles:

```sh
ORG="my-org"
coder organizations members list -O "$ORG" -o json \
  | jq -c '.[] | {user_id, roles: [.roles[].name]}' \
  | while read -r row; do
      user_id=$(echo "$row" | jq -r '.user_id')
      roles=$(echo "$row" | jq -r '(.roles + ["agents-access"]) | unique | join(" ")')
      # shellcheck disable=SC2086
      coder organizations members edit-roles "$user_id" -O "$ORG" $roles
    done
```

You can also set the organization with the `CODER_ORGANIZATION` environment
variable instead of `-O`.

## Step 3: Start your first Coder Agent

1. Go to the **Agents** page in the Coder dashboard.
1. Select a model from the dropdown (your default will be pre-selected).
1. Type a prompt and send it.

The agent processes the prompt in the control plane. If the task requires
a workspace — reading files, running commands, editing code — the agent
selects a template and provisions one automatically. Conversations that
don't require compute (planning, Q&A, architecture discussions) start
immediately with no provisioning delay.

## Optimize your templates

The agent selects templates based on their **name and description** — it does
not read Terraform. Clear, specific descriptions are the most important factor
in whether the agent picks the right template.

Update your template descriptions to include:

- The language, framework, or stack the template targets.
- Which repository or service it is for, if applicable.
- What type of work it supports (backend, frontend, data pipeline, etc.).

**Good examples:**

| Description                                                                                 | Why it works                                 |
|---------------------------------------------------------------------------------------------|----------------------------------------------|
| Python backend services for the payments repo. Includes Poetry, Python 3.12, and PostgreSQL | Specific language, repo, and toolchain       |
| React frontend development for the customer portal. Node 20, pnpm, Storybook pre-installed  | Clear stack, named project, key tools listed |
| General-purpose Go development environment with Go 1.23, Docker, and common CLI tools       | Broad but descriptive                        |

**Descriptions to avoid:**

| Description        | Problem                                         |
|--------------------|-------------------------------------------------|
| Team A template v2 | No information about what the template is for   |
| Dev environment    | Too generic to distinguish from other templates |
| Default            | Tells the agent nothing                         |

See [Template Optimization](./platform-controls/template-optimization.md) for
the full guide, including dedicated agent templates, network boundaries,
credential scoping, and pre-installing dependencies.

## Things to know before you start

### Plan for change between releases

Coder Agents is under active development. APIs, behavior, and
configuration may change between releases without notice. Pin a
specific release before broad rollout and review the release notes
before upgrading so changes do not surprise developers in production.

### Use HTTPS for push notifications

Coder Agents use browser push notifications to alert you when a task
completes or needs attention. Most browsers require a secure (HTTPS)
origin for the [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API)
to work. If your access URL uses plain HTTP,
push notifications may not function.

This does not affect agents themselves — only the browser notification
delivery. If you terminate TLS at a reverse proxy, ensure the
[access URL](../../admin/setup/index.md) is configured with an `https://` scheme.

### Set a deployment-wide system prompt

Administrators can set a system prompt that applies to all Coder Agents across the
deployment. Use this to encode organizational conventions:

- Coding standards and style guidelines.
- Commit message formats.
- Branch naming conventions.
- Required review processes before merging.
- Any guardrails specific to your environment.

Configure the system prompt from **Agents** > **Settings** >
**Manage Agents** > **Instructions**
or via the API at `PUT /api/experimental/chats/config/system-prompt`.
See [Platform Controls](./platform-controls/index.md) for details.

### Understand the security model

The agent runs in the control plane, not inside workspaces. This means:

- **No LLM API keys in workspaces.** Credentials stay in the control plane.
- **No agent software in workspaces.** No supply chain risk from
  third-party agent tools.
- **User identity is always attached.** Every action is tied to the user
  who submitted the prompt — no shared bot accounts.
- **No privilege escalation.** The agent has exactly the same permissions
  as the prompting user.

Agent workspaces inherit the same network access as any manually created
workspace. If your templates don't restrict egress, the agent has full
internet access from the workspace. Consider
[creating dedicated agent templates](./platform-controls/template-optimization.md#create-dedicated-agent-templates)
with tighter network policies.

### Plan for LLM costs

Every conversation turn sends tokens to your LLM provider. Long-running tasks,
sub-agent delegation, and complex multi-step work can consume significant
token volume. Consider:

- Starting with a single model to establish a cost baseline.
- Setting per-model token pricing under **Agents** > **Settings** >
  **Manage Agents** > **Models** (Input Price, Output Price) to track spend.
- Monitoring provider dashboards for usage trends during the evaluation.

### Pilot with a small group

Identify 3–5 developers and a few concrete use cases for the initial rollout.
Good starting points:

- **Low-risk, high-visibility tasks** — generating unit tests, writing inline
  documentation, small refactors.
- **Investigation and triage** — exploring unfamiliar code, triaging bugs,
  understanding legacy systems.
- **Prototyping** — building proof-of-concept implementations, simple
  dashboards, internal tools.

Set expectations that this is an evaluation period. Developers should still
review all agent-produced code before merging. The agent is a force
multiplier, not a replacement for developer judgment.

### Use the API for programmatic automation

The [Chats API](../../reference/api/chats.md) enables programmatic access to Coder Agents.
This is useful for building automations such as:

- Triggering Coder Agents from CI/CD pipelines when builds fail.
- Creating Coder Agents from GitHub webhooks on new issues or PRs.
- Building internal tools or dashboards on top of the API.
- Scripting batch operations across repositories.

**Quick example — create a Coder Agent via the API:**

```sh
curl -X POST https://coder.example.com/api/experimental/chats \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [
      {"type": "text", "text": "Fix the failing tests in the auth service"}
    ]
  }'
```

Stream updates in real time by connecting to the WebSocket endpoint:

```text
GET /api/experimental/chats/{chat}/stream
```

For service-to-service automation, use
[API keys](../../admin/users/sessions-tokens.md)
rather than developer session tokens. Keep automation credentials
narrowly scoped.

> [!NOTE]
> The Chats API is in beta and may change without notice.
> See [Chats API](../../reference/api/chats.md) for the full endpoint reference.

### Add workspace context with AGENTS.md

Create an `AGENTS.md` file in the home directory (`~/.coder/AGENTS.md`) or
the workspace agent's working directory to provide persistent context to the
agent. This file is automatically read and included in the system prompt
for every conversation with a Coder Agent that uses that workspace.

Use it for:

- Repository-specific build and test instructions.
- Important architectural decisions or constraints.
- Links to relevant documentation or runbooks.
- Any context that helps the agent work effectively in that codebase.

### Consider prebuilt workspaces for faster startup

Workspace provisioning is the main source of latency when the agent starts a
task. If your templates take more than a minute to provision, consider
configuring
[prebuilt workspaces](../../admin/templates/extending-templates/prebuilt-workspaces.md)
to maintain a pool of ready-to-use workspaces. The agent gets assigned an
already-running workspace instead of provisioning from scratch.

## Providing feedback

Coder Agents is a collaborative evaluation between your team and Coder.
Share feedback — workflow observations, feature requests, bugs, performance
issues, or operational challenges — through your **customer-specific Slack
channel** with the Coder team.

Good feedback includes:

- **What you tried** — the prompt, the template, and the model.
- **What happened** — the agent's behavior, any errors, unexpected results.
- **What you expected** — the outcome you were looking for.
- **Context** — screenshots, `chat_id` values, or links to the Agents page help
  the team investigate quickly.

Your input directly influences product direction during Beta.

## Next steps

- [Architecture](./architecture.md) — how the control plane, LLM providers,
  and workspaces interact.
- [Models](./models.md) — configure additional providers and models.
- [Platform Controls](./platform-controls/index.md) — system prompts,
  template routing, and admin-level configuration.
- [Template Optimization](./platform-controls/template-optimization.md) —
  create agent-friendly templates with network boundaries and scoped
  credentials.
- [Chats API](../../reference/api/chats.md): build programmatic integrations.

---

# Architecture

Source: https://coder.com/docs/ai-coder/agents/architecture

# Architecture

Coder's AI agent interacts with workspaces over the same
connection path as a developer's IDE, web terminal, and SSH session already
use. There is no sidecar process and no new network paths. If your developers
can already connect to their workspaces, the agent can too.

## Architecture at a glance

Three components are involved in every agent interaction:

1. **The control plane** runs the agent loop. It receives prompts, streams them
   to the LLM provider, interprets tool calls, and dispatches them to
   workspaces.
1. **The LLM provider** (Anthropic, OpenAI, Google, Azure, AWS Bedrock, or any
   OpenAI-compatible endpoint) performs model inference. It never communicates
   with the workspace directly.
1. **The workspace** is standard compute infrastructure. It runs shell commands,
   reads and writes files, and executes processes — exactly what occurs when a
   developer connects via their IDE.

<img src="../../images/guides/ai-agents/agent-loop-detailed.png" alt="Architecture diagram">

## The same connection your IDE uses

This is the key architectural insight: the agent reaches into a workspace
over the same Tailnet tunnel that a developer's tools already use.

When a developer opens a web terminal in the Coder dashboard, connects via
VS Code Remote, or runs `coder ssh`, the traffic follows this path:

1. The client connects to the control plane.
1. The control plane routes the connection through its internal Tailnet node.
1. The connection reaches the workspace daemon over a DERP relay or
   direct peer-to-peer link.
1. The workspace daemon handles the request — spawning a shell,
   forwarding a port, or serving a file.

When the agent executes a tool call — reading a file, running a command,
writing code — it follows the same tunnel:

1. The agent loop in the control plane issues a tool call.
1. The control plane routes the call through its internal Tailnet node.
1. The call reaches the workspace daemon over the same DERP relay or
   peer-to-peer link.
1. The workspace daemon handles the request via its HTTP API — reading a file,
   starting a process, or writing content.

The underlying tunnel is identical. IDE connections use SSH, web terminals use
a WebSocket protocol, and the agent uses the workspace daemon's HTTP API — but
all three traverse the same Tailnet connection and rely on the same security
boundary. No additional ports or network paths are introduced.

### No inbound ports

The workspace daemon always dials _out_ to the control plane — never
the reverse. The control plane then uses that established tunnel to reach back
in. This means:

- The workspace needs no inbound ports or exposed services.
- You can block all inbound traffic to the workspace.
- The only required outbound connection from the workspace is to the control
  plane itself.

This is unchanged from how workspaces already operate in Coder. Enabling
Coder Agents does not change your workspace network requirements.

## The agent loop

When a user submits a prompt, the control plane processes it as a background
job:

1. The prompt is saved to the database and the chat is marked `pending`.
1. The control plane picks up the chat and marks it `running`.
1. The control plane streams the conversation to the configured LLM provider.
1. The model responds with text, reasoning, or tool calls.
1. If the response includes tool calls, the control plane executes them
   (connecting to the workspace as needed) and returns the results to the model.
1. Steps 3–5 repeat until the model produces a final response with no further
   tool calls.
1. The chat is marked `waiting` for the next user message.

This loop runs inside the control plane process. There is no separate service
to deploy — it is part of the same binary that serves the dashboard and API.

### Context compaction

As conversations grow, the agent automatically summarizes older context to stay
within the model's context window. When token usage exceeds a threshold, the
agent generates a compressed summary and inserts it as a new message. Earlier
messages remain in the database and are still visible to users, but are excluded
from the model's context window. This happens transparently and keeps
long-running sessions productive.

### Message queuing

Users can send follow-up messages while the agent is actively working. Messages
are queued in the database and delivered when the agent completes its current
turn — the full sequence of steps until the model stops calling tools. There is
no need to wait for a response before providing additional context or
redirecting the agent.

## Tool execution

Tools are how the agent takes action. Each tool call from the LLM translates to
a concrete operation — either inside a workspace or within the control plane
itself.

The agent is restricted to the built-in tool set defined in this section,
plus any additional tools from workspace skills and MCP servers. Skills
provide structured instructions the agent loads on demand
(see [Extending Agents](./extending-agents.md)). MCP tools come from
admin-configured external servers
(see [MCP Servers](./platform-controls/mcp-servers.md)) and from workspace
`.mcp.json` files. The agent has no direct access to the Coder API beyond
what these tools expose and cannot execute arbitrary operations against the
control plane.

### Workspace connection lifecycle

The connection to a workspace is **lazy**. It is not established when a chat
starts — only when something needs to reach the workspace. This is typically
triggered by the first tool call that requires workspace access. Once
established, the connection is cached and reused for the duration of that chat
session.

Chats that don't need workspace access (answering questions, planning an
approach, discussing architecture) never provision or connect to a workspace.

### Workspace tools

These tools execute inside the workspace via the workspace daemon's HTTP API.
They traverse the same Tailnet tunnel used by web terminals and IDE connections.

| Tool             | What it does                                                                                                                                                                                                                                                                       |
|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `read_file`      | Reads file contents with line-number pagination.                                                                                                                                                                                                                                   |
| `write_file`     | Writes content to a file.                                                                                                                                                                                                                                                          |
| `edit_files`     | Performs atomic search-and-replace edits across one or more files.                                                                                                                                                                                                                 |
| `execute`        | Runs a shell command, waiting for completion up to a timeout.                                                                                                                                                                                                                      |
| `process_output` | Retrieves output from a tracked process.                                                                                                                                                                                                                                           |
| `process_list`   | Lists all tracked processes in the workspace.                                                                                                                                                                                                                                      |
| `process_signal` | Sends a signal (SIGTERM or SIGKILL) to a tracked process.                                                                                                                                                                                                                          |
| `attach_file`    | Attach a workspace file to the current chat so the user can download it directly from the conversation. Use this when the user should receive an artifact such as a screenshot, log, patch, or document. Pass an absolute file path. The file must already exist in the workspace. |

### Platform tools

These tools run entirely within the control plane. They do not require a
workspace connection. Platform and orchestration tools are only available to
root chats — sub-agents spawned by `spawn_agent` do not have access to them
and cannot create workspaces or spawn further sub-agents.

| Tool                | What it does                                                                            |
|---------------------|-----------------------------------------------------------------------------------------|
| `list_templates`    | Browses available workspace templates, sorted by popularity.                            |
| `read_template`     | Gets template details and configurable parameters.                                      |
| `create_workspace`  | Creates a workspace from a template and waits for it to be ready.                       |
| `start_workspace`   | Starts the chat's workspace if it is currently stopped. Idempotent if already running.  |
| `propose_plan`      | Presents a Markdown plan file from the workspace for user review before implementation. |
| `ask_user_question` | Asks the user structured clarification questions during plan mode.                      |

`propose_plan` and `ask_user_question` are only exposed while plan mode is
active. In that mode, `write_file` and `edit_files` are restricted to the
chat-specific plan file, while `execute` and `process_output` remain available
for exploration such as cloning repositories, searching code, and running
inspection commands. Root plan-mode chats may also receive administrator-approved
external MCP tools. Workspace MCP tools remain unavailable in plan mode, and
plan-mode sub-agents still do not receive any MCP tools. Dynamic,
provider-native, and computer-use tools are not available.

### Orchestration tools

These tools manage sub-agents — child chats that work on independent tasks in
parallel.

| Tool                                        | What it does                                                                                                                                                                                                                                                                     |
|---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `spawn_agent` (`type=general` or `explore`) | Delegates a task to a sub-agent with its own context window.                                                                                                                                                                                                                     |
| `wait_agent`                                | Waits for a sub-agent to finish and collects its result.                                                                                                                                                                                                                         |
| `message_agent`                             | Sends a follow-up message to a running sub-agent.                                                                                                                                                                                                                                |
| `close_agent`                               | Stops a running sub-agent.                                                                                                                                                                                                                                                       |
| `spawn_agent` (`type=computer_use`)         | Spawns a sub-agent with desktop interaction capabilities (screenshot, mouse, keyboard). Requires an administrator-configured computer-use provider (Anthropic or OpenAI) and the [virtual desktop experiment](./platform-controls/experiments.md#virtual-desktop) to be enabled. |

### Provider tools

These tools are executed server-side by the LLM provider, not by the control
plane or workspace. They are conditionally available based on the model
configuration set by an administrator.

| Tool         | What it does                                                                                                                                     |
|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| `web_search` | Searches the internet for up-to-date information. Available when web search is enabled for the configured Anthropic, OpenAI, or Google provider. |

### Workspace extension tools

These tools are conditionally available based on the workspace contents.

| Tool              | What it does                                                                                                                   |
|-------------------|--------------------------------------------------------------------------------------------------------------------------------|
| `read_skill`      | Reads the instructions for a workspace skill by name. Available when the workspace has skills discovered in `.agents/skills/`. |
| `read_skill_file` | Reads a supporting file from a skill's directory.                                                                              |

## What runs where

Understanding the split between the control plane and the workspace is central
to the security model.

| Responsibility      | Where it runs | Details                                                                   |
|---------------------|---------------|---------------------------------------------------------------------------|
| Agent loop          | Control plane | Prompt processing, tool dispatch, step iteration.                         |
| LLM inference       | LLM provider  | The control plane streams requests to the external provider.              |
| Chat state          | Control plane | All messages, token usage, and status stored in the database.             |
| Git authentication  | Control plane | Uses existing Coder external auth (GitHub, GitLab, Bitbucket).            |
| User identity       | Control plane | Every action is tied to the user who submitted the prompt.                |
| Model/prompt config | Control plane | Administrators configure providers, models, and system prompts centrally. |
| File read/write     | Workspace     | The workspace file system is the source of truth for code.                |
| Shell execution     | Workspace     | Commands run in the workspace's environment with its packages and tools.  |
| Git operations      | Workspace     | Commits, pushes, and branch management happen inside the workspace.       |
| Build and test      | Workspace     | Compilation, test suites, and dev servers run on workspace compute.       |

The workspace has **zero AI awareness**. There are no LLM API keys, no agent
processes, and no AI-specific software installed. If you inspect a workspace
created by the agent, it looks identical to one a developer created
manually.

## Chat state and persistence

All chat data is stored in the control plane database, not in the workspace.

- **Chat metadata** — status, owner, associated workspace, timestamps, and
  parent/child relationships for sub-agents.
- **Messages** — every message (user, assistant, tool calls, tool results) is
  stored as a separate record with role, content, and token usage.
- **Compressed context** — when the agent compacts the conversation, summaries
  are stored with a compression flag so the original context budget is
  preserved.
- **Queued messages** — follow-up messages sent while the agent is working are
  held in a queue and delivered in order.

Because state lives in the database:

- Chat history survives workspace stops, rebuilds, and deletions.
- An administrator can inspect any chat for audit or debugging.
- The agent can resume work by targeting a new workspace and continuing from the
  last git branch or checkpoint.

## Security posture

The control plane architecture provides built-in security properties for AI
coding workflows. These are structural guarantees, not configuration options —
they hold by default for every agent session.

### No API keys in workspaces

LLM provider credentials exist only in the control plane. The workspace never
sees them. There is nothing for a developer, a compromised dependency, or a
rogue process to exfiltrate.

### Workspaces can be fully network-isolated

Because the workspace does not need to reach any LLM provider, you can restrict
its network access to only:

- The control plane (required for the workspace daemon to function).
- Your git provider (for push/pull operations).

Everything else can be blocked. The AI functionality comes from the control
plane, not from the workspace's network.

> [!TIP]
> For sensitive environments, create dedicated templates for agent workloads
> with stricter egress rules than your standard developer templates. Because
> the AI comes from the control plane, these templates do not need any
> outbound access to LLM providers.

### Centralized enforcement

Administrators control which models are available, the system prompt, and tool
configuration from the control plane. Developers can select from the set of
admin-enabled models when starting or continuing a chat, but cannot add their
own providers or override system prompts or tool permissions. When an
administrator removes a model or modifies the system prompt, the change applies
to all agent sessions immediately.

### User identity on every action

Every action the agent takes — PRs opened, code committed, commands executed —
is tied to the user who submitted the prompt. There is no shared bot account or
anonymous identity. If a developer submits a prompt that results in a pull
request, that pull request is attributed to them via the git authentication
already configured in your Coder deployment.

### Permission boundaries

The agent operates with the exact same permissions as the user who submitted
the prompt. If a user cannot access a template, workspace, or API endpoint
through the Coder dashboard or CLI, the agent cannot access it either. There
is no privilege escalation.

This extends to workspace isolation: the agent can only interact with
workspaces owned by the user who started the chat. It cannot read files,
execute commands, or connect to workspaces belonging to other users.

Template visibility follows the same rule. When the agent lists available
templates, it sees only the templates the user is authorized to access.
The agent cannot provision a workspace from a template the user does not
have permission to use.

## Scaling and resource impact

The control plane overhead for Coder Agents is minimal. The heavy computation
happens elsewhere:

- **LLM inference** runs on the external provider's infrastructure.
- **File I/O, builds, and tests** run on workspace compute.
- **The control plane** primarily proxies streaming responses and dispatches
  tool calls over existing network connections.

---

# Models

Source: https://coder.com/docs/ai-coder/agents/models

# Models

Administrators configure LLM providers and models from the Coder dashboard.
Providers, models, and centrally managed credentials are deployment-wide
settings managed by platform teams. Developers select from the set of models
that an administrator has enabled.

Optionally, administrators can allow developers to supply their own API keys
for specific providers. See [User API keys](#user-api-keys-byok) below.

## Providers

Each LLM provider has a type, a credential configuration, and an optional base URL override.

Coder supports the following provider types:

| Provider          | Description                                                      |
|-------------------|------------------------------------------------------------------|
| Anthropic         | Claude models via Anthropic API                                  |
| OpenAI            | GPT and o-series models via OpenAI API                           |
| Google            | Gemini models via Google AI API                                  |
| Azure OpenAI      | OpenAI models hosted on Azure                                    |
| AWS Bedrock       | Models via AWS Bedrock (bearer token or ambient AWS credentials) |
| OpenAI Compatible | Any endpoint implementing the OpenAI API                         |
| OpenRouter        | Multi-model routing via OpenRouter                               |
| Vercel AI Gateway | Models via Vercel AI SDK                                         |

The **OpenAI Compatible** type is a catch-all for any service that exposes an
OpenAI-compatible chat completions endpoint. Use it to connect to self-hosted
models, internal gateways, or third-party proxies like LiteLLM.

### Add a provider

1. Navigate to the **Agents** page in the Coder dashboard.
1. Open **Settings** > **Manage Agents** and select the **Providers** tab.
1. Click the provider you want to configure.
1. Enter the **API key** for the provider, if required.
1. Optionally set a **Base URL** to override the default endpoint. This is
   useful for enterprise proxies, regional endpoints, or self-hosted models.
1. Click **Save**.

<img src="../../images/guides/ai-agents/models-providers.png" alt="Screenshot of the providers list in the Agents settings">

<small>The providers list shows all supported providers and their configuration
status.</small>

<img src="../../images/guides/ai-agents/models-add-provider.png" alt="Screenshot of the add provider form">

<small>Adding a provider usually requires an API key. AWS Bedrock can also use
ambient AWS credentials. The base URL is optional.</small>

## Configuring AWS Bedrock

AWS Bedrock supports two credential modes for Agents providers:

- **Bearer token mode**: Enter a Bedrock-compatible bearer token in the
  **API key** field when you add the provider.
- **Ambient AWS credentials mode**: Leave the **API key** field empty. The
  Coder server resolves credentials from the standard AWS SDK credential chain,
  including IAM instance roles and `AWS_ACCESS_KEY_ID` /
  `AWS_SECRET_ACCESS_KEY` environment variables.

Region comes from the standard AWS SDK configuration. In most deployments, set
`AWS_REGION` on the Coder server. Bearer token mode falls back to `us-east-1`
when no region is configured. Ambient credentials require a region from the
standard AWS SDK chain, for example `AWS_REGION`.

The **Base URL** field overrides the Bedrock runtime endpoint. Use it for
custom endpoints or VPC endpoints.

> [!NOTE]
> Agents Bedrock provider configuration is separate from AI Gateway Bedrock
> flags (`CODER_AIBRIDGE_BEDROCK_*`). AI Gateway and Agents use independent
> credential paths.

## Provider credentials and security

Provider API keys entered in the dashboard are stored encrypted in the Coder
database. They are never exposed to workspaces, developers, or the browser
after initial entry. The dashboard shows only whether a key is set, not the
key itself.

When a provider uses ambient credentials, Coder resolves them from the server
environment at request time instead of storing a secret in the database.

Because the agent loop runs in the control plane, workspaces never need direct
access to LLM providers. See
[Architecture](./architecture.md#no-api-keys-in-workspaces) for details
on this security model.

## Key policy

Each provider has three policy flags that control how provider credentials are
sourced:

| Setting                 | Default | Description                                                                                                              |
|-------------------------|---------|--------------------------------------------------------------------------------------------------------------------------|
| Central API key         | On      | The provider uses deployment-managed credentials configured by an administrator. For most providers, this is an API key. |
| Allow user API keys     | Off     | Developers may supply their own API key for this provider.                                                               |
| Central key as fallback | Off     | When user keys are allowed, fall back to deployment-managed credentials if a developer has not set a personal key.       |

At least one credential source must be enabled. These settings appear in the
provider configuration form under **Key policy**.

The interaction between these flags determines whether a provider is available
to a given developer:

| Central key | User keys allowed | Fallback | Developer has key | Result               |
|-------------|-------------------|----------|-------------------|----------------------|
| On          | Off               | —        | —                 | Uses central key     |
| Off         | On                | —        | Yes               | Uses developer's key |
| Off         | On                | —        | No                | Unavailable          |
| On          | On                | Off      | Yes               | Uses developer's key |
| On          | On                | Off      | No                | Unavailable          |
| On          | On                | On       | Yes               | Uses developer's key |
| On          | On                | On       | No                | Uses central key     |

When a developer's personal key is present, it always takes precedence over
deployment-managed credentials. When user keys are required and fallback is
disabled, the provider is unavailable to developers who have not saved a
personal key, even if deployment-managed credentials exist. This is
intentional: it enforces that each developer authenticates with their own
credentials.

## Models

Each model belongs to a provider and has its own configuration for context limits,
generation parameters, and provider-specific options.

### Add a model

1. Open **Settings** > **Manage Agents** and select the **Models** tab.
1. Click **Add** and select the provider for the new model.
1. Enter the **Model Identifier** — the exact model string your provider
   expects (e.g., `claude-opus-4-6`, `gpt-5.3-codex`).
1. Set a **Display Name** so developers see a human-readable label in the model
   selector.
1. Set the **Context Limit** — the maximum number of tokens in the model's
   context window (e.g., `200000` for Claude Sonnet).
1. Configure any provider-specific options (see below).
1. Click **Save**.

<img src="../../images/guides/ai-agents/models-list.png" alt="Screenshot of the models list in the Agents settings">

<small>The models list shows all configured models grouped by provider.</small>

<img src="../../images/guides/ai-agents/models-add-model.png" alt="Screenshot of the add model form">

<small>Adding a model requires a model identifier, display name, and context
limit. Provider-specific options appear dynamically based on the selected
provider.</small>

### Set a default model

Click the **star icon** next to a model in the models list to make it the
default. The default model is pre-selected when developers start a new chat.
Only one model can be the default at a time.

## Model options

Every model has a set of general options and provider-specific options.
The admin UI generates these fields automatically from the provider's
configuration schema, so the available options always match the provider type.

### General options

These options apply to all providers:

| Option                | Description                                                                                      |
|-----------------------|--------------------------------------------------------------------------------------------------|
| Model Identifier      | The API model string sent to the provider (e.g., `claude-opus-4-6`).                             |
| Display Name          | The label shown to developers in the model selector.                                             |
| Context Limit         | Maximum tokens in the context window. Used to determine when context compaction triggers.        |
| Compression Threshold | Percentage (0–100) of context usage at which the agent compresses older messages into a summary. |
| Max Output Tokens     | Maximum tokens generated per model response.                                                     |
| Temperature           | Controls randomness. Lower values produce more deterministic output.                             |
| Top P                 | Nucleus sampling threshold.                                                                      |
| Top K                 | Limits token selection to the top K candidates.                                                  |
| Presence Penalty      | Penalizes tokens that have already appeared in the conversation.                                 |
| Frequency Penalty     | Penalizes tokens proportional to how often they have appeared.                                   |
| Input Price           | Optional USD price metadata for input tokens, recorded per 1M tokens.                            |
| Output Price          | Optional USD price metadata for output tokens, recorded per 1M tokens.                           |
| Cache Read Price      | Optional USD price metadata for cache read tokens, recorded per 1M tokens.                       |
| Cache Write Price     | Optional USD price metadata for cache creation/write tokens, recorded per 1M tokens.             |

### Provider-specific options

Each provider type exposes additional options relevant to its models. These
fields appear dynamically in the admin UI when you select a provider.

#### Anthropic

| Option                 | Description                                                      |
|------------------------|------------------------------------------------------------------|
| Thinking Budget Tokens | Maximum tokens allocated for extended thinking.                  |
| Effort                 | Thinking effort level (`low`, `medium`, `high`, `xhigh`, `max`). |

#### OpenAI

| Option                | Description                                                                               |
|-----------------------|-------------------------------------------------------------------------------------------|
| Reasoning Effort      | How much effort the model spends reasoning (`minimal`, `low`, `medium`, `high`, `xhigh`). |
| Max Completion Tokens | Cap on completion tokens for reasoning models.                                            |
| Parallel Tool Calls   | Whether the model can call multiple tools at once.                                        |

#### Google

| Option           | Description                                         |
|------------------|-----------------------------------------------------|
| Thinking Budget  | Maximum tokens for the model's internal reasoning.  |
| Include Thoughts | Whether to include thinking traces in the response. |

#### OpenRouter

| Option            | Description                                       |
|-------------------|---------------------------------------------------|
| Reasoning Enabled | Enable extended reasoning mode.                   |
| Reasoning Effort  | Reasoning effort level (`low`, `medium`, `high`). |

#### Vercel AI Gateway

| Option            | Description                     |
|-------------------|---------------------------------|
| Reasoning Enabled | Enable extended reasoning mode. |
| Reasoning Effort  | Reasoning effort level.         |

> [!NOTE]
> Azure OpenAI uses the same options as OpenAI. AWS Bedrock uses the same
> model configuration options as Anthropic (thinking budget, reasoning
> effort).

## How developers select models

Developers see a model selector dropdown when starting or continuing a chat on
the Agents page. The selector shows only models from providers that have valid
credentials configured. Models are grouped by provider if multiple providers
are active.

The model selector uses the following precedence to pre-select a model:

1. **Last used model** — stored in the browser's local storage.
1. **Admin-designated default** — the model marked with the star icon.
1. **First available model** — if no default is set and no history exists.

Developers cannot add their own providers or models. If no models are
configured, the chat interface displays a message directing developers to
contact an administrator.

## Model overrides

Beyond the chat-level model picker, Coder Agents supports two override
layers:

- **Subagent overrides** (admin, deployment-wide): Pin specific subagent
  contexts to a particular model. Configure them at **Agents** >
  **Settings** > **Manage Agents** > **Agents**.
- **Personal overrides** (per user, opt-in by admin): Let users override
  the model for their own root chats and delegated subagents. Admins
  enable the toggle on the same admin page; once on, each user sees an
  **Agents** tab in their personal **Agents** > **Settings**.

The configurable contexts:

| Context              | Layer        | Applies to                                                                     |
|----------------------|--------------|--------------------------------------------------------------------------------|
| **General**          | Admin + user | Write-capable subagents (`spawn_agent` with `type=general` or `computer_use`). |
| **Explore**          | Admin + user | Read-only subagents (`spawn_agent` with `type=explore`).                       |
| **Title generation** | Admin only   | Automatic title generation for new chats.                                      |
| **Root**             | User only    | The user's own root chats.                                                     |

Resolution order, evaluated per chat or subagent:

1. Personal override (when the admin gate is on and a model is set).
1. Admin subagent override.
1. The chat's selected model (or the deployment default for new chats).

If a referenced model is later disabled or deleted, that layer is skipped
and resolution falls through to the next.

> [!NOTE]
> Both override layers are experimental and may change between releases.
> The same values are available through the experimental chat
> configuration API under `/api/experimental/chats/config/`.

## User API keys (BYOK)

When an administrator enables **Allow user API keys** on a provider,
developers can supply their own API key from the Agents settings page.

### Managing personal API keys

1. Navigate to the **Agents** page in the Coder dashboard.
1. Open **Settings** and select the **API Keys** tab.
1. Each provider that allows user keys is listed with a status indicator:
   - **Key saved** — your personal key is active and will be used for requests.
   - **Using shared key** — no personal key set, but the central deployment
     key is available as a fallback.
   - **No key** — you must add a personal key before you can use this provider.
1. Enter your API key and click **Save**.

Personal API keys are encrypted at rest using the same database encryption
used for deployment-managed provider secrets. The dashboard never displays a
saved key, only whether one is set.

### How key selection works

When you start a chat, the control plane resolves which credential source to
use for each provider:

1. If you have a personal key for the provider, it is used.
1. If you do not have a personal key and central key fallback is enabled,
   deployment-managed credentials are used.
1. If you do not have a personal key and fallback is disabled, the provider
   is unavailable to you. Models from that provider will not appear in the
   model selector.

### Removing a personal key

Click **Remove** on the provider card in the API Keys settings tab. If
central key fallback is enabled, subsequent requests will use the shared
deployment-managed credentials. If fallback is disabled, the provider becomes
unavailable until you add a new personal key.

## Using an LLM proxy

Organizations that route LLM traffic through a centralized proxy — such as
Coder's AI Gateway or third parties like LiteLLM — can point any provider's **Base URL** at their proxy endpoint.

For example, to route all OpenAI traffic through Coder's AI Gateway:

1. Add or edit the **OpenAI** provider.
1. Set the **Base URL** to your AI Gateway endpoint
   (e.g., `https://example.coder.com/api/v2/aibridge/openai/v1`).
1. Enter the API key your proxy expects.

Alternatively, use the **OpenAI Compatible** provider type if your proxy serves
multiple model families through a single OpenAI-compatible endpoint.

This lets you keep existing proxy-level features like per-user budgets, rate
limiting, and audit logging while using Coder Agents as the developer interface.

---

# Platform Controls

Source: https://coder.com/docs/ai-coder/agents/platform-controls

# Platform Controls

## Design philosophy

Coder Agents is built on a simple premise: platform teams should have full
control over how agents operate, and developers should have zero configuration
burden.

This means:

- **All agent configuration is admin-level.** Providers, models, system prompts,
  and tool permissions are set by platform teams from the control plane. These
  are not user preferences — they are deployment-wide policies.
- **Developers never need to configure anything by default.** A developer just
  describes the work they want done. They do not need to pick a provider or
  write a system prompt — the platform team has already set all of that up.
  When a platform team enables user API keys for a provider, developers may
  optionally supply their own key — but this is an opt-in policy decision, not
  a requirement.
- **Enforcement, not defaults.** Settings configured by administrators are
  enforced server-side. Developers cannot override them. This is a deliberate
  distinction — a setting that a user can change is a preference, not a policy.

This is an architectural decision, not just a product choice. Because the agent
loop runs in the control plane rather than inside developer workspaces, there is
no local configuration for developers to modify and no agent software for them
to reconfigure. The control plane is the single source of truth for how agents
behave.

## What platform teams control today

### Providers and models

Administrators configure which LLM providers and models are available from the
Coder dashboard. This includes API keys, base URLs (for enterprise proxies or
self-hosted models), and per-model parameters like context limits, thinking
budgets, and reasoning effort.

Developers select from the set of models an administrator has enabled. They
cannot add their own providers or access models that have not been explicitly
configured.

When an administrator enables user API keys on a provider, developers can
supply their own key from the Agents settings page. See
[User API keys (BYOK)](../models.md#user-api-keys-byok) for details.

See [Models](../models.md) for setup instructions.

### System prompt

Administrators can set a system prompt that applies to all agent sessions. This
is useful for establishing organizational conventions: coding standards,
commit message formats, preferred libraries, or repository-specific context.

This setting is available under **Agents** > **Settings** >
**Manage Agents** > **Instructions** and is only accessible to
administrators. Developers do not see or interact with it.

### Plan mode instructions

Administrators can add deployment-wide instructions that apply only when a chat
enters plan mode. These instructions supplement the built-in planning behavior
and are useful for organization-specific planning requirements such as required
plan sections, approval checkpoints, or review workflows.

This setting is available under **Agents** > **Settings** >
**Manage Agents** > **Instructions**. Developers do not edit it directly.

The same value is exposed over the experimental chat configuration API:

- `GET /api/experimental/chats/config/plan-mode-instructions`
- `PUT /api/experimental/chats/config/plan-mode-instructions`

### Template routing

Platform teams control which templates are available to agents and how the agent
selects them. When a developer describes a task, the agent reads template
descriptions to determine which template to provision.

By writing clear template descriptions — for example, "Use this template for
Python backend services in the payments repo" — platform teams can guide the
agent toward the correct infrastructure without requiring developers to
understand template selection at all.

Administrators can also restrict which templates are available to agents
using the template allowlist at **Agents** > **Settings** >
**Manage Agents** > **Templates**. When the allowlist is configured, the
agent can only see and provision workspaces from the selected templates.
When the allowlist is empty, all templates are available. This is separate
from what developers see when manually creating workspaces, so you can apply
stricter policies to agent-created workspaces without affecting the manual
workspace experience.

See [Template Optimization](./template-optimization.md) for best practices on writing
discoverable descriptions, restricting template visibility, configuring network
boundaries, scoping credentials, and designing template parameters for agent
use.

### MCP servers

Administrators can register external MCP (Model Context Protocol) servers that
provide additional tools for agent chat sessions. This includes configuring
authentication, controlling which tools are exposed via allow/deny lists, and
setting availability policies that determine whether a server is mandatory,
opt-out, or opt-in for each chat.

See [MCP Servers](./mcp-servers.md) for configuration details.

### Workspace autostop fallback

Administrators can set a default autostop timer for agent-created workspaces
that do not define one in their template. Template-defined autostop rules always
take precedence. Active conversations extend the stop time automatically.

This setting is available under **Agents** > **Settings** >
**Manage Agents** > **Lifecycle**. The maximum configurable value is 30
days. When disabled, workspaces follow their template's autostop rules (or
none, if the template does not define any).

### Spend management

Administrators can set spend limits to cap LLM usage per user within a rolling
time period, with per-user and per-group overrides. The cost tracking dashboard
provides visibility into per-user spending, token consumption, and per-model
breakdowns.

See [Spend Management](./usage-insights.md) for details.

### Git providers

Coder Agents leverages your existing
[external authentication](../../../admin/external-auth/index.md) configuration
to power the in-chat diff viewer. Self-hosted GitHub Enterprise deployments
require additional configuration for this feature.

See [Git Providers](./git-providers.md) for details.

### Data retention

Administrators can configure a retention period for archived conversations.
When enabled, archived conversations and orphaned files older than the
retention period are automatically purged. The default is 30 days.

This setting is available under **Agents** > **Settings** >
**Manage Agents** > **Lifecycle**. See [Data Retention](./chat-retention.md)
for details.

### Experiments

Administrators can opt in to experimental features under **Agents** >
**Settings** > **Manage Agents** > **Experiments**. Behavior, configuration
surface, and APIs may change between releases.

See [Experiments](./experiments.md) for the current list of experiments, how
to enable them, and the relevant API endpoints.

## Where we are headed

The controls above cover providers, models, system prompts, templates, MCP
servers, usage limits, and data retention. We are continuing to invest in platform controls
based on what we hear from customers deploying agents in regulated and
enterprise environments.

### Infrastructure-level enforcement

We believe that security-critical behaviors should not depend on the system
prompt. A system prompt can instruct an agent to "always format branch names like... ," but there is no guarantee the agent will comply every time.

For controls that matter — network boundaries, git push targets, allowed
hostnames — we intend to enforce them at the infrastructure and network layer.
Examples of what this looks like:

- **Network-restricted templates for agent workloads.** Because the AI comes
  from the control plane, agent workspaces do not need outbound access to LLM
  providers. You can create templates that only permit access to your git
  provider and nothing else.

## Why we take this approach

The common pattern in the industry today is that each developer installs and
configures their own coding agent inside their development environment. This
creates several problems for platform teams:

- **No standardization.** Different developers use different agents with
  different configurations. There is no unified way to enforce conventions or
  improve the experience across the organization.
- **Security is ad-hoc.** If the agent runs inside the workspace, it has access
  to whatever the workspace has access to — API keys, network endpoints,
  credentials. Restricting this requires per-workspace configuration that is
  difficult to maintain at scale.
- **Feedback is anecdotal.** Without centralized analytics, platform teams have
  no way to know which models perform best, which prompts cause failures, or how
  much agents are costing the organization.
- **Configuration is a developer burden.** Developers — especially those who
  are not power users — should not need to think about which agent to install,
  which API key to use, or how to configure a system prompt. They should
  describe the work they want done.

As models improve and the differences between agent harnesses continue to
shrink, we believe the leverage shifts toward user experience and platform-level controls: which
models to offer, how to enforce security, and how to use analytics to
continuously improve the development experience across the organization.

---

# Template Optimization

Source: https://coder.com/docs/ai-coder/agents/platform-controls/template-optimization

# Template Optimization

Not every chat with Coder Agents requires a workspace. A workspace is only provisioned when the
agent decides it needs compute — to read files, write code, run commands, or
execute builds.

When a workspace is needed, the agent reads the available templates, selects
the appropriate one based on its name and description, and provisions a
workspace automatically. Administrators can restrict which templates the agent
can see using the [template allowlist](#restrict-available-templates).

This guide covers best practices for creating templates that are discoverable
and useful to Coder Agents.

## Restrict available templates

By default, the agent can see and provision any template in the deployment.
Administrators can restrict this to a specific set of templates using the
template allowlist.

To configure the allowlist:

1. Navigate to **Agents** > **Settings** > **Manage Agents** > **Templates**.
2. Select the templates you want agents to be able to use.
3. Click **Save**.

When the allowlist is configured, the agent's `list_templates`,
`read_template`, and `create_workspace` tools are filtered to only include
the selected templates. The agent cannot see or provision templates that are
not on the list.

When no templates are selected, the allowlist is inactive and all templates
are available to agents.

The allowlist only affects agent-created workspaces. Developers can still
manually create workspaces from any template they have access to. This lets
platform teams apply stricter policies to agent workloads without affecting
the manual workspace experience.

## Write discoverable template descriptions

The agent selects templates by reading their names and descriptions — the same
metadata shown on the templates page in the Coder dashboard, sorted by number
of active developers. It does not inspect the template's Terraform to
understand what infrastructure is inside.

This means the template description is the single most important factor in
whether the agent picks the right template for a given task.

### What to include

A good template description tells the agent:

- What language, framework, or stack the template is for.
- Which repository or service it targets, if applicable.
- What type of work it supports (e.g., backend services, frontend apps, data
  pipelines).

### Examples

| Description                                                                                 | Why it works                                                       |
|---------------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| Python backend services for the payments repo. Includes Poetry, Python 3.12, and PostgreSQL | Specific language, repo, and toolchain                             |
| React frontend development for the customer portal. Node 20, pnpm, Storybook pre-installed  | Clear stack, named project, key tools listed                       |
| General-purpose Go development environment with Go 1.23, Docker, and common CLI tools       | Broad but descriptive — the agent can match it to Go-related tasks |
| Java microservices for the order-processing pipeline. Maven, JDK 21, Kafka client libraries | Names the service domain and build tool                            |

| Description        | Why it fails                                                            |
|--------------------|-------------------------------------------------------------------------|
| Team A template v2 | No information about what the template is for                           |
| Dev environment    | Too generic — the agent cannot distinguish this from any other template |
| k8s-prod-2024      | Internal shorthand that carries no meaning for the agent                |
| Default            | Tells the agent nothing                                                 |

> [!TIP]
> If many developers already use a template, the agent is more likely to
> select it because templates are sorted by active developer count. A
> well-written description on a popular template is the strongest routing
> signal you can provide.

### Template display names

Display names appear in the template selector and in the agent's tool output.
Use readable, descriptive names rather than slugs or internal codes. A display
name like "Python Backend (Payments)" is more useful to both humans and the
agent than `py-be-pay-v3`.

## Create dedicated agent templates

Rather than reusing your standard interactive developer templates for agent
workloads, consider creating dedicated templates with configurations
appropriate for unattended, agent-driven work.

Agent templates differ from developer templates in several ways:

- **No IDE tooling needed.** The agent connects via the workspace daemon's HTTP
  API, not through VS Code or JetBrains. You can omit IDE-specific
  configuration, extensions, and desktop tools.
- **Stricter network policies.** Agent workspaces typically need access to only
  the control plane and your git provider. You can apply tighter egress rules
  than you would for a developer who needs to browse documentation or access
  additional services.
- **Reduced permissions.** Agent workspaces can use scoped credentials with
  fewer permissions than a developer's interactive session.

See [Creating templates](../../../admin/templates/creating-templates.md) for
step-by-step instructions on creating templates via the UI, CLI, or CI/CD.

## Configure network boundaries

The workspace is the network boundary for the agent. If you want to control
what the agent can access, control what the workspace can access.

This is a deliberate architectural advantage of running the agent loop in the
control plane. Because all AI functionality — LLM inference, tool dispatch,
chat state — lives in the control plane, agent workspaces do not need outbound
access to any LLM provider. The workspace only needs to reach:

- **The Coder control plane** — required for the workspace daemon to function.
- **Your git provider** — required for push and pull operations.

Everything else can be blocked at the network level.

### Why network boundaries are more effective than process-level controls

Traditional approaches to restricting agent behavior — such as blocking
specific commands at the process level — are difficult to enforce reliably. An
agent executing arbitrary shell commands can find alternative paths to achieve
the same result (aliasing commands, writing scripts, using different tools).

Network-level boundaries are more robust because they operate below the process
layer. If the workspace cannot reach an external service, it does not matter
what command the agent runs — the connection simply fails. This provides a
firmer security guarantee than trying to restrict individual process behaviors.

See [Architecture](../architecture.md#workspaces-can-be-fully-network-isolated)
for more detail on the security model.

## Scope permissions and credentials

> [!WARNING]
> By default, agent workspaces inherit the same network access and
> permissions as any workspace the user creates manually. If your templates
> do not explicitly restrict outbound network access, the agent has full
> internet access from the workspace. Review the guidance below and in
> [Configure network boundaries](#configure-network-boundaries) to lock
> down agent workloads appropriately.

The agent operates with the same identity and permissions as the user who
submitted the prompt. There is no privilege escalation — if a developer cannot
access a resource through the Coder dashboard, the agent cannot access it
either.

### External service credentials

When agent workspaces need access to external services (git providers, package
registries, artifact stores), configure credentials with the minimum scope
required:

- **Use separate tokens for agent templates.** Rather than sharing the same
  broad-scope token used by developer workspaces, create a dedicated token with
  only the permissions the agent needs (e.g., read/write access to specific
  repositories, no admin access).
- **Configure external auth at the template level.** Use Coder's
  [external authentication](../../../admin/external-auth/index.md) to provide scoped
  git credentials. The agent uses the same external auth flow as any other
  workspace, so credentials are managed centrally.
- **Avoid injecting long-lived secrets.** Prefer short-lived tokens or
  credential helpers over static API keys baked into the template image.

### Git identity

Every git operation the agent performs — commits, pushes, pull requests — is
attributed to the user who submitted the prompt. This happens through the
existing git authentication configured in your Coder deployment. There is no
shared bot account.

Ensure your templates configure git with the appropriate author information so
that commits are properly attributed. The agent does not override git
configuration — it uses whatever is set in the workspace environment.

## Design template parameters for automation

The agent can read template parameters — including their names, descriptions,
and defaults — and fill them in when creating a workspace. Well-designed
parameters help the agent provision the right infrastructure without human
intervention.

### Keep parameters simple

- **Use sensible defaults.** The agent performs best when most parameters have
  reasonable defaults and only a few require explicit selection. A template
  with ten required parameters and no defaults forces the agent to guess.
- **Minimize required parameters.** If a parameter is not essential for the
  agent's use case, give it a default value or make it optional.

### Write descriptive parameter metadata

The agent reads `display_name` and `description` fields to understand what a
parameter controls. Treat these the same way you treat template descriptions —
be specific and use natural language.

```hcl
data "coder_parameter" "region" {
  name         = "region"
  display_name = "Deployment Region"
  type         = "string"
  description  = "AWS region for the workspace. Use us-east-1 for the payments service or eu-west-1 for GDPR-regulated workloads."
  default      = "us-east-1"
}
```

A description like "AWS region" is less useful to the agent than one that
explains when to use each option.

### Avoid opaque identifiers

Parameters with values like `ami-0abcdef1234567890` or `subnet-12345` are
difficult for the agent to reason about. Where possible, use human-readable
option labels or map opaque IDs to descriptive names using Terraform locals.

For full parameter reference — including types, validation, mutability, and
workspace presets — see
[Parameters](../../../admin/templates/extending-templates/parameters.md).
[Dynamic parameters](../../../admin/templates/extending-templates/dynamic-parameters.md)
add conditional form controls and identity-aware defaults for more advanced
use cases.

## Pre-install tools and dependencies

Agent workspaces should be ready to work immediately after provisioning. The
agent does not know how to install your organization's specific toolchain, and
time spent installing dependencies is time not spent on the task.

### What to pre-install

- **Language runtimes and build tools** for the target stack (e.g., Go, Node,
  Python, Maven).
- **Common CLI tools** the agent is likely to use: `git`, `curl`, `jq`, `make`,
  `docker` (if applicable).
- **Project-specific dependencies.** If the template targets a specific
  repository, consider pre-installing the project's dependencies or running the
  setup script as part of workspace startup.
- **Git configuration.** Ensure `git` is configured with credentials and author
  information so the agent can commit and push without additional setup.

For guidance on building and maintaining workspace images, see
[Image management](../../../admin/templates/managing-templates/image-management.md).

### Set a meaningful working directory

If the template targets a specific repository, pre-clone it and set the
working directory so the agent starts in the right place:

```hcl
resource "coder_agent" "main" {
  os   = "linux"
  arch = "amd64"
  dir  = "/home/coder/payments-service"
}
```

This avoids a round trip where the agent needs to figure out where the code
lives before it can begin working.

## Use prebuilt workspaces to reduce provisioning time

Workspace provisioning is the primary source of latency when the agent begins a
task. Templates with complex infrastructure, large images, or lengthy startup
scripts can take minutes to provision — time where the developer is waiting
and the agent is idle.

[Prebuilt workspaces](../../../admin/templates/extending-templates/prebuilt-workspaces.md)
eliminate this delay by maintaining a pool of ready-to-use workspaces for
specific parameter presets. When the agent creates a workspace that matches a
preset, Coder assigns an already-running prebuilt workspace instead of
provisioning from scratch. The agent can begin working immediately.

## Checklist

Use this as a quick reference when creating or updating templates for Coder
Agents:

- Template has a specific, natural-language description that includes
  language, framework, and target project or service.
- Display name is readable and descriptive.
- Network egress is restricted to the control plane and git provider.
- External service credentials use minimal-scope tokens.
- Template parameters have sensible defaults and descriptive metadata.
- Language runtimes, build tools, and git are pre-installed.
- Prebuilt workspaces are configured for high-traffic presets (Premium).
- Working directory is set to the target repository (if applicable).

---

# MCP Servers

Source: https://coder.com/docs/ai-coder/agents/platform-controls/mcp-servers

# MCP Servers

Administrators can register external MCP servers that provide additional tools
for agent chat sessions. Configured servers are injected into or offered to
users during chat depending on the availability policy.

This is an admin-only feature accessible at **Agents** > **Settings** >
**Manage Agents** > **MCP Servers**.

## Add an MCP server

1. Navigate to **Agents** > **Settings** > **Manage Agents** >
   **MCP Servers**.
1. Click **Add**.
1. Fill in the configuration fields described below.
1. Click **Save**.

### Identity

| Field          | Required | Description                                                   |
|----------------|----------|---------------------------------------------------------------|
| `display_name` | Yes      | Human-readable name shown to users in chat.                   |
| `slug`         | Yes      | URL-safe unique identifier, auto-generated from display name. |
| `description`  | No       | Brief summary of what the server provides.                    |
| `icon_url`     | No       | Emoji or image URL displayed alongside the server name.       |

### Connection

| Field       | Required | Description                                     |
|-------------|----------|-------------------------------------------------|
| `url`       | Yes      | The MCP server endpoint URL.                    |
| `transport` | Yes      | Transport protocol. `streamable_http` or `sse`. |

### Availability

| Field          | Required | Description                                                                                                                   |
|----------------|----------|-------------------------------------------------------------------------------------------------------------------------------|
| `enabled`      | No       | Master toggle. Disabled servers are hidden from non-admin users.                                                              |
| `availability` | Yes      | Controls how the server appears in chat sessions. See [Availability policies](#availability-policies).                        |
| `model_intent` | No       | When enabled, requires the model to describe each tool call's purpose in natural language, shown as a status label in the UI. |

#### Availability policies

| Policy        | Behavior                                               |
|---------------|--------------------------------------------------------|
| `force_on`    | Always injected into every chat. Users cannot opt out. |
| `default_on`  | Pre-selected in new chats. Users can opt out.          |
| `default_off` | Available in the server list but users must opt in.    |

## Authentication

Each MCP server uses one of five authentication modes. When you change the
auth type, fields from the previous type are automatically cleared.

Secrets are never returned in API responses — boolean flags indicate whether
a value is set.

### None

No credentials are sent. Use this for servers that do not require
authentication.

### OAuth2

Per-user authorization. The administrator configures the OAuth2 provider, and
each user independently completes the authorization flow.

**Manual configuration** — provide all three fields together:

| Field              | Description                 |
|--------------------|-----------------------------|
| `oauth2_client_id` | OAuth2 client ID.           |
| `oauth2_auth_url`  | Authorization endpoint URL. |
| `oauth2_token_url` | Token endpoint URL.         |

Optional fields:

| Field                  | Description                     |
|------------------------|---------------------------------|
| `oauth2_client_secret` | OAuth2 client secret.           |
| `oauth2_scopes`        | Space-separated list of scopes. |

**Auto-discovery** — leave `oauth2_client_id`, `oauth2_auth_url`, and
`oauth2_token_url` empty. The server attempts discovery in this order:

1. RFC 9728 — Protected Resource Metadata
1. RFC 8414 — Authorization Server Metadata
1. RFC 7591 — Dynamic Client Registration

Users connect through a popup that redirects through the OAuth2 provider.
Tokens are stored per-user and refreshed automatically. Users can disconnect
via the UI or API to remove stored tokens.

### API key

A static key sent as a header on every request.

| Field            | Required | Description                          |
|------------------|----------|--------------------------------------|
| `api_key_header` | Yes      | Header name (e.g., `Authorization`). |
| `api_key_value`  | Yes      | Secret value sent in the header.     |

### Custom headers

Arbitrary key-value header pairs sent on every request. At least one header
is required when this mode is selected.

### User OIDC Identity

Forwards the calling user's OIDC access token (stored in
`user_links.oauth_access_token`) to the MCP server as an
`Authorization: Bearer <token>` header. The token is refreshed
transparently before each request if it has expired or is close to
expiring.

No admin-configurable fields. No per-user connect step.

**Limitation**: this auth mode only works for users who authenticated to
Coder via OIDC. Users who logged in with password or GitHub will see
requests sent without an authorization header, and the upstream MCP
server is expected to respond with 401.

## Tool governance

Control which tools from a server are available in chat:

| Field             | Description                                                                           |
|-------------------|---------------------------------------------------------------------------------------|
| `tool_allow_list` | If non-empty, only the listed tool names are exposed. An empty list allows all tools. |
| `tool_deny_list`  | Listed tool names are always blocked, even if they appear in the allow list.          |

## Permissions

| Action                        | Required role             |
|-------------------------------|---------------------------|
| Create, update, or delete     | Admin (deployment config) |
| View enabled servers          | Any authenticated user    |
| OAuth2 connect and disconnect | Any authenticated user    |

Non-admin users only see enabled servers. Sensitive fields such as API keys
and client secrets are redacted in API responses.

---

# Spend Management

Source: https://coder.com/docs/ai-coder/agents/platform-controls/usage-insights

# Spend Management

Coder provides admin-only controls for monitoring and controlling agent
spend: usage limits and cost tracking.

## Usage limits

Navigate to **Agents** > **Settings** > **Manage Agents** > **Spend**.

Usage limits cap how much each user can spend on LLM usage within a rolling
time period. When enabled, the system checks the user's current spend before
processing each chat message.

### Configuration

- **Enable/disable toggle** — master on/off for the entire limit system.
- **Period** — `day`, `week`, or `month`. Periods are UTC-aligned: midnight
  UTC for daily, Monday start for weekly, first of the month for monthly.
- **Default limit** — deployment-wide default in dollars. Applies to all
  users who do not have a more specific override. Leave unset for no limit.
- **Per-user overrides** — set a custom dollar limit for an individual user.
  Takes highest priority.
- **Per-group overrides** — set a limit for a group. When a user belongs to
  multiple groups, the lowest group limit applies.

### Priority hierarchy

The system resolves a user's effective limit in this order:

1. Individual user override (highest priority)
1. Minimum group limit across all of the user's groups
1. Global default limit
1. No limit (if limits are disabled or no value is configured)

### Enforcement

- Checked before each chat message is processed.
- When current spend meets or exceeds the limit, the chat returns a
  **409 Conflict** response and the message is blocked.
- Fail-open: if the limit query itself fails, the message is allowed
  through.
- Brief overage is possible when concurrent messages are in flight, because
  cost is determined only after the LLM returns.

### User-facing status

Users can view their own spend status, including whether a limit is active,
their effective limit, current spend, and when the current period resets.

> [!NOTE]
> The admin configuration page shows the count of models without pricing
> data. Models missing pricing cannot be tracked accurately against limits.

## Cost tracking

Navigate to **Agents** > **Settings** > **Manage Agents** > **Spend**.

This view shows deployment-wide LLM chat costs with per-user drill-down.

### Top-level view

A per-user rollup table with the following columns:

| Column             | Description                         |
|--------------------|-------------------------------------|
| Total cost         | Aggregate dollar spend for the user |
| Messages           | Number of chat messages sent        |
| Chats              | Number of distinct chat sessions    |
| Input tokens       | Total input tokens consumed         |
| Output tokens      | Total output tokens consumed        |
| Cache read tokens  | Tokens served from cache            |
| Cache write tokens | Tokens written to cache             |

The table supports date range filtering (default: last 30 days), search by
name or username, and pagination.

### Per-user detail view

Select a user to see:

- **Summary cards** — total cost, token breakdowns, and message counts.
- **Usage limit progress** — if a limit is active, a color-coded progress
  bar shows current spend relative to the limit.
- **Per-model breakdown** — table of costs and token usage by model.
- **Per-chat breakdown** — table of costs and token usage by chat session.

> [!NOTE]
> Automatic title generation uses lightweight models, such as Claude Haiku or GPT-4o
> Mini. Its token usage is not counted towards usage limits or shown in usage
> summaries.

---

# Git Providers

Source: https://coder.com/docs/ai-coder/agents/platform-controls/git-providers

# Git Providers

Coder Agents leverages your existing
[external authentication](../../../admin/external-auth/index.md) configuration
to power the in-chat diff viewer.
Self-hosted GitHub Enterprise deployments require one additional setting
(`API_BASE_URL`) for this feature to work.

> [!NOTE]
> Only `github` type external auth providers are supported today.

## GitHub Enterprise configuration

For public `github.com`, no additional configuration is needed.

For self-hosted GitHub Enterprise, add `API_BASE_URL` to your
[existing configuration](../../../admin/external-auth/index.md#github-enterprise):

```env
CODER_EXTERNAL_AUTH_0_ID="primary-github"
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=xxxxxx
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_AUTH_URL="https://github.example.com/login/oauth/authorize"
CODER_EXTERNAL_AUTH_0_TOKEN_URL="https://github.example.com/login/oauth/access_token"
CODER_EXTERNAL_AUTH_0_VALIDATE_URL="https://github.example.com/api/v3/user"
CODER_EXTERNAL_AUTH_0_API_BASE_URL="https://github.example.com/api/v3"
CODER_EXTERNAL_AUTH_0_REGEX=github\.example\.com
```

Without `API_BASE_URL`, Coder defaults to `https://api.github.com`. Clone
and push still work (they use `AUTH_URL` and `TOKEN_URL` directly), but
the diff viewer silently fails because Coder builds its URL-matching
patterns from the API base URL.

> [!NOTE]
> If you have both a `github.com` and a GHE external auth config, only the
> GHE config needs `API_BASE_URL`.

## Troubleshooting

### Diffs not appearing on GHE

Add `API_BASE_URL` to your GHE external auth config and restart Coder.
Diffs should appear within a couple of minutes.

### Users not seeing diffs

The chat owner must have linked their account through the relevant external
auth provider.

### Checking logs

Look for gitsync warnings such as `no provider for origin` or
`resolve token` errors.

---

# Data Retention

Source: https://coder.com/docs/ai-coder/agents/platform-controls/chat-retention

# Conversation Data Retention

Coder Agents automatically cleans up old conversation data to manage database
growth. Archived conversations and their associated files are periodically
purged based on a configurable retention period.

Conversations become eligible for purging only after they are archived. Old
conversations can be archived manually, or automatically. See
[Auto-Archive](./chat-auto-archive.md) for how the two controls interact.

Debug run and step cleanup is controlled separately. See
[Chat Debug Data Retention](./chat-debug-retention.md).

## How it works

A background process runs approximately every 10 minutes to remove expired
conversation data. Only archived conversations are eligible for deletion —
active (non-archived) conversations are never purged.

When an archived conversation exceeds the retention period, it is deleted along
with its messages, diff statuses, and queued messages via cascade. Orphaned
files (not referenced by any active or recently-archived conversation) are also
deleted. Both operations run in batches of 1,000 rows per cycle.

## Configuration

Navigate to the **Agents** page, open **Settings**, and select the **Behavior**
tab to configure the conversation retention period. The default is 30 days. Use the toggle to
disable retention entirely.

Use the experimental admin API to read or update the value:

```text
GET  /api/experimental/chats/config/retention-days
PUT  /api/experimental/chats/config/retention-days
```

## What gets deleted

| Data                   | Condition                                                                                      | Cascade                                                       |
|------------------------|------------------------------------------------------------------------------------------------|---------------------------------------------------------------|
| Archived conversations | Archived longer than retention period                                                          | Messages, diff statuses, queued messages deleted via CASCADE. |
| Conversation files     | Older than retention period AND not referenced by any active or recently-archived conversation | —                                                             |

## Unarchive safety

If a user unarchives a conversation whose files were purged, stale file
references are automatically cleaned up by FK cascades. The conversation
remains usable but previously attached files are no longer available.

---

# Debug Data Retention

Source: https://coder.com/docs/ai-coder/agents/platform-controls/chat-debug-retention

# Chat Debug Data Retention

Coder Agents automatically cleans up old chat debug data to manage database
growth. Debug data includes persisted debug runs and their associated debug
steps.

This setting is independent from [conversation data retention](./chat-retention.md),
which only purges archived conversations and orphaned files.

## How it works

A background process removes debug runs older than the configured retention
period. When a debug run is deleted, its debug steps are deleted via cascade.

The retention clock uses the debug run's `updated_at` value, which reflects the
last write to the debug run. It does not use the chat archive time. If a debug
run remains in progress for an unusually long period, such as after broken
finalization, it can still be purged once its `updated_at` value is older than
the cutoff.

## Configuration

Navigate to the **Agents** page, open **Settings**, and select the
**Lifecycle** tab to configure chat debug data retention. The default is 30 days.
Set the value to `0` to disable debug data retention entirely. The maximum value
is `3650` days.

Use the experimental admin API to read or update the value:

```text
GET  /api/experimental/chats/config/debug-retention-days
PUT  /api/experimental/chats/config/debug-retention-days
```

## Interaction with conversation retention

Conversation retention and debug data retention are orthogonal controls:

| Control                | What it deletes                                             | Default |
|------------------------|-------------------------------------------------------------|---------|
| Conversation retention | Archived conversations and orphaned files                   | 30 days |
| Debug data retention   | Debug runs and debug steps, based on debug run `updated_at` | 30 days |

Deleting a chat still deletes its debug data immediately via cascade, regardless
of the debug retention window. Unarchiving a chat does not restore debug data
that was already purged.

---

# Auto-Archive

Source: https://coder.com/docs/ai-coder/agents/platform-controls/chat-auto-archive

# Conversation Auto-Archive

Coder Agents automatically archives long-inactive conversations so they
drop out of active chat lists without any user intervention. Archived
conversations are still visible (and can be unarchived) until they age
out of the separate retention window, at which point they are purged.

## How it works

A background process runs approximately every 10 minutes. On each tick
it scans the chat database for root conversations whose most recent
non-deleted message is older than the configured auto-archive window
and flips them from "active" to "archived". Cascaded children (chats
linked into a larger conversation via `root_chat_id`) are archived
alongside their parent so the conversation stays coherent.

Activity is defined as the most recent non-deleted message in the
conversation family, counting messages from every role. Root chats
whose status indicates ongoing work (`running`, `pending`, `paused`,
or `requires_action`) are never selected for auto-archiving.
Children inherit their root's archival decision.

Pinned root conversations (those with a non-zero pin order) are never
selected for auto-archiving. Children are archived alongside their
root regardless of individual pin status. Admins and users who want
to retain a conversation long after its last message should pin the
root.

## Notifications

When your chats are auto-archived, you receive a digest notification
listing the titles of the archived conversations and the
auto-archive window currently configured.

If you find the digest noisy, you can disable the "Chats
Auto-Archived" notification entirely from your notification preferences.

## Interaction with retention

Auto-archive and deletion are two independent controls:

| Control             | What it does                                                              | Default           |
|---------------------|---------------------------------------------------------------------------|-------------------|
| Auto-archive window | Moves inactive chats to the archived state                                | 0 days (disabled) |
| Retention window    | Deletes chats that have been archived long enough and orphaned chat files | 30 days           |

A conversation needs to be inactive for `auto_archive_days`, then
archived for `retention_days`, before it is deleted. The two windows
stack additively. With auto-archive disabled by default, inactive
chats are never auto-archived; once an admin opts in by setting a
non-zero `auto_archive_days`, a conversation lives for at least
`auto_archive_days + retention_days` from its last message before it
is permanently removed.

Auto-archive (like manual archive) resets the per-chat retention
clock, so the full `retention_days` runs from the tick that archived
the chat, not from its last message.

Setting either value to `0` disables that step. Setting
`auto_archive_days` to `0` means inactive chats are never
auto-archived (users still archive manually). Setting
`retention_days` to `0` means archived chats are kept indefinitely.

## Configuration

The auto-archive window is stored as the
`agents_chat_auto_archive_days` key in the `site_configs` table.
The default is `0` (disabled); set to a positive number of days to
enable auto-archiving.

Use the admin API to read or update the value:

    GET  /api/experimental/chats/config/auto-archive-days
    PUT  /api/experimental/chats/config/auto-archive-days

## Rollout advice

Auto-archive is disabled by default, so upgrading to a release that
includes this feature will not archive any existing chats until an
admin opts in. The first tick after enabling auto-archive on a
deployment with a long history will process up to 1,000 root chats
(and their children). If your deployment has a large backlog, the
initial rollout will span many ticks. This is intentional and avoids
stalling the rest of `dbpurge` during the first run. To disable,
set `auto_archive_days` back to `0`.

## Audit trail

Each auto-archived root chat produces an audit log entry with the
background subsystem tag `chat_auto_archive`. Cascaded children are
not audited individually.

---

# Experiments

Source: https://coder.com/docs/ai-coder/agents/platform-controls/experiments

# Experiments

The **Experiments** tab under **Agents** > **Settings** > **Manage Agents**
is where administrators opt in to features that are still iterating. The
behavior, configuration surface, and APIs documented here may change between
releases without notice.

> [!NOTE]
> Everything in this page is experimental. Pin a release before broad rollout
> and review the release notes before upgrading.

## Virtual desktop

Lets agents drive a graphical desktop inside the workspace through
`spawn_agent` with `type=computer_use` (screenshots, mouse, keyboard).

To enable, toggle **Virtual Desktop** on, then choose a **Computer use
provider** (Anthropic or OpenAI). It also requires:

- The [portabledesktop](https://registry.coder.com/modules/coder/portabledesktop)
  module installed in the workspace template.
- An API key for the selected provider configured under the **Providers**
  tab.

The Anthropic and OpenAI computer-use models are fixed by Coder per provider
and are not selectable from this UI. Anthropic is the default when no
provider is set.

## Advisor

Lets a root agent pause its current turn and request strategic guidance from
a separate, single-step model call. The advisor sees recent conversation
context, runs without any tools, and returns concise advice for the parent
agent rather than the end user. While active, it is the only tool the parent
can call for that turn.

Useful for planning ambiguity, architectural tradeoffs, debugging strategy
after repeated failures, or risk reduction before a destructive operation.

| Field             | Default              | Notes                                                                                                                   |
|-------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------|
| Advisor (toggle)  | Off                  | Master switch. When off, the advisor tool is not attached to new chats.                                                 |
| Max uses per run  | `0` (unlimited)      | Caps how many times an agent can call the advisor in a single chat run. Must be a non-negative integer.                 |
| Max output tokens | `0` (server default) | Caps the advisor model's response length. `0` uses the server default of 16,384 tokens. Must be a non-negative integer. |
| Reasoning effort  | Use chat model       | One of unset, `low`, `medium`, or `high`. Unset delegates to the underlying model's default.                            |
| Advisor model     | Use chat model       | Optional dedicated chat model config for the advisor. When unset, the advisor reuses the parent chat's model.           |

The advisor is not available in plan mode or to subagents. Failed advisor
invocations refund the per-run budget, and advisor calls are not metered
against the parent chat's usage limit.

The same configuration is available at:

- `GET /api/experimental/chats/config/advisor`
- `PUT /api/experimental/chats/config/advisor`

## Chat debug logging

Records a detailed trace of each chat turn for troubleshooting: the
normalized request sent to the LLM provider, the full response, token usage,
retry attempts, and errors.

Off by default. Three layers control whether it runs for a given chat:

1. **Deployment override.** Setting `CODER_CHAT_DEBUG_LOGGING_ENABLED=true`
   (or `--chat-debug-logging-enabled` at server start) forces debug logging
   on for every chat. The runtime admin and user toggles become read-only.
1. **Runtime admin gate.** With the deployment override unset, the
   *Let users record chat debug logs* toggle decides whether users can opt
   in. Configure it at
   `GET/PUT /api/experimental/chats/config/debug-logging`.
1. **Per-user toggle.** Users with the admin gate enabled can turn debug
   logging on for their own chats from **Agents** > **Settings** > **General**
   under *Record debug logs for my chats*. The endpoint
   `PUT /api/experimental/chats/config/user-debug-logging` returns
   `409 Conflict` if the deployment override is active and `403 Forbidden`
   if the admin has not enabled user opt-in.

> [!IMPORTANT]
> Debug logs may contain sensitive content from prompts, responses, tool
> calls, and errors. Treat them with the same care as conversation history.
> Only the chat owner (or a user with read access to the chat) can fetch a
> chat's debug runs through the API. Administrators do not get blanket
> access to all users' debug data.

When debug logging is active for a chat, a **Debug** tab appears in the
right panel of the Agents page (alongside Git, Terminal, and Desktop) for
that chat's owner. The tab lists recent debug runs and lets you expand a run
into its per-step request, response, token usage, retry attempts, errors,
and policy metadata.

The same data is available through the experimental API:

- `GET /api/experimental/chats/{chat}/runs` lists the most recent runs for a
  chat (up to 100, newest first).
- `GET /api/experimental/chats/{chat}/runs/{debugRun}` returns a single run
  with all of its steps, including normalized request and response bodies.

Debug runs are stored alongside the chat and are removed when the parent
conversation is deleted (manually, by retention, or by chat purge). See
[Data Retention](./chat-retention.md) for the conversation retention
controls.

---

# Extending Agents

Source: https://coder.com/docs/ai-coder/agents/extending-agents

# Extending Agents

Workspace templates can extend the agent with custom skills and MCP tools.
These mechanisms let platform teams provide repository-specific instructions,
domain expertise, and external tool integrations without modifying the agent
itself.

## Skills

Skills are structured, reusable instruction sets that the agent loads on
demand. They live in the workspace filesystem and are discovered
automatically when a chat attaches to a workspace.

### How skills work

Place skill directories under `.agents/skills/` relative to the workspace
working directory. Each directory contains a required `SKILL.md` file and
any supporting files the skill needs.

On the first turn of a workspace-attached chat, the agent scans
`.agents/skills/` and builds an `<available-skills>` block in its system
prompt listing each skill's name and description. Only frontmatter is read
during discovery — the full skill content is loaded lazily when the agent
calls a tool.

Two tools are registered when skills are present:

| Tool              | Parameters                       | Description                                              |
|-------------------|----------------------------------|----------------------------------------------------------|
| `read_skill`      | `name` (string)                  | Returns the SKILL.md body and a list of supporting files |
| `read_skill_file` | `name` (string), `path` (string) | Returns the content of a supporting file                 |

### Directory structure

```text
.agents/skills/
├── deep-review/
│   ├── SKILL.md
│   └── roles/
│       ├── security-reviewer.md
│       └── concurrency-reviewer.md
├── pull-requests/
│   └── SKILL.md
└── refine-plan/
    └── SKILL.md
```

### SKILL.md format

Each `SKILL.md` starts with YAML frontmatter containing a `name` and an
optional `description`, followed by the full instructions in markdown:

```markdown
---
name: deep-review
description: "Multi-reviewer code review with domain-specific reviewers"
---

# Deep Review

Instructions for the skill go here...
```

### Naming and size constraints

- Names must be kebab-case (`^[a-z0-9]+(-[a-z0-9]+)*$`) and match the
  directory name exactly.
- `SKILL.md` has a maximum size of 64 KB.
- Supporting files have a maximum size of 512 KB. Files exceeding the limit
  are silently truncated.

### Path safety

`read_skill_file` rejects absolute paths, paths containing `..`, and
references to hidden files. All paths are resolved relative to the skill
directory.

## Workspace MCP tools

Workspace templates can expose custom
[MCP](https://modelcontextprotocol.io/introduction) tools by placing a
`.mcp.json` file in the workspace working directory. The agent discovers
these tools automatically when it connects to a workspace and registers
them alongside its built-in tools.

### Configuration

Define MCP servers in `.mcp.json` at the workspace root. Each entry under
`mcpServers` describes a server. The transport type is inferred from
whether `command` or `url` is present, or you can set it explicitly with
`type`:

```json
{
  "mcpServers": {
    "github": {
      "command": "github-mcp-server",
      "args": ["--token", "..."]
    },
    "my-api": {
      "type": "http",
      "url": "http://localhost:8080/mcp",
      "headers": { "Authorization": "Bearer ..." }
    }
  }
}
```

**Stdio transport** — set `command`, and optionally `args` and `env`. The
agent spawns the process in the workspace.

**HTTP transport** — set `url`, and optionally `headers`. The agent connects
to the HTTP endpoint from the workspace.

### How discovery works

The agent reads `.mcp.json` via the workspace agent connection on each chat
turn. Discovery uses a 5-second timeout. Servers that fail to
respond are skipped — partial success is acceptable. Empty results are not
cached because the MCP servers may still be starting.

### Tool naming

Tool names are prefixed with the server name as `serverName__toolName` to
avoid collisions between servers and with built-in tools.

### Timeouts

- **Discovery**: 5-second timeout.
- **Tool calls**: 60 seconds per invocation.

---

# Tasks to Chats API Migration

Source: https://coder.com/docs/ai-coder/agents/tasks-to-chats-migration

# Migrating from the Tasks API to the Chats API

The [Tasks API](../../reference/api/tasks.md) (`/api/v2/tasks`) and the
[Chats API](../../reference/api/chats.md) (`/api/experimental/chats`) serve similar
goals (programmatic access to AI-powered coding agents) but they differ
significantly in architecture, capabilities, and usage patterns.

This guide walks you through updating your integrations from the Tasks API
to the Chats API.

> [!NOTE]
> The Chats API is experimental in current Coder releases. Endpoints live under `/api/experimental/chats` and may change without notice until the feature graduates to GA.

## When to migrate

Coder Tasks is being deprecated. Support continues on the ESR release and
through Coder v2.36. See the deprecation notice on the [Coder Tasks](../tasks.md) page for the full timeline.

If you currently run workflows on the Tasks API, you should plan to
migrate to the Chats API and [Coder Agents](./index.md). Coder Agents
runs the agent loop in the Coder control plane rather than inside the
workspace, and is the supported path going forward.

The two systems are not interchangeable. Tasks and Chats are separate
resources with separate APIs, so plan to update your integrations rather
than expecting a drop-in replacement.

## Key architectural differences

Before mapping individual endpoints, understand the structural changes:

| Aspect                 | Tasks API                                                                        | Chats API                                                  |
|------------------------|----------------------------------------------------------------------------------|------------------------------------------------------------|
| Agent execution        | Agent runs **inside the workspace** (via AgentAPI)                               | Agent loop runs **in the control plane**                   |
| LLM credentials        | Injected into workspace environment                                              | Stored in control plane only; never enters the workspace   |
| Workspace provisioning | You specify a `template_version_id` at creation                                  | The agent auto-selects a template and provisions on demand |
| Template requirements  | Requires `coder_ai_task` resource, `coder_task` data source, and an agent module | Any template with a clear description works                |
| Chat state             | Stored in the workspace (AgentAPI state file)                                    | Persisted in the Coder database                            |
| Conversation model     | Single prompt with optional follow-up input                                      | Multi-turn chat with message history, queuing, and editing |
| Real-time updates      | HTTP polling (`GET .../logs`)                                                    | WebSocket streaming (`GET .../stream`)                     |
| Sub-agents             | Not supported                                                                    | Built-in sub-agent delegation                              |

## Endpoint mapping

The table below maps each Tasks API endpoint to its Chats API equivalent.

| Operation         | Tasks API                                 | Chats API                                                           |
|-------------------|-------------------------------------------|---------------------------------------------------------------------|
| List              | `GET /api/v2/tasks`                       | `GET /api/experimental/chats`                                       |
| Create            | `POST /api/v2/tasks/{user}`               | `POST /api/experimental/chats`                                      |
| Get by ID         | `GET /api/v2/tasks/{user}/{task}`         | `GET /api/experimental/chats/{chat}`                                |
| Delete            | `DELETE /api/v2/tasks/{user}/{task}`      | `PATCH /api/experimental/chats/{chat}` with `{"archived": true}`    |
| Send follow-up    | `POST /api/v2/tasks/{user}/{task}/send`   | `POST /api/experimental/chats/{chat}/messages`                      |
| Update input      | `PATCH /api/v2/tasks/{user}/{task}/input` | `PATCH /api/experimental/chats/{chat}/messages/{message}`           |
| Get logs / stream | `GET /api/v2/tasks/{user}/{task}/logs`    | `GET /api/experimental/chats/{chat}/stream` (WebSocket)             |
| Pause             | `POST /api/v2/tasks/{user}/{task}/pause`  | `POST /api/experimental/chats/{chat}/interrupt`                     |
| Resume            | `POST /api/v2/tasks/{user}/{task}/resume` | `POST /api/experimental/chats/{chat}/messages` (send a new message) |
| Watch all         | n/a                                       | `GET /api/experimental/chats/watch` (WebSocket)                     |
| Get messages      | n/a                                       | `GET /api/experimental/chats/{chat}/messages`                       |
| List models       | n/a                                       | `GET /api/experimental/chats/models`                                |
| Upload file       | n/a                                       | `POST /api/experimental/chats/files`                                |

## Migration steps

### 1. Configure an LLM provider

With Tasks, LLM credentials are injected into the workspace as environment
variables (e.g. `ANTHROPIC_API_KEY`). With Coder Agents, credentials are
configured once in the control plane:

1. Navigate to the **Agents** page in the Coder dashboard.
1. Open **Settings** > **Manage Agents** > **Providers**, pick a provider,
   enter your API key, and save.
1. Under **Models**, add at least one model and set it as the default.

You no longer pass API keys in template variables or workspace environment. See https://coder.com/docs/ai-coder/agents/getting-started for more information.

### 2. Update task creation calls

**Tasks API**. You specify the user, template version, and a prompt
string:

```sh
# Tasks API: create a task
curl -X POST https://coder.example.com/api/v2/tasks/me \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "template_version_id": "<template-version-uuid>",
    "input": "Fix the failing tests in the auth service"
  }'
```

**Chats API**. You send structured content parts. No template or user
path segment is required:

```sh
# Chats API: create a chat
curl -X POST https://coder.example.com/api/experimental/chats \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "<your-org-id>",
    "content": [
      {"type": "text", "text": "Fix the failing tests in the auth service"}
    ]
  }'
```

Key differences:

- The `{user}` path parameter is removed. The authenticated user is
  inferred from the session token.
- `organization_id` is required in the request body. The caller must be a
  member of that organization.
- The prompt is now an array of `ChatInputPart` objects (supporting `text`,
  `file`, and `file-reference` types) instead of a plain string.
- `template_version_id` and `template_version_preset_id` are removed. The
  agent selects a template automatically based on the prompt and available
  template descriptions. To pin to a specific workspace, pass
  `workspace_id` instead.
- Optionally pass `model_config_id` to override the default model, or
  `mcp_server_ids` to attach MCP servers.

### 3. Update follow-up message calls

**Tasks API**. Follow-ups use the send endpoint with a plain string:

```sh
# Tasks API: send input
curl -X POST https://coder.example.com/api/v2/tasks/me/my-task/send \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"input": "Now also update the integration tests"}'
```

**Chats API**. Follow-ups use the messages endpoint with content parts:

```sh
# Chats API: send a message
curl -X POST \
  https://coder.example.com/api/experimental/chats/$CHAT_ID/messages \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [
      {"type": "text", "text": "Now also update the integration tests"}
    ]
  }'
```

The Chats API supports message queuing. If the agent is busy, the message
is queued automatically and delivered when the agent finishes its current
step. The response includes a `queued` field indicating whether the message
was delivered immediately or queued.

### 4. Switch from log polling to WebSocket streaming

**Tasks API**. You poll for logs:

```sh
# Tasks API: get logs
curl https://coder.example.com/api/v2/tasks/me/my-task/logs \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```

**Chats API**. You open a one-way WebSocket connection:

```text
GET wss://coder.example.com/api/experimental/chats/{chat}/stream
```

The WebSocket sends JSON envelopes with a `type` field (`"ping"`,
`"data"`, or `"error"`). Data envelopes contain batches of events:

| Event type     | Description                                             |
|----------------|---------------------------------------------------------|
| `message_part` | A chunk of the agent's response (text, tool call, etc.) |
| `message`      | A complete message has been persisted                   |
| `status`       | The chat status changed (e.g. `running` → `waiting`)    |
| `error`        | An error occurred during processing                     |
| `retry`        | The server is retrying a failed LLM call                |
| `queue_update` | The queued message list changed                         |

Use `after_id` as a query parameter when reconnecting to skip messages the
client already has.

### 5. Update status handling

Task and chat statuses use different values. The Chats API status set is
defined in `codersdk.ChatStatus`:

| Tasks API status | Chats API status  | Notes                                                                                                                                                                                                                         |
|------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `pending`        | `pending`         | Queued for processing.                                                                                                                                                                                                        |
| `running`        | `running`         | Agent is actively working.                                                                                                                                                                                                    |
| `complete`       | `waiting`         | Idle. Newly created, finished successfully, or interrupted. This is the default idle state.                                                                                                                                   |
| `paused`         | n/a               | The Tasks API pause stops the workspace; the Chats API equivalent is `interrupt` plus separate workspace lifecycle. The `paused` enum value exists in code but no production path on `main` transitions a chat into it today. |
| `failed`         | `error`           | Agent encountered an error.                                                                                                                                                                                                   |
| n/a              | `requires_action` | Agent invoked a client-provided tool and is waiting for the result before continuing.                                                                                                                                         |

The Chats API uses `waiting` as the default idle state (not `complete`).
A chat enters `waiting` when it is first created (before any message is
queued) and again whenever a run finishes or is interrupted, so treat
`waiting` as "the agent is not currently working" rather than only "the
agent just finished." The `completed` enum value is also defined but is
not currently set by any production code path on `main`.

### 6. Replace delete with archive

The Tasks API uses `DELETE` to remove a task. The Chats API uses archiving:

```diff
- curl -X DELETE https://coder.example.com/api/v2/tasks/me/my-task \
-   -H "Coder-Session-Token: $CODER_SESSION_TOKEN"

+ curl -X PATCH https://coder.example.com/api/experimental/chats/$CHAT_ID \
+   -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
+   -H "Content-Type: application/json" \
+   -d '{"archived": true}'
```

Archived chats can be restored by setting `archived` to `false`.

### 7. Replace pause/resume with interrupt and messaging

**Tasks API**. Pause and resume stop and start the workspace:

```sh
# Tasks API
curl -X POST \
  https://coder.example.com/api/v2/tasks/me/my-task/pause \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"

curl -X POST \
  https://coder.example.com/api/v2/tasks/me/my-task/resume \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```

**Chats API**. Interrupt stops the current agent loop. Sending a new
message resumes processing:

```sh
# Chats API: interrupt
curl -X POST \
  https://coder.example.com/api/experimental/chats/$CHAT_ID/interrupt \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"

# Chats API: resume by sending a new message
curl -X POST \
  https://coder.example.com/api/experimental/chats/$CHAT_ID/messages \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [
      {"type": "text", "text": "Continue where you left off"}
    ]
  }'
```

In the Tasks API, pausing stops the workspace and frees compute. In the
Chats API, interrupt stops the agent loop in the control plane; the
workspace may remain running. The workspace lifecycle is managed
independently.

### 8. Update GitHub Actions integrations

If you use the
[Create Task Action](https://github.com/coder/create-task-action) GitHub
Action, replace it with the dedicated
[`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action).
It handles the API call, the GitHub user lookup, and the optional issue
comment, so most existing workflows can swap one `uses:` line and rename
a few inputs.

We are actively shipping new features for `create-agent-chat-action`, so
pin to a major version (for example `@v0`) and watch the
[releases](https://github.com/coder/create-agent-chat-action/releases) for
updates.

```diff
# .github/workflows/triage-bug.yaml
jobs:
  coder-create-task:
    runs-on: ubuntu-latest
    if: github.event.label.name == 'coder'
    steps:
-     - name: Coder Create Task
-       uses: coder/create-task-action@v0
-       with:
-         coder-url: ${{ secrets.CODER_URL }}
-         coder-token: ${{ secrets.CODER_TOKEN }}
-         coder-organization: "default"
-         coder-template-name: "my-template"
-         coder-task-name-prefix: "gh-task"
-         coder-task-prompt: >-
-           Use the gh CLI to read
-           ${{ github.event.issue.html_url }},
-           fix the issue, and create a PR.
-         github-user-id: ${{ github.event.sender.id }}
-         github-issue-url: ${{ github.event.issue.html_url }}
-         github-token: ${{ github.token }}
-         comment-on-issue: true
+     - name: Coder Create Agent Chat
+       uses: coder/create-agent-chat-action@v0
+       with:
+         coder-url: ${{ secrets.CODER_URL }}
+         coder-token: ${{ secrets.CODER_TOKEN }}
+         chat-prompt: >-
+           Use the gh CLI to read
+           ${{ github.event.issue.html_url }},
+           fix the issue, and create a PR.
+         github-user-id: ${{ github.event.sender.id }}
+         github-issue-url: ${{ github.event.issue.html_url }}
+         github-token: ${{ github.token }}
+         comment-on-issue: true
```

Key differences from the Tasks GHA:

- No `coder-template-name` or `coder-task-name-prefix`. The agent
  auto-provisions a workspace; pass `workspace-id` if you want to pin to
  an existing workspace instead.
- The prompt input is renamed from `coder-task-prompt` to `chat-prompt`.
- LLM credentials are no longer passed through the template. They are
  configured in the Coder control plane.
- Identify the user with `github-user-id` (the action resolves it to a
  Coder user via the GitHub OAuth link) or with `coder-username`
  directly.

See the
[action README](https://github.com/coder/create-agent-chat-action#inputs)
for the full input and output reference, including the `existing-chat-id`
input for sending follow-up messages on a previous chat.

## Template recommendations

<!-- NEEDS REVIEW: This section contains initial recommendations based on
     the current Coder Agents architecture. Platform teams should validate
     these against their own deployment patterns before adopting them. -->

> [!NOTE]
> This section contains recommendations that may evolve as Coder Agents
> matures. Review these against your deployment requirements.

With Coder Tasks, every task-capable template requires specific Terraform
resources (`coder_ai_task`, `coder_task`, agent modules, and LLM API
keys). With Coder Agents, templates no longer need any of these. The
agent runs in the control plane and treats the workspace as plain compute.

However, **we still recommend creating dedicated templates for agent
workloads** rather than reusing your standard developer templates
unchanged. The reasons are different from Tasks, but the principle holds:

### Why dedicated agent templates still matter

- **Network boundaries.** Agent workspaces inherit whatever network access
  the template allows. Because the agent does not need outbound access to
  LLM providers (that happens in the control plane), you can lock down
  agent templates to only reach the Coder control plane and your git
  provider. Standard developer templates typically allow broader access.
- **No IDE tooling overhead.** The agent connects via the workspace
  daemon's HTTP API, not through VS Code or JetBrains. Removing IDE
  extensions, desktop environments, and similar tooling from agent
  templates reduces image size and startup time.
- **Scoped credentials.** Agent workloads may warrant more restrictive
  credentials than interactive developer sessions. A dedicated template
  lets you provide a separate, narrower-scoped git token or service
  account without affecting your developers' workflow.
- **Cost control.** Agent workspaces can often use smaller compute
  resources than developer workspaces since they don't need to run IDEs,
  language servers, or other interactive tooling. A dedicated template lets
  you right-size the infrastructure.

### What to include in agent templates

<!-- TODO: Expand this section with concrete Terraform examples once
     template patterns stabilize. -->

- **Clear descriptions.** The agent selects templates by reading names and
  descriptions. Include the target language, framework, repository, and
  type of work. For example: *"Python backend services for the payments
  repo. Includes Poetry, Python 3.12, and PostgreSQL."*
- **Pre-installed dependencies.** Language runtimes, build tools, `git`,
  and project-specific dependencies should be baked into the image. Time
  the agent spends installing tools is time not spent on the task.
- **Git configuration.** Ensure `git` is configured with credentials and
  author information so the agent can commit and push without additional
  setup.
- **Minimal parameters.** Use sensible defaults so the agent can provision
  workspaces without guessing. Avoid required parameters with opaque
  identifiers.

### What to remove from migrated task templates

If you are converting an existing task template for use with Coder Agents,
you can safely remove the Tasks-specific Terraform resources. They are
unused when the chat is driven by the Chats API:

```diff
  terraform {
    required_providers {
      coder = {
        source  = "coder/coder"
-       version = ">= 2.13"
+       version = ">= 2.13"
      }
    }
  }

- data "coder_task" "me" {}
-
- resource "coder_ai_task" "task" {
-   app_id = module.claude-code.task_app_id
- }
-
- module "claude-code" {
-   source         = "registry.coder.com/coder/claude-code/coder"
-   version        = "4.0.0"
-   agent_id       = coder_agent.main.id
-   ai_prompt      = data.coder_task.me.prompt
-   claude_api_key = var.anthropic_api_key
- }
-
- variable "anthropic_api_key" {
-   type        = string
-   description = "Anthropic API key"
-   sensitive   = true
- }

  resource "coder_agent" "main" {
    os   = "linux"
    arch = "amd64"
+   # No agent modules, no AgentAPI, no LLM keys needed.
+   # The Coder Agents control plane handles the agent loop.
  }
```

> [!TIP]
> You do not have to remove these resources immediately. Templates can
> serve both Tasks and Chats simultaneously during a transition period.
> The Tasks-specific resources are simply unused when work comes through
> the Chats API.

See
[Template Optimization](./platform-controls/template-optimization.md)
for the full guide on writing discoverable descriptions, configuring
network boundaries, scoping credentials, and pre-installing dependencies.

### Pre-creating a workspace for deterministic results

Letting the agent pick a template and provision a workspace works well
for exploratory chats. If your workflow requires deterministic results like:

- Automations
- Recurring processes
- Generally any case that needs a known reproducible environment

pre-create the workspace yourself and attach it when you create the chat.

The pattern is two API calls:

1. Create a workspace from a specific template via
   [`POST /api/v2/users/{user}/workspaces`](../../reference/api/workspaces.md#create-user-workspace).
   You control the template, the version, and any rich parameters.
2. Create the chat with `workspace_id` set to the workspace you just
   created. The agent runs against that workspace instead of selecting
   one heuristically.

```sh
# 1. Provision the workspace from the exact template you want.
WORKSPACE_ID=$(curl -s -X POST \
  https://coder.example.com/api/v2/users/me/workspaces \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "<your-agent-template-uuid>",
    "name": "agent-run-${GITHUB_RUN_ID}"
  }' | jq -r '.id')

# 2. Create the chat bound to that workspace.
curl -s -X POST https://coder.example.com/api/experimental/chats \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"organization_id\": \"<your-org-id>\",
    \"workspace_id\": \"$WORKSPACE_ID\",
    \"content\": [
      {\"type\": \"text\", \"text\": \"Fix the failing tests in the auth service\"}
    ]
  }"
```

This pattern is the closest analogue to the Tasks API behavior of
`template_version_id` plus `coder-template-name`: you decide which
template runs, the agent decides what to do inside it. The same approach
works from the
[`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action)
GHA, which exposes the same pin via its `workspace-id` input.

## How to test your migration

After completing the migration steps above, walk through these checks to
confirm the Chats API integration is working end-to-end.

### 1. Confirm LLM provider connectivity

List available models to verify at least one provider is configured and
reachable:

```sh
curl -s https://coder.example.com/api/experimental/chats/models \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '.[].display_name'
```

If this returns an empty list or an error, revisit
[Step 1: Configure an LLM provider](#1-configure-an-llm-provider).

### 2. Create a chat and confirm the response

Create a simple chat that does not require a workspace:

```sh
curl -s -X POST https://coder.example.com/api/experimental/chats \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [{"type": "text", "text": "What is 2 + 2?"}]
  }' | jq '{id, status, title}'
```

You should receive a `Chat` object with `status` set to `"waiting"` or
`"pending"`. Save the `id` for subsequent steps.

### 3. Stream the response

Open a WebSocket connection to verify the agent processes the prompt and
returns a response. Using [websocat](https://github.com/vi/websocat):

```sh
websocat -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  "wss://coder.example.com/api/experimental/chats/$CHAT_ID/stream"
```

You should see JSON envelopes with `"type": "data"` containing
`message_part` and `status` events. The chat should eventually reach
`"waiting"` status, indicating the agent completed its response.

### 4. Send a follow-up message

Verify multi-turn conversation works:

```sh
curl -s -X POST \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID/messages" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [{"type": "text", "text": "Now multiply that by 10"}]
  }' | jq '{queued}'
```

The response should include `"queued": false` (delivered immediately) or
`"queued": true` (agent was busy. The message is queued and will be
processed next).

### 5. Test workspace provisioning

Create a workspace from your converted agent template through the
standard Coder UI, then attach it to a new chat from the chat composer:

1. In the Coder dashboard, create a workspace from the agent template
   you migrated.
2. Open **Agents** and start a new chat.
3. In the composer, use the workspace picker to attach the workspace you
   just created.
4. Send a prompt that exercises the workspace, for example: *"List the
   files in the root directory of this workspace."*

The response stream should show the agent invoking workspace tools (such
as `execute`) against the attached workspace. After the chat finishes,
verify the chat is bound to the workspace via the API:

```sh
curl -s "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '{workspace_id, status}'
```

A `workspace_id` matching the workspace you attached confirms the chat
is driving that workspace end-to-end. Auto-provisioning from the chat
flow is also supported but is easier to verify once the manual-attach
path is working.

### 6. Verify interrupt works

Start a long-running chat and interrupt it:

```sh
curl -s -X POST \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID/interrupt" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```

Then confirm the chat status returns to `"waiting"`:

```sh
curl -s "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '.status'
```

### 7. Validate archive and restore

```sh
# Archive
curl -s -X PATCH \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"archived": true}'

# Confirm it no longer appears in the default list
curl -s "https://coder.example.com/api/experimental/chats" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  | jq --arg id "$CHAT_ID" '[.[] | select(.id == $id)] | length'
# Should return 0

# Restore
curl -s -X PATCH \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"archived": false}'
```

### Quick checklist

Use this checklist to confirm each part of your integration:

- [ ] At least one LLM model is configured and returned by `/chats/models`
- [ ] `POST /chats` creates a chat and returns a valid `Chat` object
- [ ] WebSocket stream at `/chats/{chat}/stream` delivers events
- [ ] Follow-up messages via `/chats/{chat}/messages` are accepted
- [ ] Chat attached to a workspace from the converted template runs
      tools against that workspace
- [ ] `POST /chats/{chat}/interrupt` stops the agent and returns to `waiting`
- [ ] Archive and restore via `PATCH /chats/{chat}` works
- [ ] (If applicable) GitHub Actions workflow creates chats successfully

## Features available only in the Chats API

The Chats API includes capabilities that have no equivalent in the Tasks
API:

| Feature                              | Description                                                                    |
|--------------------------------------|--------------------------------------------------------------------------------|
| **WebSocket streaming**              | Real-time event stream via `GET /chats/{chat}/stream` instead of HTTP polling  |
| **Watch all chats**                  | `GET /chats/watch` pushes events for all chats owned by the user               |
| **Message editing**                  | `PATCH /chats/{chat}/messages/{message}` to edit a sent message and re-process |
| **Message queuing**                  | Follow-up messages are automatically queued when the agent is busy             |
| **File uploads**                     | Attach images via `POST /chats/files` and reference them in messages           |
| **Model selection**                  | `GET /chats/models` to discover models; override per-chat or per-message       |
| **MCP server attachment**            | Attach MCP servers to a chat for tool augmentation                             |
| **Labels**                           | Key-value metadata on chats for filtering (`label` query parameter)            |
| **Sub-agents**                       | Agent can spawn child agents for parallel work                                 |
| **Diff/PR tracking**                 | `GET /chats/{chat}/diff` returns change tracking and PR metadata               |
| **Title regeneration**               | `POST /chats/{chat}/title/regenerate`                                          |
| **Pinning**                          | Pin and reorder chats via the `pin_order` field                                |
| **Automatic workspace provisioning** | No workspace needed for Q&A. Provisioned only when the agent needs to act      |

## Response schema changes

The Tasks API returns a `Task` object with workspace-centric fields. The
Chats API returns a `Chat` object with conversation-centric fields:

| Tasks API field    | Chats API equivalent                          | Notes                                                            |
|--------------------|-----------------------------------------------|------------------------------------------------------------------|
| `id`               | `id`                                          | Both are UUIDs                                                   |
| `initial_prompt`   | First message in `GET /chats/{chat}/messages` | Prompt is a message, not a top-level field                       |
| `display_name`     | `title`                                       | Auto-generated or set via `PATCH`                                |
| `status`           | `status`                                      | Different enum values (see status table above)                   |
| `current_state`    | Latest `status` event from the stream         | No equivalent top-level field                                    |
| `workspace_id`     | `workspace_id`                                | Nullable in Chats. May be `null` if no workspace was provisioned |
| `workspace_status` | n/a                                           | Manage workspace lifecycle separately                            |
| `template_id`      | n/a                                           | Not exposed; the agent selects templates internally              |
| `owner_id`         | `owner_id`                                    | Same concept                                                     |
| `name`             | n/a                                           | Chats use `id` for identification, not human-readable names      |

## CLI changes

The Tasks CLI (`coder task`) and the Coder Agents CLI are separate. Coder
ships an experimental TUI for Coder Agents at `coder exp agents` (planned
to graduate to `coder agents` in the May Beta release per
[#24432](https://github.com/coder/coder/pull/24432)). The TUI talks to the
same `/api/experimental/chats` endpoints documented in this guide; for
automation, prefer direct API calls.

| Tasks CLI           | Chats equivalent                        |
|---------------------|-----------------------------------------|
| `coder task create` | `coder exp agents` TUI or `POST /chats` |
| `coder task list`   | `coder exp agents` TUI or `GET /chats`  |
| `coder task logs`   | `GET /chats/{chat}/stream` (WebSocket)  |
| `coder task pause`  | `POST /chats/{chat}/interrupt`          |
| `coder task resume` | Send a follow-up message to the chat    |

> [!NOTE]
> The Coder Agents CLI today is an interactive TUI rather than a set of
> per-action subcommands like `coder task`. Use `curl`, the SDK, or your
> HTTP client of choice for non-interactive automation. Dedicated
> non-interactive subcommands may be added in a future release.

---

# AI Governance Add-On

Source: https://coder.com/docs/ai-coder/ai-governance

# AI Governance Add-On (Premium)

Coder Workspaces already lets teams run AI tools like
[Cursor](https://registry.coder.com/modules/coder/cursor) and
[Claude Code](https://registry.coder.com/modules/coder/claude-code) inside their
development environments. As adoption grows, many enterprises also need
observability, management, and policy controls to support secure and auditable
AI rollouts.

The AI Governance Add-On is a per-user license that can be added to Premium seats. Each user with the add-on gets access to a set of features
that help organizations safely roll out AI tooling at scale:

- [AI Gateway](./ai-gateway/index.md): LLM gateway to audit AI sessions, central
  MCP server management, and policy enforcement
- [Agent Firewall](./agent-firewall/index.md): Process-level firewalls for
  agents, restricting which domains can be accessed by AI agents

## Who should use the AI Governance Add-On

The AI Governance Add-On is for teams that want to extend that platform to
support AI-powered IDEs and coding agents in a controlled, observable way.

It's a good fit if you're:

- Rolling out AI-powered IDEs like Cursor and AI coding agents like Claude Code
  across teams
- Looking to centrally observe, audit, and govern AI activity in Coder
  Workspaces
- Managing AI workflows against sensitive or regulated codebases

If you already use other AI Governance tools, such as third-party LLM gateways
or vendor-managed policies, you can continue using them. Coder Workspaces can
still serve as the backend for development environments and AI workflows, with
or without the AI Governance Add-On.

## Use cases for AI Governance

Organizations adopting AI coding tools at scale often encounter operational and
security challenges that traditional developer tooling doesn't address.

### Auditing AI activity across teams

Without centralized monitoring, teams have no way to understand how AI tools are
being used across the organization. AI Gateway provides audit trails of prompts,
token usage, and tool invocations, giving administrators insight into AI
adoption patterns and potential issues.

### Restricting agent network and command access

AI agents can make arbitrary network requests, potentially accessing
unauthorized services or exfiltrating data. They can also execute destructive
commands within a workspace. Agent Firewall enforces process-level policies
that restrict which domains agents can reach and what actions they can perform,
preventing unintended data exposure and destructive operations like `rm -rf`.

### Centralizing API key management

Managing individual API keys for AI providers across hundreds of developers
creates security risks and administrative overhead. AI Gateway centralizes
authentication so users authenticate through Coder, eliminating the need to
distribute and rotate provider API keys.

### Standardizing MCP tools and servers

Different teams may use different MCP servers and tools with varying security
postures. AI Gateway enables centralized MCP administration, allowing
organizations to define approved tools and servers that all users can access.

### Measuring AI adoption and spend

Without usage data, it's hard to justify AI tooling investments or identify
high-leverage use cases. AI Gateway captures metrics on token spend, adoption
rates, and usage patterns to inform decisions about AI strategy.

## GA status and availability

Starting with Coder v2.30 (February 2026), AI Gateway and Agent Firewall are
generally available as part of the AI Governance Add-On.

The AI Governance add-on is required to use AI Gateway and Agent Firewall.
If your deployment does not have the add-on, you'll see a notification banner
reminding you to enable it.

To learn more about enabling the AI Governance Add-On, pricing, or trial
options, reach out to your
[Coder account team](https://coder.com/contact/sales).

## How Coder Tasks usage is measured

> [!NOTE]
> There is a known issue with how Agent Workspace Builds are tallied in v2.28
> and v2.29. We recommend updating to v2.28.9, v2.29.4, or v2.30 to resolve
> this issue.

The usage metric used to measure Coder Tasks consumption is called **Agent
Workspace Builds** (prev. "managed agents").

An Agent Workspace Build is counted each time a workspace is started
specifically for a coding agent to independently work on a Coder Task. Most of
the work in this workspace is performed by the agent, not a human developer.
Each Coder Task starts its own workspace, and the usage meter counts one Agent
Workspace Build.

Traditional Coder Workspaces started manually by developers or scheduled to
auto-start do not count as an Agent Workspace Build. These are considered
daily-driver development environments where developers co-exist with their IDEs
and coding assistants.

### Scenarios

| Scenario                                                                                          | Consumes Agent Workspace Build |
|---------------------------------------------------------------------------------------------------|--------------------------------|
| Developer creates a Coder Task to write end-to-end tests                                          | Yes                            |
| Automated pipeline creates a task via Coder Tasks CLI (with Claude Code) to review a pull request | Yes                            |
| Developer resumes an old Coder Task order to continue prototyping                                 | Yes                            |
| Developer starts a workspace for use with VS Code and Jupyter                                     | No                             |
| Developer creates a workspace for use with Cursor and Claude Code CLI                             | No                             |
| Developer creates a workspace for use with Coder AI Gateway and Agent Firewall                    | No                             |

In the future, additional capabilities for managing agents (beyond Coder Tasks)
may also consume agent workspace builds.

### Agent Workspace Build Limits

Without proper controls and sandboxing, it is not recommended to open up Coder
Tasks to a large audience in the enterprise. Both Community and Premium
deployments include 1,000 Agent Workspace Builds, primarily for proof-of-concept
use and basic workflows. Community deployments do not have access to
[AI Gateway](./ai-gateway/index.md) or [Agent Firewall](./agent-firewall/index.md).

Our [AI Governance Add-On](./ai-governance.md) includes a shared usage pool of
Agent Workspace Builds for automated workflows, along with limits that scale
proportionately with user count. Usage counts are measured and sent to Coder via
[usage data reporting](./usage-data-reporting.md). Coder Tasks and other AI
features continue to function normally even if the limit is breached. Admins
will receive a warning to [contact their account team](https://coder.com/contact)
to remediate.

### Tracking Agent Workspace Builds

Admins can monitor Agent Workspace Build usage from the Coder dashboard.
Navigate to **Deployment** > **Licenses** to view current usage against your
entitlement limits.

![Agent Workspace Build usage](../images/admin/ai-governance-awb-usage.png)

<small>Agent Workspace Build usage showing current consumption against
entitlement limits in the Licenses page.</small>

## Identifying AI seat consumers

When the AI Governance add-on is licensed, the **Users** table and
**Organization Members** table display an **AI add-on** column that shows
whether each user is consuming an AI seat:

- A green check icon indicates the user is actively consuming an AI seat.
- A gray X icon indicates the user is not consuming an AI seat.

A user consumes an AI seat when they use AI features such as AI Gateway or
Tasks. The column helps administrators identify which users contribute to
the organization's AI seat count, making it easier to manage seat
allocations and stay within license limits.

The **AI add-on** column only appears when the deployment has an active
`ai_governance_user_limit` entitlement. If the entitlement is not present
or the license has expired, the column is hidden.

> **Tip:** Hover over the **AI add-on** column header for a tooltip
> describing what the column represents.

---

# Agent Firewall

Source: https://coder.com/docs/ai-coder/agent-firewall

# Agent Firewall

Agent Firewall is a process-level firewall that restricts and audits what
autonomous programs, such as AI agents, can access and use.

![Screenshot of Agent Firewall blocking a process](../../images/guides/ai-agents/boundary.png)Example
of Agent Firewall blocking a process.

> [!NOTE]
> Agent Firewall was previously known as "Agent Boundaries". Some
> configuration options and internal references still use the old name
> and will be updated in a future release.

## Supported Agents

Agent Firewall supports the securing of any terminal-based agent, including
your own custom agents.

## Features

Agent Firewall offers network policy enforcement, which blocks domains and HTTP
verbs to prevent exfiltration, and writes logs to the workspace.

Agent Firewall also streams audit logs to Coder's control plane for centralized
monitoring of HTTP requests.

## Getting Started with Agent Firewall

The easiest way to use Agent Firewall is through existing Coder modules, such
as the
[Claude Code module](https://registry.coder.com/modules/coder/claude-code). It
can also be ran directly in the terminal by installing the
[CLI](https://github.com/coder/boundary).

## Configuration

> [!NOTE]
> For information about version requirements and compatibility, see the [Version Requirements](./version.md) documentation.

Agent Firewall is configured using a `config.yaml` file. This allows you to
maintain allow lists and share detailed policies with teammates.

In your Terraform module, enable Agent Firewall with minimal configuration:

```tf
module "claude-code" {
  source              = "dev.registry.coder.com/coder/claude-code/coder"
  version             = "4.7.0"
  enable_boundary     = true
}
```

Create a `config.yaml` file in your template directory with your policy. For the
Claude Code module, use the following minimal configuration:

```yaml
allowlist:
  - "domain=dev.coder.com" # Required - use your Coder deployment domain
  - "domain=api.anthropic.com" # Required - API endpoint for Claude
  - "domain=statsig.anthropic.com" # Required - Feature flags and analytics
  - "domain=claude.ai" # Recommended - WebFetch/WebSearch features
  - "domain=*.sentry.io" # Recommended - Error tracking (helps Anthropic fix bugs)
jail_type: nsjail
log_dir: /tmp/boundary_logs
proxy_port: 8087
log_level: warn
```

For a basic recommendation of what to allow for agents, see the
[Anthropic documentation on default allowed domains](https://code.claude.com/docs/en/claude-code-on-the-web#default-allowed-domains).
For a comprehensive example of a production Agent Firewall configuration, see
the
[Coder dogfood policy example](https://github.com/coder/coder/blob/main/dogfood/coder/boundary-config.yaml).

Add a `coder_script` resource to mount the configuration file into the workspace
filesystem:

```tf
resource "coder_script" "boundary_config_setup" {
  agent_id     = coder_agent.dev.id
  display_name = "Boundary Setup Configuration"
  run_on_start = true

  script = <<-EOF
    #!/bin/sh
    mkdir -p ~/.config/coder_boundary
    echo '${base64encode(file("${path.module}/config.yaml"))}' | base64 -d > ~/.config/coder_boundary/config.yaml
    chmod 600 ~/.config/coder_boundary/config.yaml
  EOF
}
```

Agent Firewall automatically reads `config.yaml` from
`~/.config/coder_boundary/` when it starts, so everyone who launches Agent
Firewall manually inside the workspace picks up the same configuration without
extra flags. This is especially convenient for managing extensive allow lists in
version control.

### Configuration Parameters

- `allowlist` defines the URLs that the agent can access, in addition to the
  default URLs required for the agent to work. Rules use the format
  `"key=value [key=value ...]"`:
  - `domain=github.com` - allows the domain and all its subdomains
  - `domain=*.github.com` - allows only subdomains (the specific domain is
    excluded)
  - `method=GET,HEAD domain=api.github.com` - allows specific HTTP methods for a
    domain
  - `method=POST domain=api.example.com path=/users,/posts` - allows specific
    methods, domain, and paths
  - `path=/api/v1/*,/api/v2/*` - allows specific URL paths
- `jail_type` selects the isolation backend. Valid values: `nsjail` (default),
  `landjail`. See [Jail Types](#jail-types) for a detailed comparison.
- `log_dir` defines where boundary writes log files.
- `log_level` defines the verbosity at which requests are logged. Agent
  Firewall uses the following verbosity levels:
  - `WARN`: logs only requests that have been blocked by Agent Firewall
  - `INFO`: logs all requests at a high level
  - `DEBUG`: logs all requests in detail
- `no_user_namespace` disables creation of a user namespace inside the jail.
  Enable this in restricted environments that disallow user namespaces, such
  as Bottlerocket nodes in EKS auto-mode. Only applies to the `nsjail` jail
  type.
- `proxy_port` defines the port used by the HTTP proxy. Default: `8080`.
- `use_real_dns` uses the host's real DNS resolver inside the jail instead of
  the built-in dummy DNS server. This allows DNS resolution for non-proxied
  traffic but permits DNS-based data exfiltration. Default: `false`.

For detailed information about the rules engine and how to construct allowlist
rules, see the [rules engine documentation](./rules-engine.md).

You can also run Agent Firewall directly in your workspace and configure it
per template. You can do so by installing the
[binary](https://github.com/coder/boundary) into the workspace image or at
start-up. You can do so with the following command:

```bash
curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | bash
```

## Jail Types

Agent Firewall supports two different jail types for process isolation, each
with different characteristics and requirements:

1. **nsjail** - Uses Linux namespaces for isolation. This is the default jail
   type and provides network namespace isolation. See
   [nsjail documentation](./nsjail/index.md) for detailed information about runtime
   requirements and Docker configuration.

2. **landjail** - Uses Landlock V4 for network isolation. This provides network
   isolation through the Landlock Linux Security Module (LSM) without requiring
   network namespace capabilities. See [landjail documentation](./landjail.md)
   for implementation details.

The choice of jail type depends on your security requirements, available Linux
capabilities, and runtime environment. Both nsjail and landjail provide network
isolation, but they use different underlying mechanisms. nsjail uses Linux
namespaces, while landjail uses Landlock V4. Landjail may be preferred in
environments where namespace capabilities are limited or unavailable.

## Implementation Comparison: Namespaces+iptables vs Landlock V4

| Aspect                        | Namespace Jail (Namespaces + veth-pair + iptables)                                | Landlock V4 Jail                                                        |
|-------------------------------|-----------------------------------------------------------------------------------|-------------------------------------------------------------------------|
| **Privileges**                | Requires `CAP_NET_ADMIN`                                                          | ✅ No special capabilities required                                      |
| **Docker seccomp**            | ❌ Requires seccomp profile modifications or sysbox-runc                           | ✅ Works without seccomp changes                                         |
| **Kernel requirements**       | Linux 3.8+ (widely available)                                                     | ❌ Linux 6.7+ (very new, limited adoption)                               |
| **Bypass resistance**         | ✅ Strong - transparent interception prevents bypass                               | ❌ **Medium - can bypass by connecting to `evil.com:<HTTP_PROXY_PORT>`** |
| **Process isolation**         | ✅ PID namespace (processes can't see/kill others); **implementation in-progress** | ❌ No PID namespace (agent can kill other processes)                     |
| **Non-TCP traffic control**   | ✅ Can block/control UDP via iptables; **implementation in-progress**              | ❌ No control over UDP (data can leak via UDP)                           |
| **Application compatibility** | ✅ Works with ANY application (transparent interception)                           | ❌ Tools without `HTTP_PROXY` support will be blocked                    |

## Audit Logs

Agent Firewall streams audit logs to the Coder control plane, providing
centralized visibility into HTTP requests made within workspaces—whether from AI
agents or ad-hoc commands run with `boundary`.

Audit logs are independent of application logs:

- **Audit logs** record Agent Firewall's policy decisions: whether each HTTP
  request was allowed or denied based on the allowlist rules. These are always
  sent to the control plane regardless of Agent Firewall's configured log
  level.
- **Application logs** are Agent Firewall's operational logs written locally to
  the workspace. These include startup messages, internal errors, and debugging
  information controlled by the `log_level` setting.

For example, if a request to `api.example.com` is allowed by Agent Firewall
but the remote server returns a 500 error, the audit log records
`decision=allow` because Agent Firewall permitted the request. The HTTP
response status is not tracked in audit logs.

> [!NOTE]
> Requires Coder v2.30+ and Agent Firewall v0.5.2+.

### Audit Log Contents

Each Agent Firewall audit log entry includes:

| Field                 | Description                                                                             |
|-----------------------|-----------------------------------------------------------------------------------------|
| `decision`            | Whether the request was allowed (`allow`) or blocked (`deny`)                           |
| `workspace_id`        | The UUID of the workspace where the request originated                                  |
| `workspace_name`      | The name of the workspace where the request originated                                  |
| `owner`               | The owner of the workspace where the request originated                                 |
| `template_id`         | The UUID of the template that the workspace was created from                            |
| `template_version_id` | The UUID of the template version used by the current workspace build                    |
| `http_method`         | The HTTP method used (GET, POST, PUT, DELETE, etc.)                                     |
| `http_url`            | The fully qualified URL that was requested                                              |
| `event_time`          | Timestamp when boundary processed the request (RFC3339 format)                          |
| `matched_rule`        | The allowlist rule that permitted the request (only present when `decision` is `allow`) |

### Viewing Audit Logs

Agent Firewall audit logs are emitted as structured log entries from the Coder
server. You can collect and analyze these logs using any log aggregation system
such as Grafana Loki.

Example of an allowed request (assuming stderr):

```console
2026-01-16 00:11:40.564 [info]  coderd.agentrpc: boundary_request owner=joe  workspace_name=some-task-c88d agent_name=dev  decision=allow  workspace_id=f2bd4e9f-7e27-49fc-961e-be4d1c2aa987  http_method=GET http_url=https://dev.coder.com  event_time=2026-01-16T00:11:39.388607657Z  matched_rule=domain=dev.coder.com request_id=9f30d667-1fc9-47ba-b9e5-8eac46e0abef trace=478b2b45577307c4fd1bcfc64fad6ffb span=9ece4bc70c311edb
```

---

# NS Jail

Source: https://coder.com/docs/ai-coder/agent-firewall/nsjail

# nsjail Jail Type

nsjail is Agent Firewall's default jail type that uses Linux namespaces to
provide process isolation. It creates unprivileged network namespaces to control
and monitor network access for processes running under Boundary.

**Running on Docker, Kubernetes, or ECS?** See the relevant page for runtime
and permission requirements:

- [nsjail on Docker](./docker.md)
- [nsjail on Kubernetes](./k8s.md)
- [nsjail on ECS](./ecs.md)

## Overview

nsjail leverages Linux namespace technology to isolate processes at the network
level. When Agent Firewall runs with nsjail, it creates a separate network
namespace for the isolated process, allowing Agent Firewall to intercept and
filter all network traffic according to the configured policy.

This jail type requires Linux capabilities to create and manage network
namespaces, which means it has specific runtime requirements when running in
containerized environments like Docker and Kubernetes.

## Architecture

<img width="1228" height="604" alt="Boundary" src="https://github.com/user-attachments/assets/1b7c8c5b-7b8f-4adf-8795-325bd28715c6" />

---

# NS Jail on Docker

Source: https://coder.com/docs/ai-coder/agent-firewall/nsjail/docker

# nsjail on Docker

This page describes the runtime and permission requirements for running Agent
Firewall with the **nsjail** jail type on **Docker**.

For an overview of nsjail, see [nsjail](./index.md).

## Runtime & Permission Requirements for Running Boundary in Docker

This section describes the Linux capabilities and runtime configurations
required to run Agent Firewall with nsjail inside a Docker container.
Requirements vary depending on the OCI runtime and the seccomp profile in use.

### 1. Default `runc` runtime with `CAP_NET_ADMIN`

When using Docker's default `runc` runtime, Agent Firewall requires the
container to have `CAP_NET_ADMIN`. This is the minimal capability needed for
configuring virtual networking inside the container.

Docker's default seccomp profile may also block certain syscalls (such as
`clone`) required for creating unprivileged network namespaces. If you encounter
these restrictions, you may need to update or override the seccomp profile to
allow these syscalls.

[see Docker Seccomp Profile Considerations](#docker-seccomp-profile-considerations)

### 2. Default `runc` runtime with `CAP_SYS_ADMIN` (testing only)

For development or testing environments, you may grant the container
`CAP_SYS_ADMIN`, which implicitly bypasses many of the restrictions in Docker's
default seccomp profile.

- Agent Firewall does not require `CAP_SYS_ADMIN` itself.
- However, Docker's default seccomp policy commonly blocks namespace-related
  syscalls unless `CAP_SYS_ADMIN` is present.
- Granting `CAP_SYS_ADMIN` enables Agent Firewall to run without modifying the
  seccomp profile.

⚠️ Warning: `CAP_SYS_ADMIN` is extremely powerful and should not be used in
production unless absolutely necessary.

### 3. `sysbox-runc` runtime with `CAP_NET_ADMIN`

When using the `sysbox-runc` runtime (from Nestybox), Agent Firewall can run
with only:

- `CAP_NET_ADMIN`

The sysbox-runc runtime provides more complete support for unprivileged user
namespaces and nested containerization, which typically eliminates the need for
seccomp profile modifications.

## Docker Seccomp Profile Considerations

Docker's default seccomp profile frequently blocks the `clone` syscall, which is
required by Agent Firewall when creating unprivileged network namespaces. If
the `clone` syscall is denied, Agent Firewall will fail to start.

To address this, you may need to modify or override the seccomp profile used by
your container to explicitly allow the required `clone` variants.

You can find the default Docker seccomp profile for your Docker version here
(specify your docker version):

https://github.com/moby/moby/blob/v25.0.13/profiles/seccomp/default.json#L628-L635

If the profile blocks the necessary `clone` syscall arguments, you can provide a
custom seccomp profile that adds an allow rule like the following:

```json
{
    "names": ["clone"],
    "action": "SCMP_ACT_ALLOW"
}
```

This example unblocks the clone syscall entirely.

### Example: Overriding the Docker Seccomp Profile

To use a custom seccomp profile, start by downloading the default profile for
your Docker version:

https://github.com/moby/moby/blob/v25.0.13/profiles/seccomp/default.json#L628-L635

Save it locally as seccomp-v25.0.13.json, then insert the clone allow rule shown
above (or add "clone" to the list of allowed syscalls).

Once updated, you can run the container with the custom seccomp profile:

```bash
docker run -it \
  --cap-add=NET_ADMIN \
  --security-opt seccomp=seccomp-v25.0.13.json \
  test bash
```

This instructs Docker to load your modified seccomp profile while granting only
the minimal required capability (`CAP_NET_ADMIN`).

---

# NS Jail on Kubernetes

Source: https://coder.com/docs/ai-coder/agent-firewall/nsjail/k8s

# nsjail on Kubernetes

This page describes the runtime and permission requirements for running Agent
Firewall with the **nsjail** jail type on **Kubernetes**.

## Runtime & Permission Requirements for Running Boundary in Kubernetes

Requirements depend on the node OS and the container runtime. The following
examples use **EKS with Managed Node Groups** for two common node AMIs.

---

### Example 1: EKS + Managed Node Groups + Amazon Linux

On **Amazon Linux** nodes, the default seccomp and runtime behavior typically
allow the syscalls needed for Boundary. You only need to
grant `NET_ADMIN`.

**Container `securityContext`:**

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: coder-agent
spec:
  containers:
    - name: coder-agent
      image: your-coder-agent-image
      securityContext:
        capabilities:
          add:
            - NET_ADMIN
      # ... rest of container spec
```

---

### Example 2: EKS + Managed Node Groups + Bottlerocket

On **Bottlerocket** nodes, the default seccomp profile often blocks the `clone`
syscalls required for unprivileged user namespaces. You must either disable or
modify seccomp for the pod (see [Docker Seccomp Profile Considerations](./docker.md#docker-seccomp-profile-considerations)) or grant `SYS_ADMIN`.

**Option A: `NET_ADMIN` + disable seccomp**

Disabling the seccomp profile allows the container to create namespaces
without granting `SYS_ADMIN` capabilities.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: coder-agent
spec:
  containers:
    - name: coder-agent
      image: your-coder-agent-image
      securityContext:
        capabilities:
          add:
            - NET_ADMIN
        seccompProfile:
          type: Unconfined
      # ... rest of container spec
```

**Option B: `NET_ADMIN` + `SYS_ADMIN`**

Granting `SYS_ADMIN` bypasses many seccomp restrictions and allows namespace
creation.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: coder-agent
spec:
  containers:
    - name: coder-agent
      image: your-coder-agent-image
      securityContext:
        capabilities:
          add:
            - NET_ADMIN
            - SYS_ADMIN
      # ... rest of container spec
```

### User namespaces on Bottlerocket

User namespaces are often disabled (`user.max_user_namespaces=0`) on Bottlerocket
nodes. Check and enable user namespaces:

```bash
# Check current value
sysctl user.max_user_namespaces

# If it returns 0, enable user namespaces
sysctl -w user.max_user_namespaces=65536
```

If `sysctl -w` is not allowed, configure it via Bottlerocket bootstrap settings
when creating the node group (e.g., in Terraform):

```hcl
bootstrap_extra_args = <<-EOT
  [settings.kernel.sysctl]
  "user.max_user_namespaces" = "65536"
EOT
```

This ensures Boundary can create user namespaces with nsjail.

### Running without user namespaces

If the environment is restricted and you cannot enable user namespaces (e.g.
Bottlerocket in EKS auto-mode), you can run Boundary with the
`--no-user-namespace` flag. Use this when you have no way to allow user namespace creation.

---

### Example 3: EKS + Fargate (Firecracker VMs)

nsjail is not currently supported on **EKS Fargate** (Firecracker-based VMs), which
blocks the capabilities needed for nsjail.

If you run on Fargate, we recommend using [landjail](../landjail.md) instead,
provided kernel version supports it (Linux 6.7+).

---

# NS Jail on ECS

Source: https://coder.com/docs/ai-coder/agent-firewall/nsjail/ecs

# nsjail on ECS

This page describes the runtime and permission requirements for running Agent
Firewall with the **nsjail** jail type on **Amazon ECS**.

## Runtime & Permission Requirements for Running Agent Firewall in ECS

The setup for ECS is similar to [nsjail on Kubernetes](./k8s.md); that environment
is better explored and tested, so the Kubernetes page is a useful reference. On
ECS, requirements depend on the node OS and how ECS runs your tasks. The
following examples use **ECS with Self Managed Node Groups** (EC2 launch type).

---

### Example 1: ECS + Self Managed Node Groups + Amazon Linux

On **Amazon Linux** nodes with ECS, the default Docker seccomp profile enforced
by ECS blocks the syscalls needed for Agent Firewall. Because it is difficult to
disable or modify the seccomp profile on ECS, you must grant `SYS_ADMIN` (along
with `NET_ADMIN`) so that Agent Firewall can create namespaces and run nsjail.

**Task definition (Terraform) — `linuxParameters`:**

```hcl
container_definitions = jsonencode([{
  name      = "coder-agent"
  image     = "your-coder-agent-image"

  linuxParameters = {
    capabilities = {
      add = ["NET_ADMIN", "SYS_ADMIN"]
    }
  }
}])
```

This gives the container the capabilities required for nsjail when ECS uses the
default Docker seccomp profile.

---

# LandJail

Source: https://coder.com/docs/ai-coder/agent-firewall/landjail

# landjail Jail Type

landjail is Agent Firewall's alternative jail type that uses Landlock V4 for
network isolation.

## Overview

Agent Firewall uses Landlock V4 to enforce network restrictions:

- All `bind` syscalls are forbidden
- All `connect` syscalls are forbidden except to the port that is used by http
  proxy

This provides network isolation without requiring network namespace capabilities
or special Docker permissions.

---

# Rules Engine

Source: https://coder.com/docs/ai-coder/agent-firewall/rules-engine

# Rules Engine Documentation

## Overview

The `rulesengine` package provides a flexible rule-based filtering system for
HTTP/HTTPS requests. Rules use a simple key-value syntax with support for
wildcards and multiple values.

### Basic Syntax

Rules follow the format: `key=value [key=value ...]` with three supported keys:

- **`method`**: HTTP method(s) - Any HTTP method (e.g., `GET`, `POST`, `PUT`,
  `DELETE`), `*` (all methods), or comma-separated list
- **`domain`**: Domain/hostname pattern - `github.com`, `*.example.com`, `*`
  (all domains)
- **`path`**: URL path pattern - `/api/users`, `/api/*/users`, `*` (all paths),
  or comma-separated list

**Key behavior**:

- If a key is omitted, it matches all values
- Multiple key-value pairs in one rule are separated by whitespace
- Multiple rules in the allowlist are OR'd together (OR logic)
- Default deny: if no rule matches, the request is denied

**Examples**:

```yaml
allowlist:
  - domain=github.com # All methods, all paths for github.com (exact match)
  - domain=*.github.com # All subdomains of github.com
  - method=GET,POST domain=api.example.com # GET/POST to api.example.com (exact match)
  - domain=api.example.com path=/users,/posts # Multiple paths
  - method=GET domain=github.com path=/api/* # All three keys
```

---

## Wildcard Symbol for Domains

The `*` wildcard matches domain labels (parts separated by dots).

| Pattern        | Matches                                                     | Does NOT Match                                                           |
|----------------|-------------------------------------------------------------|--------------------------------------------------------------------------|
| `*`            | All domains                                                 | -                                                                        |
| `github.com`   | `github.com` (exact match only)                             | `api.github.com`, `v1.api.github.com` (subdomains), `github.io`          |
| `*.github.com` | `api.github.com`, `v1.api.github.com` (1+ subdomain levels) | `github.com` (base domain)                                               |
| `api.*.com`    | `api.github.com`, `api.google.com`                          | `api.v1.github.com` (`*` in the middle matches exactly one domain label) |
| `*.*.com`      | `api.example.com`, `api.v1.github.com`                      | -                                                                        |
| `api.*`        | ❌ **ERROR** - Cannot end with `*`                           | -                                                                        |

**Important**:

- Patterns without `*` match **exactly** (no automatic subdomain matching)
- `*.example.com` matches one or more subdomain levels
- To match both base domain and subdomains, use separate rules:
  `domain=github.com` and `domain=*.github.com`
- Domain patterns **cannot end with asterisk**

---

## Wildcard Symbol for Paths

The `*` wildcard matches path segments (parts separated by slashes).

| Pattern        | Matches                                                    | Does NOT Match                          |
|----------------|------------------------------------------------------------|-----------------------------------------|
| `*`            | All paths                                                  | -                                       |
| `/api/users`   | `/api/users`                                               | `/api/users/123` (subpaths don't match) |
| `/api/*`       | `/api/users`, `/api/posts`                                 | `/api`                                  |
| `/api/*/users` | `/api/v1/users`, `/api/v2/users`                           | `/api/users`, `/api/v1/v2/users`        |
| `/*/users`     | `/api/users`, `/v1/users`                                  | `/api/v1/users`                         |
| `/api/v1/*`    | `/api/v1/users`, `/api/v1/users/123/details` (1+ segments) | `/api/v1`                               |

**Important**:

- `*` matches **exactly one segment** (except at the end)
- `*` at the **end** matches **one or more segments** (special behavior)
- `*` must match an entire segment (cannot be part of a segment like
  `/api/user*`)

---

## Special Meaning of Wildcard at Beginning and End

| Position   | Domain              | Path                  |
|------------|---------------------|-----------------------|
| Beginning  | 1+ subdomain levels | Exactly 1 segment     |
| Middle     | Exactly 1 label     | Exactly 1 segment     |
| End        | ❌ Not allowed       | 1+ segments (special) |
| Standalone | All domains         | All paths             |

---

## Multipath

Specify multiple paths in a single rule by separating them with commas:

```yaml
allowlist:
  - domain=api.example.com path=/users,/posts,/comments
  - domain=api.example.com path=/api,/api/*
```

`NOTE`: The pattern `/api/*` does not include the base path `/api`. To match
both, use `path=/api,/api/*`.

---

# Version Compatibility

Source: https://coder.com/docs/ai-coder/agent-firewall/version

# Version Requirements

## Recommended Versions

It's recommended to use **Coder v2.30.0 or newer** and **Claude Code module
v4.7.0 or newer**.

### Coder v2.30.0+

Since Coder v2.30.0, Agent Firewall is embedded inside the Coder binary, and
you don't need to install it separately. The `coder boundary` subcommand is
available directly from the Coder CLI.

### Claude Code Module v4.7.0+

Since Claude Code module v4.7.0, the embedded `coder boundary` subcommand is
used by default. This means you don't need to set `boundary_version`; the
boundary version is tied to your Coder version.

## Compatibility with Older Versions

### Using Coder Before v2.30.0 with Claude Code Module v4.7.0+

If you're using Coder before v2.30.0 with Claude Code module v4.7.0 or newer,
the `coder boundary` subcommand isn't available in your Coder installation. In
this case, you need to:

1. Set `use_boundary_directly = true` in your Terraform module configuration
2. Explicitly set `boundary_version` to specify which Agent Firewall version
   to install

Example configuration:

```tf
module "claude-code" {
  source              = "dev.registry.coder.com/coder/claude-code/coder"
  version             = "4.7.0"
  enable_boundary     = true
  use_boundary_directly = true
  boundary_version    = "0.6.0"
}
```

### Using Claude Code Module Before v4.7.0

If you're using Claude Code module before v4.7.0, the module expects to use
Agent Firewall directly. You need to explicitly set `boundary_version` in your
Terraform configuration:

```tf
module "claude-code" {
  source              = "dev.registry.coder.com/coder/claude-code/coder"
  version             = "4.6.0"
  enable_boundary     = true
  boundary_version    = "0.6.0"
}
```

## Summary

| Coder Version | Claude Code Module Version | Configuration Required                                |
|---------------|----------------------------|-------------------------------------------------------|
| v2.30.0+      | v4.7.0+                    | No additional configuration needed                    |
| < v2.30.0     | v4.7.0+                    | `use_boundary_directly = true` and `boundary_version` |
| Any           | < v4.7.0                   | `boundary_version`                                    |

---

# AI Gateway

Source: https://coder.com/docs/ai-coder/ai-gateway

# AI Gateway

![AI bridge diagram](../../images/aibridge/aibridge_diagram.png)

AI Gateway is a smart gateway for AI. It acts as an intermediary between your users' coding agents / IDEs
and providers like OpenAI and Anthropic. By intercepting all the AI traffic between these clients and
the upstream APIs, AI Gateway can record user prompts, token usage, and tool invocations.
AI Gateway supports clients running inside or outside Coder workspaces.

AI Gateway solves 3 key problems:

1. **Centralized authn/z management**: no more issuing & managing API tokens for OpenAI/Anthropic usage.
   Users use their Coder session or API tokens to authenticate with `coderd` (Coder control plane), and
   `coderd` securely communicates with the upstream APIs on their behalf.
1. **Auditing and attribution**: all interactions with AI services, whether autonomous or human-initiated,
   will be audited and attributed back to a user.
1. **Centralized MCP administration**: define a set of approved MCP servers and tools which your users may
   use.

> [!NOTE]
> AI Gateway was previously known as "AI Bridge". Some configuration
> options, environment variables, and API paths still use the old name
> and will be updated in a future release.

## When to use AI Gateway

As LLM adoption grows, administrators need centralized auditing, monitoring, and token management. AI Gateway enables organizations to manage AI tooling access for thousands of engineers from a single control plane.

If you are an administrator or devops leader looking to:

- Measure AI tooling adoption across teams or projects
- Establish an audit trail of prompts, issues, and tools invoked
- Manage token spend in a central dashboard
- Investigate opportunities for AI automation
- Uncover high-leverage use cases last

AI Gateway is best suited for organizations facing these centralized management and observability challenges.

## Next steps

- [Set up AI Gateway](./setup.md) on your Coder deployment
- [Configure AI clients](./clients/index.md) to use AI Gateway
- [Configure MCP servers](./mcp.md) for tool access
- [Audit AI sessions](./audit.md)
- [Monitor usage and metrics](./monitoring.md) and [configure data retention](./setup.md#data-retention)
- [Reference documentation](./reference.md)

<children></children>

---

# Setup

Source: https://coder.com/docs/ai-coder/ai-gateway/setup

# Setup

AI Gateway runs inside the Coder control plane (`coderd`), requiring no separate compute to deploy or scale. Once enabled, `coderd` runs the `aibridged` in-memory and brokers traffic to your configured AI providers on behalf of authenticated users.

**Required**:

1. A **Premium** license with the [AI Governance Add-On](../ai-governance.md).
1. Feature must be [enabled](#activation) using the server flag
1. One or more [providers](#configure-providers) API key(s) must be configured

## Activation

You will need to enable AI Gateway explicitly:

```sh
export CODER_AIBRIDGE_ENABLED=true
coder server
# or
coder server --aibridge-enabled=true
```

## Configure Providers

AI Gateway proxies requests to upstream LLM APIs. Configure at least one provider before exposing AI Gateway to end users.

<div class="tabs">

### OpenAI

Set the following when routing [OpenAI-compatible](https://coder.com/docs/reference/cli/server#--aibridge-openai-key) traffic through AI Gateway:

- `CODER_AIBRIDGE_OPENAI_KEY` or `--aibridge-openai-key`
- `CODER_AIBRIDGE_OPENAI_BASE_URL` or `--aibridge-openai-base-url`

The default base URL (`https://api.openai.com/v1/`) works for the native OpenAI service. Point the base URL at your preferred OpenAI-compatible endpoint (for example, a hosted proxy or LiteLLM deployment) when needed.

If you'd like to create an [OpenAI key](https://platform.openai.com/api-keys) with minimal privileges, this is the minimum required set:

![List Models scope should be set to "Read", Model Capabilities set to "Request"](../../images/aibridge/openai_key_scope.png)

### Anthropic

Set the following when routing [Anthropic-compatible](https://coder.com/docs/reference/cli/server#--aibridge-anthropic-key) traffic through AI Gateway:

- `CODER_AIBRIDGE_ANTHROPIC_KEY` or `--aibridge-anthropic-key`
- `CODER_AIBRIDGE_ANTHROPIC_BASE_URL` or `--aibridge-anthropic-base-url`

The default base URL (`https://api.anthropic.com/`) targets Anthropic's public API. Override it for Anthropic-compatible brokers.

Anthropic does not allow [API keys](https://console.anthropic.com/settings/keys) to have restricted permissions at the time of writing (Nov 2025).

### Amazon Bedrock

Set the following when routing [Amazon Bedrock](https://coder.com/docs/reference/cli/server#--aibridge-bedrock-region) traffic through AI Gateway:

**Required:**

- `CODER_AIBRIDGE_BEDROCK_REGION` or `--aibridge-bedrock-region`.
Alternatively, set `CODER_AIBRIDGE_BEDROCK_BASE_URL` or `--aibridge-bedrock-base-url` to a full URL (e.g., when routing through a proxy between AI Gateway and AWS Bedrock or using a non-standard endpoint that doesn't follow the `https://bedrock-runtime.<region>.amazonaws.com` format).
If both are set, `CODER_AIBRIDGE_BEDROCK_BASE_URL` takes precedence.
- `CODER_AIBRIDGE_BEDROCK_MODEL` or `--aibridge-bedrock-model`
- `CODER_AIBRIDGE_BEDROCK_SMALL_FAST_MODEL` or `--aibridge-bedrock-small-fast-model`

> [!NOTE]
> These Bedrock settings configure AI Gateway only. To configure Bedrock as an
> Agents provider, see [Configuring AWS Bedrock](../agents/models.md#configuring-aws-bedrock).

**Optional:**

- `CODER_AIBRIDGE_BEDROCK_ACCESS_KEY` or `--aibridge-bedrock-access-key`
- `CODER_AIBRIDGE_BEDROCK_ACCESS_KEY_SECRET` or `--aibridge-bedrock-access-key-secret`

#### Authentication

AI Gateway supports two credential configuration paths:

##### AWS SDK default credential chain (recommended)

When no credentials are set in AI Gateway config, the AWS SDK resolves them automatically from the environment.
This includes IAM Roles (instance profiles, IRSA, ECS task roles), shared config files, environment variables, SSO, and more.

**IAM Roles are the recommended approach** when AI Gateway runs on AWS infrastructure.
Attach an IAM Role with Bedrock permissions to the compute running AI Gateway (EC2 instance, EKS pod via IRSA, or ECS task), no credentials need to be configured in AI Gateway itself.

The IAM Role must have permission to invoke the Bedrock models configured for AI Gateway (`bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream`).
See [Amazon Bedrock identity-based policy examples](https://docs.aws.amazon.com/bedrock/latest/userguide/security_iam_id-based-policy-examples.html) for policy examples,
and [AWS IAM role creation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html) for general guidance on attaching roles to AWS services.

This aligns with [AWS best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) for using temporary credentials instead of long-lived access keys.

##### Static credentials

For deployments when explicit credentials are preferred, provide an access key and secret for an IAM User:

1. **Choose a region** where you want to use Bedrock.

2. **Generate API keys** in the [AWS Bedrock console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/api-keys/long-term/create) (replace `us-east-1` in the URL with your chosen region):
   - Choose an expiry period for the key.
   - Click **Generate**.
   - This creates an IAM user with strictly-scoped permissions for Bedrock access.

3. **Create an access key** for the IAM user:
   - After generating the API key, click **"You can directly modify permissions for the IAM user associated"**.
   - In the IAM user page, navigate to the **Security credentials** tab.
   - Under **Access keys**, click **Create access key**.
   - Select **"Application running outside AWS"** as the use case.
   - Click **Next**.
   - Add a description like "Coder AI Gateway token".
   - Click **Create access key**.
   - Save both the access key ID and secret access key securely.

4. **Configure your Coder deployment** with the credentials:

   ```sh
   export CODER_AIBRIDGE_BEDROCK_REGION=us-east-1
   export CODER_AIBRIDGE_BEDROCK_ACCESS_KEY=<your-access-key-id>
   export CODER_AIBRIDGE_BEDROCK_ACCESS_KEY_SECRET=<your-secret-access-key>
   coder server
   ```

### GitHub Copilot

GitHub Copilot offers three plans — Individual, Business, and Enterprise —
each with its own API endpoint. Configure one or more `copilot` providers
using the [indexed provider format](#multiple-instances-of-the-same-provider)
depending on which plans your organization uses.
Copilot providers use OAuth app installations for authentication rather than
static API keys.

```sh
# GitHub Copilot (Individual)
export CODER_AIBRIDGE_PROVIDER_0_TYPE=copilot
export CODER_AIBRIDGE_PROVIDER_0_NAME=copilot

# GitHub Copilot Business
export CODER_AIBRIDGE_PROVIDER_1_TYPE=copilot
export CODER_AIBRIDGE_PROVIDER_1_NAME=copilot-business
export CODER_AIBRIDGE_PROVIDER_1_BASE_URL=https://api.business.githubcopilot.com

# GitHub Copilot Enterprise
export CODER_AIBRIDGE_PROVIDER_2_TYPE=copilot
export CODER_AIBRIDGE_PROVIDER_2_NAME=copilot-enterprise
export CODER_AIBRIDGE_PROVIDER_2_BASE_URL=https://api.enterprise.githubcopilot.com
```

The default base URL targets the individual Copilot API
(`api.individual.githubcopilot.com`). Override `CODER_AIBRIDGE_PROVIDER_<N>_BASE_URL`
for Business or Enterprise tiers as shown above.

For client-side setup (proxy, certificates, IDE configuration), see
[GitHub Copilot client configuration](./clients/copilot.md).

### ChatGPT

Configure a ChatGPT provider by creating an `openai`-typed instance with the
ChatGPT Codex base URL:

```sh
export CODER_AIBRIDGE_PROVIDER_0_TYPE=openai
export CODER_AIBRIDGE_PROVIDER_0_NAME=chatgpt
export CODER_AIBRIDGE_PROVIDER_0_BASE_URL=https://chatgpt.com/backend-api/codex
```

</div>

> [!NOTE]
> See the [Supported APIs](./reference.md#supported-apis) section below for precise endpoint coverage and interception behavior.

### Multiple instances of the same provider

You can configure multiple instances of the same provider type — for example, to
route different teams to separate API keys, use different base URLs per region, or
connect to both a direct API and a proxy simultaneously. Use indexed environment
variables following the pattern `CODER_AIBRIDGE_PROVIDER_<N>_<KEY>`:

```sh
# Anthropic routed through a corporate proxy
export CODER_AIBRIDGE_PROVIDER_0_TYPE=anthropic
export CODER_AIBRIDGE_PROVIDER_0_NAME=anthropic-corp
export CODER_AIBRIDGE_PROVIDER_0_KEY=sk-ant-corp-xxx
export CODER_AIBRIDGE_PROVIDER_0_BASE_URL=https://llm-proxy.internal.example.com/anthropic

# Anthropic direct (for teams that need direct access)
export CODER_AIBRIDGE_PROVIDER_1_TYPE=anthropic
export CODER_AIBRIDGE_PROVIDER_1_NAME=anthropic-direct
export CODER_AIBRIDGE_PROVIDER_1_KEY=sk-ant-direct-yyy

# Azure-hosted OpenAI deployment
export CODER_AIBRIDGE_PROVIDER_2_TYPE=openai
export CODER_AIBRIDGE_PROVIDER_2_NAME=azure-openai
export CODER_AIBRIDGE_PROVIDER_2_KEY=azure-key-zzz
export CODER_AIBRIDGE_PROVIDER_2_BASE_URL=https://my-deployment.openai.azure.com/

# Anthropic via AWS Bedrock
export CODER_AIBRIDGE_PROVIDER_3_TYPE=anthropic
export CODER_AIBRIDGE_PROVIDER_3_NAME=anthropic-bedrock
export CODER_AIBRIDGE_PROVIDER_3_BEDROCK_REGION=us-west-2
export CODER_AIBRIDGE_PROVIDER_3_BEDROCK_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
export CODER_AIBRIDGE_PROVIDER_3_BEDROCK_ACCESS_KEY_SECRET=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

coder server
```

Each provider instance gets a unique route based on its `NAME`. Clients send
requests to `/api/v2/aibridge/<NAME>/` to target a specific instance:

| Instance name       | Route                                               |
|---------------------|-----------------------------------------------------|
| `anthropic-corp`    | `/api/v2/aibridge/anthropic-corp/v1/messages`       |
| `anthropic-direct`  | `/api/v2/aibridge/anthropic-direct/v1/messages`     |
| `azure-openai`      | `/api/v2/aibridge/azure-openai/v1/chat/completions` |
| `anthropic-bedrock` | `/api/v2/aibridge/anthropic-bedrock/v1/messages`    |

**Supported keys per provider:**

| Key        | Required | Description                                           |
|------------|----------|-------------------------------------------------------|
| `TYPE`     | Yes      | Provider type: `openai`, `anthropic`, or `copilot`    |
| `NAME`     | No       | Unique instance name for routing. Defaults to `TYPE`  |
| `KEY`      | No       | API key for upstream authentication (alias: `KEYS`)   |
| `BASE_URL` | No       | Base URL of the upstream API                          |
| `DUMP_DIR` | No       | Directory for provider API request and response dumps |

> [!WARNING]
> `DUMP_DIR` is not intended for regular use. Setting this option
> results in a high number of writes. Dump files contain raw request and
> response data, which may include proprietary or sensitive information
> (prompts, completions, tool inputs). Enable only briefly for diagnostic
> purposes and protect the target directory.

For `anthropic` providers using AWS Bedrock, the following keys are also
available: `BEDROCK_BASE_URL`, `BEDROCK_REGION`,
`BEDROCK_ACCESS_KEY` (alias: `BEDROCK_ACCESS_KEYS`),
`BEDROCK_ACCESS_KEY_SECRET` (alias: `BEDROCK_ACCESS_KEY_SECRETS`),
`BEDROCK_MODEL`, `BEDROCK_SMALL_FAST_MODEL`.

> [!NOTE]
> Indices must be contiguous and start at `0`. Each instance must have a unique
> `NAME` — if two instances of the same `TYPE` omit `NAME`, they will both
> default to the type name and fail with a duplicate name error.
>
> The legacy single-provider environment variables (`CODER_AIBRIDGE_OPENAI_KEY`,
> `CODER_AIBRIDGE_ANTHROPIC_KEY`, etc.) continue to work. However, setting both
> a legacy variable and an indexed provider with the same default name (e.g.
> `CODER_AIBRIDGE_OPENAI_KEY` and an indexed provider named `openai`) will
> produce a startup error — remove one or the other to resolve the conflict.

## Data Retention

AI Gateway records prompts, token usage, tool invocations, and model reasoning for auditing and
monitoring purposes. By default, this data is retained for **60 days**.

Configure retention using `--aibridge-retention` or `CODER_AIBRIDGE_RETENTION`:

```sh
coder server --aibridge-retention=90d
```

Or in YAML:

```yaml
aibridge:
  retention: 90d
```

Set to `0` to retain data indefinitely.

For duration formats, how retention works, and best practices, see the
[Data Retention](../../admin/setup/data-retention.md) documentation.

## Structured Logging

AI Gateway can emit structured logs for every interception record, making it
straightforward to export data to external SIEM or observability platforms.

Enable with `--aibridge-structured-logging` or `CODER_AIBRIDGE_STRUCTURED_LOGGING`:

```sh
coder server --aibridge-structured-logging=true
```

Or in YAML:

```yaml
aibridge:
  structured_logging: true
```

These logs are written to the same output stream as all other `coderd` logs,
using the format configured by
[`--log-human`](../../reference/cli/server.md#--log-human) (default, writes to
stderr) or [`--log-json`](../../reference/cli/server.md#--log-json). For machine
ingestion, set `--log-json` to a file path or `/dev/stderr` so that records are
emitted as JSON.

Filter for AI Gateway records in your logging pipeline by matching on the
`"interception log"` message. Each log line includes a `record_type` field that
indicates the kind of event captured:

| `record_type`        | Description                             | Key fields                                                                     |
|----------------------|-----------------------------------------|--------------------------------------------------------------------------------|
| `interception_start` | A new intercepted request begins.       | `interception_id`, `initiator_id`, `provider`, `model`, `client`, `started_at` |
| `interception_end`   | An intercepted request completes.       | `interception_id`, `ended_at`                                                  |
| `token_usage`        | Token consumption for a response.       | `interception_id`, `input_tokens`, `output_tokens`, `created_at`               |
| `prompt_usage`       | The last user prompt in a request.      | `interception_id`, `prompt`, `created_at`                                      |
| `tool_usage`         | A tool/function call made by the model. | `interception_id`, `tool`, `input`, `server_url`, `injected`, `created_at`     |
| `model_thought`      | Model reasoning or thinking content.    | `interception_id`, `content`, `created_at`                                     |

---

# Client Configuration

Source: https://coder.com/docs/ai-coder/ai-gateway/clients

# Client Configuration

Once AI Gateway is setup on your deployment, the AI coding tools used by your users will need to be configured to route requests via AI Gateway.

There are two ways to connect AI tools to AI Gateway:

- Base URL configuration (Recommended): Most AI tools allow customizing the base URL for API requests. This is the preferred approach when supported.
- AI Gateway Proxy: For tools that don't support base URL configuration, [AI Gateway Proxy](../ai-gateway-proxy/index.md) can intercept traffic and forward it to AI Gateway.

> [!NOTE]
> AI Gateway works with tools running inside or outside
> of Coder workspaces. For non-workspace setup, see
> [External and Desktop Clients](#external-and-desktop-clients).

## Base URLs

Most AI coding tools allow the "base URL" to be customized. In other words, when a request is made to OpenAI's API from your coding tool, the API endpoint such as [`/v1/chat/completions`](https://platform.openai.com/docs/api-reference/chat) will be appended to the configured base. Therefore, instead of the default base URL of `https://api.openai.com/v1`, you'll need to set it to `https://coder.example.com/api/v2/aibridge/openai/v1`.

The exact configuration method varies by client — some use environment variables, others use configuration files or UI settings:

- **OpenAI-compatible clients**: Set the base URL (commonly via the `OPENAI_BASE_URL` environment variable) to `https://coder.example.com/api/v2/aibridge/openai/v1`
- **Anthropic-compatible clients**: Set the base URL (commonly via the `ANTHROPIC_BASE_URL` environment variable) to `https://coder.example.com/api/v2/aibridge/anthropic`

Replace `coder.example.com` with your actual Coder deployment URL.

## Authentication

Instead of distributing provider-specific API keys (OpenAI/Anthropic keys) to users, they authenticate to AI Gateway using their **Coder API token**:

- **OpenAI clients**: Users set `OPENAI_API_KEY` to their Coder API token
- **Anthropic clients**: Users set `ANTHROPIC_API_KEY` to their Coder API token

> [!NOTE]
> Only Coder-issued tokens can authenticate users against AI Gateway.
> AI Gateway will use provider-specific API keys to [authenticate against upstream AI services](../setup.md#configure-providers).

Again, the exact environment variable or setting naming may differ from tool to tool. See a list of [supported clients](#all-supported-clients) below and consult your tool's documentation for details.

### Retrieving your session token

If you're logged in with the Coder CLI, you can retrieve your current session
token using [`coder login token`](../../../reference/cli/login_token.md):

```sh
export ANTHROPIC_API_KEY=$(coder login token)
export ANTHROPIC_BASE_URL="https://coder.example.com/api/v2/aibridge/anthropic"
```

Alternatively, [generate a long-lived API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself) via the Coder dashboard.

## Bring Your Own Key (BYOK)

In addition to centralized key management, AI Gateway supports **Bring Your
Own Key** (BYOK) mode. Users can provide their own LLM API keys or use
provider subscriptions (such as Claude Pro/Max or ChatGPT Plus/Pro) while
AI Gateway continues to provide observability and governance.

![BYOK authentication flow](../../../images/aibridge/clients/byok_auth_flow.png)

In BYOK mode, users need two credentials:

- A **Coder API token** to authenticate with AI Gateway.
- Their **own LLM credential** (personal API key or subscription token) which AI Gateway forwards
  to the upstream provider.

BYOK and centralized modes can be used together. When a user provides
their own credential, AI Gateway forwards it directly. When no user
credential is present, AI Gateway falls back to the admin-configured
provider key. This lets organizations offer centralized keys as a default
while allowing individual users to bring their own.

See individual client pages for configuration details.

### Enabling or disabling BYOK

BYOK is enabled by default. Administrators can disable it using `--aibridge-allow-byok=false` or `CODER_AIBRIDGE_ALLOW_BYOK=false`:

```sh
coder server --aibridge-allow-byok=false
```

When disabled, BYOK requests are rejected with a `403 Forbidden` response and only centralized key authentication is permitted.

## Compatibility

The table below shows tested AI clients and their compatibility with AI Gateway.

| Client                            | OpenAI | Anthropic | BYOK | Notes                                                                                                                                                  |
|-----------------------------------|--------|-----------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Coder Agents](./coder-agents.md) | ✅      | ✅         | ❌    | First-class AI Gateway client. Uses the Coder Agents [provider config](../../agents/models.md#providers).                                              |
| [Mux](./mux.md)                   | ✅      | ✅         | -    |                                                                                                                                                        |
| [Claude Code](./claude-code.md)   | -      | ✅         | ✅    |                                                                                                                                                        |
| [Codex CLI](./codex.md)           | ✅      | -         | ✅    |                                                                                                                                                        |
| [OpenCode](./opencode.md)         | ✅      | ✅         | ✅    |                                                                                                                                                        |
| [Factory](./factory.md)           | ✅      | ✅         | ✅    |                                                                                                                                                        |
| [Cline](./cline.md)               | ✅      | ✅         | ✅    |                                                                                                                                                        |
| [Kilo Code](./kilo-code.md)       | ✅      | ✅         | ❌    |                                                                                                                                                        |
| [Roo Code](./roo-code.md)         | ✅      | ✅         | ✅    |                                                                                                                                                        |
| [VS Code](./vscode.md)            | ✅      | ❌         | ❌    | Only supports Custom Base URL for OpenAI.                                                                                                              |
| [JetBrains IDEs](./jetbrains.md)  | ✅      | ❌         | ❌    | Works in Chat mode via [third-party model configuration](https://www.jetbrains.com/help/ai-assistant/use-custom-models.html#provide-your-own-api-key). |
| [Zed](./zed.md)                   | ✅      | ✅         | ❌    |                                                                                                                                                        |
| [GitHub Copilot](./copilot.md)    | ⚙️     | -         | -    | Requires [AI Gateway Proxy](../ai-gateway-proxy/index.md). Uses per-user GitHub tokens.                                                                |
| WindSurf                          | ❌      | ❌         | ❌    | No option to override base URL.                                                                                                                        |
| Cursor                            | ❌      | ❌         | ❌    | Override for OpenAI broken ([upstream issue](https://forum.cursor.com/t/requests-are-sent-to-incorrect-endpoint-when-using-base-url-override/144894)). |
| Sourcegraph Amp                   | ❌      | ❌         | ❌    | No option to override base URL.                                                                                                                        |
| Kiro                              | ❌      | ❌         | ❌    | No option to override base URL.                                                                                                                        |
| Gemini CLI                        | ❌      | ❌         | ❌    | No Gemini API support. Upvote [this issue](https://github.com/coder/coder/issues/24804).                                                               |
| Antigravity                       | ❌      | ❌         | ❌    | No option to override base URL.                                                                                                                        |
|

*Legend: ✅ supported, ⚙️ requires AI Gateway Proxy, ❌ not supported, - not applicable.*

## Configuring In-Workspace Tools

AI coding tools running inside a Coder workspace, such as IDE extensions, can be configured to use AI Gateway.

This section applies when you want template admins to preconfigure tools inside Coder workspaces. For tools running outside of a workspace, see [External and Desktop Clients](#external-and-desktop-clients).

While users can manually configure these tools with a long-lived API key, template admins can provide a more seamless experience by pre-configuring them. Admins can automatically inject the user's session token with `data.coder_workspace_owner.me.session_token` and the AI Gateway base URL into the workspace environment.

In this example, Claude Code respects these environment variables and will route all requests via AI Gateway.

```hcl
data "coder_workspace_owner" "me" {}

data "coder_workspace" "me" {}

resource "coder_agent" "dev" {
    arch = "amd64"
    os   = "linux"
    dir  = local.repo_dir
    env = {
        ANTHROPIC_BASE_URL : "${data.coder_workspace.me.access_url}/api/v2/aibridge/anthropic",
        ANTHROPIC_AUTH_TOKEN : data.coder_workspace_owner.me.session_token
    }
    ... # other agent configuration
}
```

## External and Desktop Clients

You can also configure AI tools running outside of a Coder workspace, such as local IDE extensions or desktop applications, to connect to AI Gateway. Use the same settings as the in-workspace case, configure the [base URL](#base-urls) and authenticate with a Coder API token.

For base URL setup, the client machine must have network access to the AI Gateway endpoint on your Coder deployment. Clients using [AI Gateway Proxy](../ai-gateway-proxy/index.md) must be able to reach the proxy endpoint and trust its CA certificate.

Users can generate a long-lived API token from the Coder UI or CLI. Follow the instructions at [Sessions and API tokens](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself) to create one.

For headless scenarios, first [create a service account](../../../admin/users/headless-auth.md#create-a-service-account), then generate a long-lived token for it.

<details>
<summary>Example</summary>
For clients supporting [base URL](#base-urls), eg. [Claude Code](./claude-code.md):

```sh
export ANTHROPIC_BASE_URL="https://coder.example.com/api/v2/aibridge/anthropic"
export ANTHROPIC_AUTH_TOKEN="<your-coder-api-token>"
```

Replace `coder.example.com` with your Coder deployment URL.

For other clients setup [AI Gateway Proxy](../ai-gateway-proxy/index.md). Configure the proxy endpoint and [CA certificates](../ai-gateway-proxy/setup.md#environment-variables):

```sh
export HTTPS_PROXY="https://coder:<your-coder-api-token>@<proxy-host>:8888"
export SSL_CERT_FILE="/path/to/coder-aibridge-proxy-ca.pem"
```

For proxy setup details, see [AI Gateway Proxy setup](../ai-gateway-proxy/setup.md).

For BYOK and workspace template examples, see full [Claude Code](./claude-code.md) example.
</details>

For complete setup instructions, see the [supported client examples](#all-supported-clients).

## All Supported Clients

<children></children>

---

# Coder Agents

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/coder-agents

# Coder Agents

[Coder Agents](../../agents/index.md) is a chat interface and API for delegating
development work to coding agents that run inside the Coder control plane. When
AI Gateway is enabled on the same deployment, Coder Agents traffic can be
routed through it for full audit and governance coverage.

## Prerequisites

- AI Gateway is [enabled](../setup.md#activation) on your Coder deployment.
- At least one [provider](../setup.md#configure-providers) is configured in
  AI Gateway with a valid upstream key.
- You are an administrator with permission to configure Coder Agents
  [providers](../../agents/models.md#providers).

> [!NOTE]
> AI Gateway and Coder Agents use independent provider configurations. Adding
> a provider to AI Gateway does not enable it in Coder Agents, and vice versa.
> Configure each separately.

## Configuration

Point each Agents provider's **Base URL** at your local AI Gateway endpoint
and set the **API Key** to a credential AI Gateway accepts. Because both
services run in the same `coderd` process, the AI Gateway endpoint is just
your deployment URL plus `/api/v2/aibridge/<provider>`.

The steps are the same regardless of provider type, only the Base URL
changes:

1. Open the Coder dashboard and navigate to the **Agents** page.
1. Click **Admin**, then select the **Providers** tab.
1. Click the provider you want to route through AI Gateway.
1. Set the **Base URL** using the table below.
1. Set the **API Key** to a Coder API token. See
   [Authentication](#authentication) for which token to use.
1. Click **Save**.

| Agents provider                           | Base URL                                              |
|-------------------------------------------|-------------------------------------------------------|
| Anthropic                                 | `https://coder.example.com/api/v2/aibridge/anthropic` |
| OpenAI                                    | `https://coder.example.com/api/v2/aibridge/openai/v1` |
| OpenAI Compatible (named OpenAI instance) | `https://coder.example.com/api/v2/aibridge/<name>/v1` |

Replace `coder.example.com` with your Coder deployment URL.

To target a [named AI Gateway instance](../setup.md#multiple-instances-of-the-same-provider)
through the **Anthropic** or **OpenAI** providers, swap the provider segment
of the Base URL for the instance name. For example, an Anthropic instance
named `anthropic-corp` becomes
`https://coder.example.com/api/v2/aibridge/anthropic-corp`, and an OpenAI
instance named `azure-openai` becomes
`https://coder.example.com/api/v2/aibridge/azure-openai/v1`.

> [!NOTE]
> The table above covers the Coder Agents provider types most commonly
> routed through AI Gateway. Coder Agents also supports Azure OpenAI,
> AWS Bedrock, Google, OpenRouter, and Vercel AI Gateway provider types,
> but only providers that speak a wire protocol AI Gateway supports
> (Anthropic, OpenAI, or Copilot today) can be routed through it. The
> base URL pattern is the same for any compatible provider: point it at
> `https://<your-coder-host>/api/v2/aibridge/<instance-name>`.

After saving, [add or update a model](../../agents/models.md#add-a-model) on
each provider so developers can select it from the chat. Models from a
provider only appear in the model selector once the provider has valid
credentials.

## Authentication

AI Gateway accepts Coder-issued tokens for client authentication and also
supports [Bring Your Own Key
(BYOK)](../clients/index.md#bring-your-own-key-byok) for other clients.
Coder Agents only uses the centralized key mode today. The upstream
provider keys you configured for AI Gateway (for example,
`CODER_AIBRIDGE_OPENAI_KEY`) are used by AI Gateway internally to call the
upstream provider; they are not what Coder Agents sends.

Coder Agents stores the **API Key** field on each provider as the bearer
credential it forwards to AI Gateway on every request from any chat that
uses that provider. AI Gateway resolves the bearer token to a Coder user
and uses **that user** as the initiator on every interception.

Because the Agents provider config is deployment-wide, every chat that
uses this provider is logged in AI Gateway under the identity of whoever
owns the API token configured here. Per-chat attribution to the developer
who started a chat is **not** preserved when routing Agents traffic
through AI Gateway today. See
[Known limitations](#known-limitations) below.

For that reason, **use a long-lived API token for a dedicated
[service account](../../../admin/users/headless-auth.md#create-a-service-account)**
that is intended to represent Agents traffic in audit. Avoid using an
admin's personal token: every chat would otherwise appear to have been
initiated by that admin.

> [!NOTE]
> Coder Agents does not support Bring Your Own Key when routing through
> AI Gateway today, but we plan to unify these authentication modes in a
> future release. For now, the Agents [User API
> keys](../../agents/models.md#user-api-keys-byok) feature is independent
> of AI Gateway and applies to direct provider calls only.

## Identity and correlation headers

When Coder Agents calls a provider, it attaches identity headers to every
outgoing request. Today AI Gateway uses two of them:

| Header            | Used by AI Gateway today                                                                                                 |
|-------------------|--------------------------------------------------------------------------------------------------------------------------|
| `User-Agent`      | Detects Coder Agents traffic and labels sessions with the `Coder Agents` client name.                                    |
| `X-Coder-Chat-Id` | Acts as the AI Gateway session key, so every interception in a chat (and its sub-agents) appears under a single session. |

Coder Agents also sends `X-Coder-Owner-Id`, `X-Coder-Subchat-Id`, and
`X-Coder-Workspace-Id`. These are emitted for forward compatibility but
are not consumed by AI Gateway today, which is why per-developer
attribution is not preserved. See
[Known limitations](#known-limitations) for details.

You don't need to configure these headers; they are set automatically.

## Pre-configuring in templates

You don't need to configure anything inside workspaces for Coder Agents
itself to use AI Gateway. The agent loop runs in the control plane, so
the Agents provider's Base URL is the only place AI Gateway needs to be
wired up.

If you also want IDE-based clients running inside Agents-provisioned
workspaces (such as Claude Code or Codex CLI) to route through AI
Gateway, configure them on the workspace template. See the
[Configuring In-Workspace Tools](./index.md#configuring-in-workspace-tools)
section for the general pattern, plus the per-client pages such as
[Claude Code](./claude-code.md#pre-configuring-in-templates).

## Verifying the integration

After saving the provider, start a new chat from the Agents page and send
a short prompt. Then:

1. Open the AI Gateway sessions UI at
   `https://coder.example.com/aibridge/sessions`.
1. The most recent session should show **Coder Agents** as the client and
   the user that owns the API token configured on the Agents provider as
   the initiator.
1. Click into the session to see the chat's interceptions, token usage,
   and any tool invocations.

If the session does not appear, check that the Agents provider's Base URL
points at your deployment's `/api/v2/aibridge/...` path and that the API
key is a valid Coder token.

## Troubleshooting

- **`401 Unauthorized` from the chat.** The API key on the Agents provider
  is not a valid Coder token, has been revoked, or belongs to a user that
  cannot reach AI Gateway. Generate a new long-lived token and update the
  provider.
- **Sessions in audit show a generic client instead of Coder Agents.**
  This usually means the request bypassed AI Gateway. Confirm the
  provider's Base URL starts with your deployment's `/api/v2/aibridge/`
  path and not the upstream provider URL.
- **Provider does not appear in the Agents model selector.** Add at least
  one [model](../../agents/models.md#add-a-model) to the provider after
  saving the Base URL. Providers without an enabled model are hidden from
  developers.

## Known limitations

- **Per-developer attribution is not preserved.** AI Gateway attributes
  every interception to the user that owns the bearer token configured
  on the Agents provider, regardless of which developer started the
  chat. The chat owner ID is sent by Coder Agents in `X-Coder-Owner-Id`
  but is not consumed by AI Gateway today. Use a dedicated service
  account for the Agents provider's API token so audit data is
  attributed to a single, non-human identity.
- **Bring Your Own Key (BYOK) is not supported through AI Gateway.**
  Personal LLM credentials configured under
  [User API keys](../../agents/models.md#user-api-keys-byok) are sent
  directly to the provider; AI Gateway is not involved when BYOK is
  active.

## Related documentation

- [Coder Agents: Models and providers](../../agents/models.md) for the
  full reference on configuring providers in Agents.
- [Coder Agents: Using an LLM proxy](../../agents/models.md#using-an-llm-proxy)
  for the short version of this same configuration.
- [AI Gateway setup](../setup.md) for enabling AI Gateway and
  configuring upstream provider credentials.
- [Auditing AI sessions](../audit.md) for how AI Gateway groups Coder
  Agents traffic into sessions.

---

# Claude Code

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/claude-code

# Claude Code

Claude Code can be configured using environment variables. All modes require a **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)** for authentication with AI Gateway.

## Centralized API Key

```bash
# AI Gateway base URL.
export ANTHROPIC_BASE_URL="<your-deployment-url>/api/v2/aibridge/anthropic"

# Your Coder API token, used for authentication with AI Gateway.
export ANTHROPIC_AUTH_TOKEN="<your-coder-api-token>"
```

## BYOK (Personal API Key)

```bash
# AI Gateway base URL.
export ANTHROPIC_BASE_URL="<your-deployment-url>/api/v2/aibridge/anthropic"

# Your personal Anthropic API key, forwarded to Anthropic.
export ANTHROPIC_API_KEY="<your-anthropic-api-key>"

# Your Coder API token, used for authentication with AI Gateway.
export ANTHROPIC_CUSTOM_HEADERS="X-Coder-AI-Governance-Token: <your-coder-api-token>"

# Ensure no auth token is set so Claude Code uses the API key instead.
unset ANTHROPIC_AUTH_TOKEN
```

## BYOK (Claude Subscription)

```bash
# AI Gateway base URL.
export ANTHROPIC_BASE_URL="<your-deployment-url>/api/v2/aibridge/anthropic"

# Your Coder API token, used for authentication with AI Gateway.
export ANTHROPIC_CUSTOM_HEADERS="X-Coder-AI-Governance-Token: <your-coder-api-token>"

# Ensure no auth token is set so Claude Code uses subscription login instead.
unset ANTHROPIC_AUTH_TOKEN
```

When you run Claude Code, it will prompt you to log in with your Anthropic
account.

## Pre-configuring in Templates

Template admins can pre-configure Claude Code for a seamless experience. Admins can automatically inject the user's Coder session token and the AI Gateway base URL into the workspace environment.

```hcl
module "claude-code" {
  source          = "registry.coder.com/coder/claude-code/coder"
  version         = "4.7.3"
  agent_id        = coder_agent.main.id
  workdir         = "/path/to/project"  # Set to your project directory
  enable_aibridge = true
}
```

### Coder Tasks

[Coder Tasks](../../tasks.md) provides a framework for agents to complete background development operations autonomously. Claude Code can be configured in your Tasks automatically:

```hcl
resource "coder_ai_task" "task" {
  count  = data.coder_workspace.me.start_count
  app_id = module.claude-code.task_app_id
}

data "coder_task" "me" {}

module "claude-code" {
  source         = "registry.coder.com/coder/claude-code/coder"
  version        = "4.7.3"
  agent_id       = coder_agent.main.id
  workdir        = "/path/to/project"  # Set to your project directory
  ai_prompt      = data.coder_task.me.prompt

  # Route through AI Gateway (Premium feature)
  enable_aibridge = true
}
```

## VS Code Extension

The Claude Code VS Code extension is also supported.

1. If pre-configured in the workspace environment variables (as shown above), it typically respects them.
2. You may need to sign in once; afterwards, it respects the workspace environment variables.

**References:** [Claude Code Settings](https://docs.claude.com/en/docs/claude-code/settings#environment-variables)

---

# Codex

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/codex

# Codex CLI

Codex CLI can be configured to use AI Gateway by setting up a custom model provider.

## Centralized API Key

To configure Codex CLI to use AI Gateway, set the following configuration options in your Codex configuration file (e.g., `~/.codex/config.toml`):

```toml
model_provider = "aibridge"

[model_providers.aibridge]
name = "AI Bridge"
base_url = "<your-deployment-url>/api/v2/aibridge/openai/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"
```

To authenticate with AI Gateway, get your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)** and set it in your environment:

```bash
export OPENAI_API_KEY="<your-coder-api-token>"
```

Run Codex as usual. It will automatically use the `aibridge` model provider from your configuration.

## BYOK (Personal API Key)

Add the following to your Codex configuration file (e.g., `~/.codex/config.toml`):

```toml
model_provider = "aibridge"

[model_providers.aibridge]
name = "AI Bridge"
base_url = "<your-deployment-url>/api/v2/aibridge/openai/v1"
wire_api = "responses"
requires_openai_auth = true
env_http_headers = { "X-Coder-AI-Governance-Token" = "CODER_API_TOKEN" }
```

Set both environment variables:

```bash
# Your personal OpenAI API key, forwarded to OpenAI.
export OPENAI_API_KEY="<your-openai-api-key>"

# Your Coder API token, used for authentication with AI Gateway.
export CODER_API_TOKEN="<your-coder-api-token>"
```

## BYOK (ChatGPT Subscription)

Add the following to your Codex configuration file (e.g., `~/.codex/config.toml`):

```toml
model_provider = "aibridge"

[model_providers.aibridge]
name = "AI Bridge"
base_url = "<your-deployment-url>/api/v2/aibridge/chatgpt/v1"
wire_api = "responses"
requires_openai_auth = true
env_http_headers = { "X-Coder-AI-Governance-Token" = "CODER_API_TOKEN" }
```

> [!NOTE]
> The `base_url` uses `/aibridge/chatgpt/v1` instead of `/aibridge/openai/v1` to route requests through the ChatGPT provider.

Set your Coder API token and ensure `OPENAI_API_KEY` is not set:

```bash
# Your Coder API token, used for authentication with AI Gateway.
export CODER_API_TOKEN="<your-coder-api-token>"

# Ensure no OpenAI API key is set so Codex uses ChatGPT login instead.
unset OPENAI_API_KEY
```

When you run Codex, it will prompt you to log in with your ChatGPT account.

## Pre-configuring in Templates

If configuring within a Coder workspace, you can use the
[Codex CLI](https://registry.coder.com/modules/coder-labs/codex) module:

```tf
module "codex" {
  source          = "registry.coder.com/coder-labs/codex/coder"
  version         = "~> 4.1"
  agent_id        = coder_agent.main.id
  workdir         = "/path/to/project"  # Set to your project directory
  enable_aibridge = true
}
```

**References:** [Codex CLI Configuration](https://developers.openai.com/codex/config-advanced)

---

# Mux

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/mux

# Mux

Mux makes it easy to run parallel coding agents, each with its own isolated workspace, from your browser or desktop; it is open source and provider-agnostic.

Mux can be configured to route OpenAI- and Anthropic-compatible traffic through AI Gateway by setting a custom provider base URL and using a Coder-issued token for authentication.

## Prerequisites

- AI Gateway is enabled on your Coder deployment.
- A **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.

## Configuration

<div class="tabs">

### OpenAI

1. Open Mux settings (`Cmd+,` / `Ctrl+,`).
2. Go to **Providers** → **OpenAI**.
3. Set **API Key** to your Coder API token.
4. Set **Base URL** to `https://coder.example.com/api/v2/aibridge/openai/v1`.

### Anthropic

1. Open Mux settings (`Cmd+,` / `Ctrl+,`).
2. Go to **Providers** → **Anthropic**.
3. Set **API Key** to your Coder API token.
4. Set **Base URL** to `https://coder.example.com/api/v2/aibridge/anthropic`.

</div>

_Replace `coder.example.com` with your Coder deployment URL._

## Environment variables

Mux reads provider configuration from its settings UI and also from environment variables.
Environment variables are useful in CI or when running Mux inside a Coder workspace.

> [!NOTE]
> Mux treats environment variables as a fallback when a provider is not configured in settings.
> If you have already configured a provider in the UI, clear it (or update it) for env vars to take effect.

```sh
# OpenAI-compatible traffic (GPT, Codex, etc.)
export OPENAI_API_KEY="<your-coder-api-token>"
export OPENAI_BASE_URL="https://coder.example.com/api/v2/aibridge/openai/v1"

# Anthropic-compatible traffic (Claude, etc.)
export ANTHROPIC_API_KEY="<your-coder-api-token>"
export ANTHROPIC_BASE_URL="https://coder.example.com/api/v2/aibridge/anthropic"
```

## Running Mux in a Coder workspace

If you want to run Mux inside a Coder workspace (for example, as a Coder app), you can install it with the [Mux module](https://registry.coder.com/modules/coder/mux) and pre-configure AI Gateway via environment variables on the agent:

```tf
data "coder_workspace" "me" {}

data "coder_workspace_owner" "me" {}

resource "coder_agent" "main" {
  # ... other agent configuration
  env = {
    OPENAI_API_KEY     = data.coder_workspace_owner.me.session_token
    OPENAI_BASE_URL    = "${data.coder_workspace.me.access_url}/api/v2/aibridge/openai/v1"
    ANTHROPIC_API_KEY  = data.coder_workspace_owner.me.session_token
    ANTHROPIC_BASE_URL = "${data.coder_workspace.me.access_url}/api/v2/aibridge/anthropic"
  }
}

module "mux" {
  source   = "registry.coder.com/coder/mux/coder"
  version  = "~> 1.0" # See the module page for the latest version.
  agent_id = coder_agent.main.id
}
```

## Advanced: providers.jsonc

If you prefer a file-based config, edit `~/.mux/providers.jsonc`:

```jsonc
{
  "openai": {
    "apiKey": "<your-coder-api-token>",
    "baseUrl": "https://coder.example.com/api/v2/aibridge/openai/v1"
  },
  "anthropic": {
    "apiKey": "<your-coder-api-token>",
    "baseUrl": "https://coder.example.com/api/v2/aibridge/anthropic"
  }
}
```

**References:** [Mux provider environment variables](https://mux.coder.com/config/providers#environment-variables)

---

# OpenCode

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/opencode

# OpenCode

OpenCode supports both OpenAI and Anthropic models and can be configured to use AI Gateway by setting custom base URLs for each provider.

## Centralized API Key

You can configure OpenCode to connect to AI Gateway by setting the following configuration options in your OpenCode configuration file (e.g., `~/.config/opencode/opencode.json`):

```json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "anthropic": {
      "options": {
        "baseURL": "https://coder.example.com/api/v2/aibridge/anthropic/v1"
      }
    },
    "openai": {
      "options": {
        "baseURL": "https://coder.example.com/api/v2/aibridge/openai/v1"
      }
    }
  }
}
```

To authenticate with AI Gateway, get your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)** and replace `<your-coder-api-token>` in `~/.local/share/opencode/auth.json`

```json
{
  "anthropic": {
    "type": "api",
    "key": "<your-coder-api-token>"
  },
  "openai": {
    "type": "api",
    "key": "<your-coder-api-token>"
  }
}
```

## BYOK (Personal API Key)

Set the following in `~/.config/opencode/opencode.json`, including the `X-Coder-AI-Governance-Token` header with your Coder API token:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "anthropic": {
      "options": {
        "baseURL": "https://coder.example.com/api/v2/aibridge/anthropic/v1",
        "headers": {
          "X-Coder-AI-Governance-Token": "<your-coder-api-token>"
        }
      }
    },
    "openai": {
      "options": {
        "baseURL": "https://coder.example.com/api/v2/aibridge/openai/v1",
        "headers": {
          "X-Coder-AI-Governance-Token": "<your-coder-api-token>"
        }
      }
    }
  }
}
```

Set your personal API keys in `~/.local/share/opencode/auth.json`:

```json
{
  "anthropic": {
    "type": "api",
    "key": "<your-anthropic-api-key>"
  },
  "openai": {
    "type": "api",
    "key": "<your-openai-api-key>"
  }
}
```

**References:** [OpenCode Documentation](https://opencode.ai/docs/providers/#config)

---

# Factory

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/factory

# Factory

Factort's Droid agent can be configured to use AI Gateway by setting up custom models for OpenAI and Anthropic.

## Centralized API Key

1. Open `~/.factory/settings.json` (create it if it does not exist).
2. Add a `customModels` entry for each provider you want to use with AI Gateway.
3. Replace `coder.example.com` with your Coder deployment URL.
4. Use a **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)** for `apiKey`.

```json
{
  "customModels": [
    {
      "model": "claude-sonnet-4-5-20250929",
      "displayName": "Claude (Coder AI Bridge)",
      "baseUrl": "https://coder.example.com/api/v2/aibridge/anthropic",
      "apiKey": "<your-coder-api-token>",
      "provider": "anthropic",
      "maxOutputTokens": 8192
    },
    {
      "model": "gpt-5.2-codex",
      "displayName": "GPT (Coder AI Bridge)",
      "baseUrl": "https://coder.example.com/api/v2/aibridge/openai/v1",
      "apiKey": "<your-coder-api-token>",
      "provider": "openai",
      "maxOutputTokens": 16384
    }
  ]
}
```

## BYOK (Personal API Key)

1. Open `~/.factory/settings.json` (create it if it does not exist).
2. Add a `customModels` entry for each provider you want to use with AI Bridge.
3. Replace `coder.example.com` with your Coder deployment URL.
4. Use your personal API key for `apiKey`.
5. Set the `X-Coder-AI-Governance-Token` header to your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.

```json
{
  "customModels": [
    {
      "model": "claude-sonnet-4-5-20250929",
      "displayName": "Claude (Coder AI Bridge)",
      "baseUrl": "https://coder.example.com/api/v2/aibridge/anthropic",
      "apiKey": "<your-anthropic-api-key>",
      "provider": "anthropic",
      "maxOutputTokens": 8192,
      "extraHeaders": {
        "X-Coder-AI-Governance-Token": "<your-coder-api-token>"
      }
    },
    {
      "model": "gpt-5.2-codex",
      "displayName": "GPT (Coder AI Bridge)",
      "baseUrl": "https://coder.example.com/api/v2/aibridge/openai/v1",
      "apiKey": "<your-openai-api-key>",
      "provider": "openai",
      "maxOutputTokens": 16384,
      "extraHeaders": {
        "X-Coder-AI-Governance-Token": "<your-coder-api-token>"
      }
    }
  ]
}
```

**References:** [Factory BYOK OpenAI & Anthropic](https://docs.factory.ai/cli/byok/openai-anthropic)

---

# Cline

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/cline

# Cline

Cline supports both OpenAI and Anthropic models and can be configured to use AI Gateway by setting providers.

## Configuration

To configure Cline to use AI Gateway, follow these steps:
![Cline Settings](../../../images/aibridge/clients/cline-setup.png)

## Centralized API Key

<div class="tabs">

### OpenAI Compatible

1. Open Cline in VS Code.
1. Go to **Settings**.
1. **API Provider**: Select **OpenAI Compatible**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/openai/v1`.
1. **OpenAI Compatible API Key**: Enter your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.
1. **Model ID** (Optional): Enter the model you wish to use (e.g., `gpt-5.2-codex`).

![Cline OpenAI Settings](../../../images/aibridge/clients/cline-openai.png)

### Anthropic

1. Open Cline in VS Code.
1. Go to **Settings**.
1. **API Provider**: Select **Anthropic**.
1. **Anthropic API Key**: Enter your **Coder API token**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/anthropic` after checking **_Use custom base URL_**.
1. **Model ID** (Optional): Select your desired Claude model.

![Cline Anthropic Settings](../../../images/aibridge/clients/cline-anthropic.png)

</div>

## BYOK (Personal API Key)

<div class="tabs">

### OpenAI Compatible

1. Open Cline in VS Code.
1. Go to **Settings**.
1. **API Provider**: Select **OpenAI Compatible**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/openai/v1`.
1. **OpenAI Compatible API Key**: Enter your personal OpenAI API key.
1. **Model ID** (Optional): Enter the model you wish to use (e.g., `gpt-5.2-codex`).
1. **Custom Headers**: Add `X-Coder-AI-Governance-Token` with your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.

![Cline BYOK OpenAI Settings](../../../images/aibridge/clients/cline-byok-openai.png)

</div>

**References:** [Cline Configuration](https://github.com/cline/cline)

---

# Kilo Code

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/kilo-code

# Kilo Code

Kilo Code allows you to configure providers via the UI and can be set up to use AI Gateway.

## Centralized API Key

<div class="tabs">

### OpenAI Compatible

1. Open Kilo Code in VS Code.
1. Go to **Settings**.
1. **Provider**: Select **OpenAI**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/openai/v1`.
1. **API Key**: Enter your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.
1. **Model ID**: Enter the model you wish to use (e.g., `gpt-5.2-codex`).

![Kilo Code OpenAI Settings](../../../images/aibridge/clients/kilo-code-openai.png)

### Anthropic

1. Open Kilo Code in VS Code.
1. Go to **Settings**.
1. **Provider**: Select **Anthropic**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/anthropic`.
1. **API Key**: Enter your **Coder API token**.
1. **Model ID**: Select your desired Claude model.

![Kilo Code Anthropic Settings](../../../images/aibridge/clients/kilo-code-anthropic.png)

</div>

## BYOK (Personal API Key)

> [!NOTE]
> Kilo Code supports sending custom headers, but the integration does not currently work reliably with AI Gateway.

**References:** [Kilo Code Configuration](https://kilocode.ai/docs/ai-providers/openai-compatible)

---

# Roo Code

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/roo-code

# Roo Code

Roo Code allows you to configure providers via the UI and can be set up to use AI Gateway.

## Configuration

Roo Code allows you to configure providers via the UI.

## Centralized API Key

<div class="tabs">

### OpenAI Compatible

1. Open Roo Code in VS Code.
1. Go to **Settings**.
1. **Provider**: Select **OpenAI**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/openai/v1`.
1. **API Key**: Enter your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.
1. **Model ID**: Enter the model you wish to use (e.g., `gpt-5.2-codex`).
![Roo Code OpenAI Settings](../../../images/aibridge/clients/roo-code-openai.png)

### Anthropic

1. Open Roo Code in VS Code.
1. Go to **Settings**.
1. **Provider**: Select **Anthropic**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/anthropic`.
1. **API Key**: Enter your **Coder API token**.
1. **Model ID**: Select your desired Claude model.

![Roo Code Anthropic Settings](../../../images/aibridge/clients/roo-code-anthropic.png)

</div>

### Notes

* If you encounter issues with the **OpenAI** provider type, use **OpenAI Compatible** to ensure correct endpoint routing.
* Ensure your Coder deployment URL is reachable from your VS Code environment.

## BYOK (Personal API Key)

<div class="tabs">

### OpenAI Compatible

1. Open Roo Code in VS Code.
1. Go to **Settings**.
1. **Provider**: Select **OpenAI Compatible**.
1. **Base URL**: Enter `https://coder.example.com/api/v2/aibridge/openai/v1`.
1. **API Key**: Enter your personal OpenAI API key.
1. **Model ID**: Enter the model you wish to use (e.g., `gpt-4o`).
1. **Custom Headers**: Add `X-Coder-AI-Governance-Token` with your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.

![Roo Code BYOK OpenAI Settings](../../../images/aibridge/clients/roo-code-byok-openai.png)

</div>

**References:** [Roo Code Configuration Profiles](https://docs.roocode.com/features/api-configuration-profiles#creating-and-managing-profiles)

---

# VS Code

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/vscode

# VS Code

VS Code's native chat can be configured to use AI Gateway with the GitHub Copilot Chat extension's custom language model support.

## Centralized API Key

> [!IMPORTANT]
> You need the **Pre-release** version of the [GitHub Copilot Chat extension](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) and [VS Code Insiders](https://code.visualstudio.com/insiders/).

1. Open command palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and search for _Chat: Open Language Models (JSON)_.
1. Paste the following JSON configuration, replacing `<your-coder-api-token>` with your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**:

```json
[
    {
        "name": "Coder",
        "vendor": "customoai",
        "apiKey": "<your-coder-api-token>",
        "models": [
            {
                "name": "GPT 5.2",
                "url": "https://coder.example.com/api/v2/aibridge/openai/v1/chat/completions",
                "toolCalling": true,
                "vision": true,
                "thinking": true,
                "maxInputTokens": 272000,
                "maxOutputTokens": 128000,
                "id": "gpt-5.2"
            },
            {
                "name": "GPT 5.2 Codex",
                "url": "https://coder.example.com/api/v2/aibridge/openai/v1/responses",
                "toolCalling": true,
                "vision": true,
                "thinking": true,
                "maxInputTokens": 272000,
                "maxOutputTokens": 128000,
                "id": "gpt-5.2-codex"
            }
        ]
    }
]
```

_Replace `coder.example.com` with your Coder deployment URL._

> [!NOTE]
> The setting names may change as the feature moves from pre-release to stable. Refer to the official documentation for the latest setting keys.

## BYOK (Personal API Key)

> [!NOTE]
> At the time of writing, GitHub Copilot Chat does not support sending custom headers, so BYOK mode is not available.

**References:** [GitHub Copilot - Bring your own language model](https://code.visualstudio.com/docs/copilot/customization/language-models#_add-an-openaicompatible-model)

---

# JetBrains

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/jetbrains

# JetBrains IDEs

JetBrains IDE (IntelliJ IDEA, PyCharm, WebStorm, etc.) support AI Gateway via the [third-party model configuration](https://www.jetbrains.com/help/ai-assistant/use-custom-models.html#provide-your-own-api-key) feature.

## Prerequisites

* [**JetBrains AI Assistant**](https://www.jetbrains.com/help/ai-assistant/installation-guide-ai-assistant.html): Installed and enabled.
* **Authentication**: Your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.

## Centralized API Key

1. **Open Settings**: Go to **Settings** > **Tools** > **AI Assistant** > **Models & API Keys**.
1. **Configure Provider**: Go to **Third-party AI providers**.
1. **Choose Provider**: Choose **OpenAI-compatible**.
1. **URL**: `https://coder.example.com/api/v2/aibridge/openai/v1`
1. **API Key**: Paste your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.
1. **Apply**: Click **Apply** and **OK**.

![JetBrains AI Assistant Settings](../../../images/aibridge/clients/jetbrains-ai-settings.png)

## Using the AI Assistant

1. Go back to **AI Chat** on theleft side bar and choose **Chat**.
1. In the Model dropdown, select the desired model (e.g., `gpt-5.2`).

![JetBrains AI Assistant Chat](../../../images/aibridge/clients/jetbrains-ai-chat.png)

You can now use the AI Assistant chat with the configured provider.

> [!NOTE]
>
> * JetBrains AI Assistant currently only supports OpenAI-compatible endpoints. There is an open [issue](https://youtrack.jetbrains.com/issue/LLM-22740) tracking support for Anthropic.
> * JetBrains AI Assistant may not support all models that support OPenAI's `/chat/completions` endpoint in Chat mode.

## BYOK (Personal API Key)

> [!NOTE]
> At the time of writing, JetBrains AI Assistant does not support sending custom headers, so BYOK mode is not available.

**References:** [Use custom models with JetBrains AI Assistant](https://www.jetbrains.com/help/ai-assistant/use-custom-models.html#provide-your-own-api-key)

---

# Zed

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/zed

# Zed

Zed IDE supports AI Gateway via its `language_models` configuration in `settings.json`.

## Centralized API Key

To configure Zed to use AI Gateway, you need to edit your `settings.json` file. You can access this by pressing `Cmd/Ctrl + ,` or opening the command palette and searching for "Open Settings".

You can configure both Anthropic and OpenAI providers to point to AI Gateway.

```json
{
  "language_models": {
    "anthropic": {
      "api_url": "https://coder.example.com/api/v2/aibridge/anthropic",
    },
    "openai": {
      "api_url": "https://coder.example.com/api/v2/aibridge/openai/v1",
    },
  },
  // optional settings to set favorite models for the AI
  "agent": {
    "favorite_models": [
      {
        "provider": "anthropic",
        "model": "claude-sonnet-4-5-thinking-latest"
      },
      {
        "provider": "openai",
        "model": "gpt-5.2-codex"
      }
    ],
  },
}
```

*Replace `coder.example.com` with your Coder deployment URL.*

> [!NOTE]
> These settings and environment variables need to be configured from client side. Zed currently does not support reading these settings from remote configuration. See this [feature request](https://github.com/zed-industries/zed/discussions/47058) for more details.

## Authentication

Zed requires an API key for these providers. For AI Gateway, this key is your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)**.

You can set this in two ways:

<div class="tabs">

### Zed UI

1. Open the **Assistant Panel** (right sidebar).
1. Click **Configuration** or the settings icon.
1. Select your provider ("Anthropic" or "OpenAI").
1. Paste your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)** for the API Key.

### Environment Variables

1. Set `ANTHROPIC_API_KEY` and `OPENAI_API_KEY` to your **[Coder API token](../../../admin/users/sessions-tokens.md#generate-a-long-lived-api-token-on-behalf-of-yourself)** in the environment where you launch Zed.

</div>

## BYOK (Personal API Key)

> [!NOTE]
> At the time of writing, Zed Agent does not support sending custom headers, so BYOK mode is not available.

**References:** [Configuring Zed - Language Models](https://zed.dev/docs/reference/all-settings#language-models)

---

# GitHub Copilot

Source: https://coder.com/docs/ai-coder/ai-gateway/clients/copilot

# GitHub Copilot

[GitHub Copilot](https://github.com/features/copilot) is an AI coding assistant that doesn't support custom base URLs but does respect proxy configurations.
This makes it compatible with [AI Gateway Proxy](../ai-gateway-proxy/index.md), which integrates with [AI Gateway](../index.md) for full access to auditing and governance features.
To use Copilot with AI Gateway, make sure AI Gateway Proxy is properly configured, see [AI Gateway Proxy Setup](../ai-gateway-proxy/setup.md) for instructions.

Copilot uses **per-user tokens** tied to GitHub accounts rather than a shared API key.
Users must still authenticate with GitHub to use Copilot.

For general information about GitHub Copilot, see the [GitHub Copilot documentation](https://docs.github.com/en/copilot).

For general client configuration requirements, see [AI Gateway Proxy Client Configuration](../ai-gateway-proxy/setup.md#client-configuration).
The sections below cover Copilot-specific setup for each client.

For provider configuration (admin), see [GitHub Copilot provider setup](../setup.md#github-copilot).

## Copilot CLI

For installation instructions, see [GitHub Copilot CLI documentation](https://docs.github.com/en/copilot/how-tos/copilot-cli/install-copilot-cli).

### Proxy configuration

Set the `HTTPS_PROXY` environment variable:

```shell
export HTTPS_PROXY="https://coder:${CODER_API_TOKEN}@<proxy-host>:8888"
```

Replace `<proxy-host>` with your AI Gateway Proxy hostname.

Note: if [TLS is not enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, replace `https://` with `http://` in the proxy URL.

### CA certificate trust

Copilot CLI is built on Node.js and uses the `NODE_EXTRA_CA_CERTS` environment variable for custom certificates:

```shell
export NODE_EXTRA_CA_CERTS="/path/to/coder-aibridge-proxy-ca.pem"
```

See [Client Configuration CA certificate trust](../ai-gateway-proxy/setup.md#trusting-the-ca-certificate) for details on how to obtain the certificate file.

When [TLS is enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, combine the MITM CA certificate and the TLS certificate into a single file:

```shell
cat coder-aibridge-proxy-ca.pem listener.crt > combined-ca.pem
export NODE_EXTRA_CA_CERTS="/path/to/combined-ca.pem"
```

Copilot CLI may start MCP server processes that use runtimes other than Node.js (e.g. Go).
These processes inherit environment variables like `HTTPS_PROXY` but may not respect `NODE_EXTRA_CA_CERTS`.
Adding the TLS certificate to the [system trust store](../ai-gateway-proxy/setup.md#system-trust-store) ensures all processes trust it.

## VS Code Copilot Extension

For installation instructions, see [Installing the GitHub Copilot extension in VS Code](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-extension?tool=vscode).

### Proxy configuration

You can configure the proxy using environment variables or VS Code settings.
For environment variables, see [AI Gateway Proxy client configuration](../ai-gateway-proxy/setup.md#configuring-the-proxy).

Alternatively, you can configure the proxy directly in VS Code settings:

1. Open Settings (`Ctrl+,` for Windows or `Cmd+,` for macOS)
1. Search for `HTTP: Proxy`
1. Set the proxy URL using the format `https://coder:<CODER_API_TOKEN>@<proxy-host>:8888`

Or add directly to your `settings.json`:

```json
{
    "http.proxy": "https://coder:<CODER_API_TOKEN>@<proxy-host>:8888"
}
```

Note: if [TLS is not enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, replace `https://` with `http://` in the proxy URL.

The `http.proxy` setting is used for both HTTP and HTTPS requests.
Replace `<proxy-host>` with your AI Gateway Proxy hostname and `<CODER_API_TOKEN>` with your Coder API token.

Restart VS Code for changes to take effect.

For more details, see [Configuring proxy settings for Copilot](https://docs.github.com/en/copilot/how-tos/configure-personal-settings/configure-network-settings?tool=vscode) in the GitHub documentation.

### CA certificate trust

Add the AI Gateway Proxy CA certificate to your operating system's trust store.
By default, VS Code loads system certificates, controlled by the `http.systemCertificates` setting.

See [Client Configuration CA certificate trust](../ai-gateway-proxy/setup.md#trusting-the-ca-certificate) for details on how to obtain the certificate file.

When [TLS is enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, add the TLS certificate to the system trust store as well.

### Using Coder Remote extension

When connecting to a Coder workspace with the [Coder extension](https://marketplace.visualstudio.com/items?itemName=coder.coder-remote), the Copilot extension runs inside the Coder workspace and not on your local machine.
This means proxy and certificate configuration must be done in the Coder workspace environment.

When [TLS is enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, add the TLS certificate to the workspace's system trust store as well.

#### Proxy configuration

Configure the proxy in VS Code's remote settings:

1. [Connect to your Coder workspace](../../../user-guides/workspace-access/vscode.md)
1. Open Settings (`Ctrl+,` for Windows or `Cmd+,` for macOS)
1. Select the **Remote** tab
1. Search for `HTTP: Proxy`
1. Set the proxy URL using the format `https://coder:<CODER_API_TOKEN>@<proxy-host>:8888`

Note: if [TLS is not enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, replace `https://` with `http://` in the proxy URL.

Replace `<proxy-host>` with your AI Gateway Proxy hostname and `<CODER_API_TOKEN>` with your Coder API token.

#### CA certificate trust

Since the Copilot extension runs inside the Coder workspace, add the [AI Gateway Proxy CA certificate](../ai-gateway-proxy/setup.md#trusting-the-ca-certificate) to the Coder workspace's system trust store.
See [System trust store](../ai-gateway-proxy/setup.md#system-trust-store) for instructions on how to do this on Linux.

Restart VS Code for changes to take effect.

## JetBrains IDEs

For installation instructions, see [Installing the GitHub Copilot extension in JetBrains IDE](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-extension?tool=jetbrains).

### Proxy configuration

Configure the proxy directly in JetBrains IDE settings:

1. Open Settings (`Ctrl+Alt+S` for Windows or `Cmd+,` for macOS)
1. Navigate to `Appearance & Behavior` > `System Settings` > `HTTP Proxy`
1. Select `Manual proxy configuration` and `HTTP`
1. Enter the proxy hostname and port (default: 8888)
1. Select `Proxy authentication` and enter:
   1. Login: `coder` (this value is ignored)
   1. Password: Your Coder API token
   1. Check `Remember` to save the password
1. Restart the IDE for changes to take effect

For more details, see [Configuring proxy settings for Copilot](https://docs.github.com/en/copilot/how-tos/configure-personal-settings/configure-network-settings?tool=jetbrains) in the GitHub documentation.

### CA certificate trust

Add the AI Gateway Proxy CA certificate to your operating system's trust store.
If the certificate is in the system trust store, no additional IDE configuration is needed.

When [TLS is enabled](../ai-gateway-proxy/setup.md#proxy-tls-configuration) on the proxy, add the TLS certificate to the system trust store as well, or add it under `Accepted certificates` in the IDE settings below.

Alternatively, you can configure the IDE to accept the certificate:

1. Open Settings (`Ctrl+Alt+S` for Windows or `Cmd+,` for macOS)
1. Navigate to `Appearance & Behavior` > `System Settings` > `Server Certificates`
1. Under `Accepted certificates`, click `+` and select the CA certificate file
1. Check `Accept non-trusted certificates automatically`
1. Restart the IDE for changes to take effect

For more details, see [Trusted root certificates](https://www.jetbrains.com/help/idea/ssl-certificates.html) in the JetBrains documentation.

See [Client Configuration CA certificate trust](../ai-gateway-proxy/setup.md#trusting-the-ca-certificate) for details on how to obtain the certificate file.

---

# MCP Tools Injection

Source: https://coder.com/docs/ai-coder/ai-gateway/mcp

# MCP

> [!WARNING]
> Injected MCP in AI Gateway is deprecated.
> It remains functional and will not be removed until
> the new implementation is released. Only critical
> security-related patches will be made.

[Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) is a mechanism for connecting AI applications to external systems.

AI Gateway can connect to MCP servers and inject tools automatically, enabling you to centrally manage the list of tools you wish to grant your users.

> [!NOTE]
> Only MCP servers which support OAuth2 Authorization are supported currently.
>
> [_Streamable HTTP_](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) is the only supported transport currently. In future releases we will support the (now deprecated) [_Server-Sent Events_](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#backwards-compatibility) transport.

AI Gateway makes use of [External Auth](../../admin/external-auth/index.md) applications, as they define OAuth2 connections to upstream services. If your External Auth application hosts a remote MCP server, you can configure AI Gateway to connect to it, retrieve its tools and inject them into requests automatically - all while using each individual user's access token.

For example, GitHub has a [remote MCP server](https://github.com/github/github-mcp-server?tab=readme-ov-file#remote-github-mcp-server) and we can use it as follows.

```bash
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=...
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=...
# Tell AI Gateway where it can find this service's remote MCP server.
CODER_EXTERNAL_AUTH_0_MCP_URL=https://api.githubcopilot.com/mcp/
```

See the diagram in [Implementation Details](./reference.md#implementation-details) for more information.

You can also control which tools are injected by using an allow and/or a deny regular expression on the tool names:

```env
CODER_EXTERNAL_AUTH_0_MCP_TOOL_ALLOW_REGEX=(.+_gist.*)
CODER_EXTERNAL_AUTH_0_MCP_TOOL_DENY_REGEX=(create_gist)
```

In the above example, all tools containing `_gist` in their name will be allowed, but `create_gist` is denied.

The logic works as follows:

- If neither the allow/deny patterns are defined, all tools will be injected.
- The deny pattern takes precedence.
- If only a deny pattern is defined, all tools are injected except those explicitly denied.

In the above example, if you prompted your AI model with "list your available github tools by name", it would reply something like:

> Certainly! Here are the GitHub-related tools that I have available:
>
> ```text
> 1. bmcp_github_update_gist
> 2. bmcp_github_list_gists
> ```

AI Gateway marks automatically injected tools with a prefix `bmcp_` ("bridged MCP"). It also namespaces all tool names by the ID of their associated External Auth application (in this case `github`).

## Tool Injection

If a model decides to invoke a tool and it has a `bmcp_` suffix and AI Gateway has a connection with the related MCP server, it will invoke the tool. The tool result will be passed back to the upstream AI provider, and this will loop until the model has all of its required data. These inner loops are not relayed back to the client; all it sees is the result of this loop. See [Implementation Details](./reference.md#implementation-details).

In contrast, tools which are defined by the client (i.e. the [`Bash` tool](https://docs.claude.com/en/docs/claude-code/settings#tools-available-to-claude) defined by _Claude Code_) cannot be invoked by AI Gateway, and the tool call from the model will be relayed to the client, after which it will invoke the tool.

If you have [Coder MCP Server](../mcp-server.md) enabled, as well as have `CODER_AIBRIDGE_INJECT_CODER_MCP_TOOLS=true` set, Coder's MCP tools will be injected into intercepted requests.

### Troubleshooting

- **Too many tools**: should you receive an error like `Invalid 'tools': array too long. Expected an array with maximum length 128, but got an array with length 132 instead`, you can reduce the number by filtering out tools using the allow/deny patterns documented in the [MCP](#mcp) section.

- **Coder MCP tools not being injected**: in order for Coder MCP tools to be injected, the internal MCP server needs to be active. Follow the instructions in the [MCP Server](../mcp-server.md) page to enable it and ensure `CODER_AIBRIDGE_INJECT_CODER_MCP_TOOLS` is set to `true`.

- **External Auth tools not being injected**: this is generally due to the requesting user not being authenticated against the [External Auth](../../admin/external-auth/index.md) app; when this is the case, no attempt is made to connect to the MCP server.

---

# AI Gateway Proxy

Source: https://coder.com/docs/ai-coder/ai-gateway/ai-gateway-proxy

# AI Gateway Proxy

AI Gateway Proxy extends [AI Gateway](../index.md) to support clients that don't allow base URL overrides.
While AI Gateway requires clients to support custom base URLs, many popular AI coding tools lack this capability.

AI Gateway Proxy solves this by acting as an HTTP proxy that intercepts traffic to supported AI providers and forwards it to AI Gateway. Since most clients respect proxy configurations even when they don't support base URL overrides, this provides a universal compatibility layer for AI Gateway.

For a list of clients supported through AI Gateway Proxy, see [Client Configuration](../clients/index.md).

## How it works

AI Gateway Proxy operates in two modes depending on the destination:

* MITM (Man-in-the-Middle) mode for allowlisted AI provider domains:
  * Intercepts and decrypts HTTPS traffic using a configured CA certificate
  * Forwards requests to AI Gateway for authentication, auditing, and routing
  * Supports: Anthropic, OpenAI, GitHub Copilot

* Tunnel mode for all other traffic:
  * Passes requests through without decryption

Clients authenticate by passing their Coder token in the proxy credentials.

<!-- TODO(ssncferreira): Add diagram showing how AI Gateway Proxy works in tunnel and MITM modes -->

## When to use AI Gateway Proxy

Use AI Gateway Proxy when your AI tools don't support base URL overrides but do respect standard proxy configurations.

For clients that support base URL configuration, you can use [AI Gateway](../index.md) directly.
Nevertheless, clients with base URL overrides also work with the proxy, in case you want to use multiple AI clients and some of them do not support base URL configuration.

## Next steps

* [Set up AI Gateway Proxy](./setup.md) on your Coder deployment

---

# Setup

Source: https://coder.com/docs/ai-coder/ai-gateway/ai-gateway-proxy/setup

# Setup

AI Gateway Proxy runs inside the Coder control plane (`coderd`), requiring no separate compute to deploy or scale.
Once enabled, `coderd` runs the `aibridgeproxyd` in-memory and intercepts traffic to supported AI providers, forwarding it to AI Gateway.

**Required:**

1. AI Gateway must be enabled and configured (requires a **Premium** license with the [AI Governance Add-On](../../ai-governance.md)). See [AI Gateway Setup](../setup.md) for further information.
1. AI Gateway Proxy must be [enabled](#proxy-configuration) using the server flag.
1. A [CA certificate](#ca-certificate) must be configured for MITM interception.
1. [Clients](#client-configuration) must be configured to use the proxy and trust the CA certificate.

## Proxy Configuration

AI Gateway Proxy is disabled by default. To enable it, set the following configuration options:

```shell
CODER_AIBRIDGE_ENABLED=true \
CODER_AIBRIDGE_PROXY_ENABLED=true \
CODER_AIBRIDGE_PROXY_CERT_FILE=/path/to/ca.crt \
CODER_AIBRIDGE_PROXY_KEY_FILE=/path/to/ca.key \
coder server
# or via CLI flags:
coder server \
  --aibridge-enabled=true \
  --aibridge-proxy-enabled=true \
  --aibridge-proxy-cert-file=/path/to/ca.crt \
  --aibridge-proxy-key-file=/path/to/ca.key
```

Both the certificate and private key are required for AI Gateway Proxy to start.
See [CA Certificate](#ca-certificate) for how to generate and obtain these files.

By default, the proxy listener accepts plain HTTP connections.
To serve the listener over HTTPS, provide a TLS certificate and key:

```shell
CODER_AIBRIDGE_PROXY_TLS_CERT_FILE=/path/to/listener.crt
CODER_AIBRIDGE_PROXY_TLS_KEY_FILE=/path/to/listener.key
# or via CLI flags:
--aibridge-proxy-tls-cert-file=/path/to/listener.crt
--aibridge-proxy-tls-key-file=/path/to/listener.key
```

Both files must be provided together.
The TLS certificate must include a Subject Alternative Name (SAN) matching the hostname or IP address that clients use to connect to the proxy.
See [Proxy TLS Configuration](#proxy-tls-configuration) for how to generate and configure these files.

The AI Gateway Proxy only intercepts and forwards traffic to AI Gateway for the supported AI provider domains:

* [Anthropic](https://www.anthropic.com/): `api.anthropic.com`
* [OpenAI](https://openai.com/): `api.openai.com`
* [GitHub Copilot](https://github.com/copilot): `api.individual.githubcopilot.com`

All other traffic is tunneled through without decryption.

For additional configuration options, see the [Coder server configuration](../../../reference/cli/server.md#options).

## Security Considerations

> [!WARNING]
> The AI Gateway Proxy should only be accessible within a trusted network and **must not** be directly exposed to the public internet.
> Without proper network restrictions, unauthorized users could route traffic through the proxy or intercept credentials.

### Encrypting client connections

By default, AI tools send the Coder session token in the proxy credentials over unencrypted HTTP.
This only applies to the initial connection between the client and the proxy.
Once connected:

* MITM mode: A TLS connection is established between the AI tool and the proxy (using the configured CA certificate), then traffic is forwarded securely to AI Gateway.
* Tunnel mode: A TLS connection is established directly between the AI tool and the destination, passing through the proxy without decryption.

As a best practice, apply one or more of the following to protect credentials during the initial connection:

* TLS listener (recommended): Enable TLS directly on the proxy so clients connect over HTTPS.
See [Proxy TLS Configuration](#proxy-tls-configuration) for configuration steps.
* Internal network only: If the proxy and all clients are on the same trusted network, credentials are not exposed to external attackers.
* TLS-terminating load balancer: Place a TLS-terminating load balancer in front of the proxy that terminates TLS and forwards requests over HTTP.

### Restricting proxy access

Requests to non-allowlisted domains are tunneled through the proxy, but connections to private and reserved IP ranges are blocked by default.
The IP validation and TCP connect happen atomically, preventing DNS rebinding attacks where the resolved address could change between the check and the connection.
To prevent unauthorized use, restrict network access to the proxy so that only authorized clients can connect.

In case the Coder access URL resolves to a private address, it is automatically exempt from this restriction so the proxy can always reach its own deployment.
If you need to allow access to additional internal networks via the proxy, use the Allowlist CIDRs option ([`CODER_AIBRIDGE_PROXY_ALLOWED_PRIVATE_CIDRS`](../../../reference/cli/server.md#--aibridge-proxy-allowed-private-cidrs)):

```shell
CODER_AIBRIDGE_PROXY_ALLOWED_PRIVATE_CIDRS=10.0.0.0/8,172.16.0.0/12
# or via CLI flag:
--aibridge-proxy-allowed-private-cidrs=10.0.0.0/8,172.16.0.0/12
```

## CA Certificate

AI Gateway Proxy uses a CA (Certificate Authority) certificate to perform MITM interception of HTTPS traffic.
When AI tools connect to AI provider domains through the proxy, the proxy presents a certificate signed by this CA.
AI tools must trust this CA certificate, otherwise, the connection will fail.

### Self-signed certificate

Use a self-signed certificate when your organization doesn't have an internal CA, or when you want a dedicated CA specifically for AI Gateway Proxy.

Generate a CA certificate specifically for AI Gateway Proxy:

1) Generate a private key:

```shell
openssl genrsa -out ca.key 4096
chmod 400 ca.key
```

1) Create a self-signed CA certificate (valid for 10 years):

```shell
openssl req -new -x509 -days 3650 \
  -key ca.key \
  -out ca.crt \
  -subj "/CN=AI Gateway Proxy CA"
```

Configure AI Gateway Proxy with both files:

```shell
CODER_AIBRIDGE_PROXY_CERT_FILE=/path/to/ca.crt
CODER_AIBRIDGE_PROXY_KEY_FILE=/path/to/ca.key
```

### Corporate CA certificate

If your organization has an internal CA that clients already trust, you can have it issue an intermediate CA certificate for AI Gateway Proxy.
This simplifies deployment since AI tools that already trust your organization's root CA will automatically trust certificates signed by the intermediate.

Your organization's CA issues a certificate and private key pair for the proxy. Configure the proxy with both files:

```shell
CODER_AIBRIDGE_PROXY_CERT_FILE=/path/to/intermediate-ca.crt
CODER_AIBRIDGE_PROXY_KEY_FILE=/path/to/intermediate-ca.key
```

### Securing the private key

> [!WARNING]
> The CA private key is used to sign certificates for MITM interception.
> Store it securely and restrict access. If compromised, an attacker could intercept traffic from any client that trusts the CA certificate.

Best practices:

* Restrict file permissions so only the Coder process can read the key.
* Use a secrets manager to store the key where possible.

### Distributing the certificate

AI tools need to trust the CA certificate before connecting through the proxy.

For **self-signed certificates**, AI tools must be configured to trust the CA certificate. The certificate (without the private key) is available at:

```shell
https://<coder-url>/api/v2/aibridge/proxy/ca-cert.pem
```

For **corporate CA certificates**, if the systems where AI tools run already trust your organization's root CA, and the intermediate certificate chains correctly to that root, no additional certificate distribution is needed.
Otherwise, AI tools must be configured to trust the intermediate CA certificate from the endpoint above.

How you configure AI tools to trust the certificate depends on the tool and operating system. See [Client Configuration](#client-configuration) for details.

## Proxy TLS Configuration

By default, the AI Gateway Proxy listener accepts plain HTTP connections.
When TLS is enabled, the proxy serves over HTTPS, encrypting the connection between AI tools and the proxy.

The TLS certificate is separate from the [MITM CA certificate](#ca-certificate).
The CA certificate is used to sign dynamically generated certificates during MITM interception.
The TLS certificate identifies the proxy itself, like any standard web server certificate.

The AI Gateway Proxy enforces a minimum TLS version of 1.2.

### Configuration

In addition to the required proxy configuration, set the following to enable TLS on the proxy:

```shell
CODER_AIBRIDGE_PROXY_TLS_CERT_FILE=/path/to/listener.crt
CODER_AIBRIDGE_PROXY_TLS_KEY_FILE=/path/to/listener.key
# or via CLI flags:
--aibridge-proxy-tls-cert-file=/path/to/listener.crt
--aibridge-proxy-tls-key-file=/path/to/listener.key
```

Both files must be provided together. If only one is set, the proxy will fail to start.

### Self-signed certificate

Use a self-signed certificate when your organization doesn't have an internal CA, or when you want a dedicated certificate specifically for the AI Gateway Proxy.

The TLS certificate must include a Subject Alternative Name (SAN) matching the hostname or IP address that clients use to connect to the proxy.
Without a matching SAN, clients will reject the connection.

1) Generate a private key:

```shell
openssl genrsa -out listener.key 4096
chmod 400 listener.key
```

1) Create a self-signed certificate:

```shell
openssl req -new -x509 -days 365 \
  -key listener.key \
  -out listener.crt \
  -subj "/CN=<proxy-host>" \
  -addext "subjectAltName=DNS:<proxy-host>,IP:<proxy-ip>"
```

Replace `<proxy-host>` and `<proxy-ip>` with the hostname and IP address that clients use to connect to the proxy.

### Corporate CA certificate

If your organization has an internal CA, have it issue a leaf certificate for the proxy.
The certificate must include a SAN matching the proxy's hostname or IP address.

If clients already trust your organization's root CA, no additional certificate configuration is needed for the TLS connection to the proxy.

### Trusting the TLS certificate

For **self-signed certificates**, AI tools must be configured to trust the TLS certificate.

For **corporate CA certificates**, if the systems where AI tools run already trust your organization's root CA, no additional configuration is needed.

How you configure AI tools to trust the certificate depends on the tool and operating system.
See [Client Configuration](#client-configuration) for details.

## Upstream proxy

If your organization requires all outbound traffic to pass through a corporate proxy, you can configure AI Gateway Proxy to chain requests to an upstream proxy.

> [!NOTE]
> AI Gateway Proxy must be the first proxy in the chain.
> AI tools must be configured to connect directly to AI Gateway Proxy, which then forwards tunneled traffic to the upstream proxy.

### How it works

Tunneled requests (non-allowlisted domains) are forwarded to the upstream proxy configured via [`CODER_AIBRIDGE_PROXY_UPSTREAM`](../../../reference/cli/server.md#--aibridge-proxy-upstream).

MITM'd requests (AI provider domains) are forwarded to AI Gateway, which then communicates with AI providers.
To ensure AI Gateway also routes requests through the upstream proxy, make sure to configure the proxy settings for the Coder server process.

<!-- TODO(ssncferreira): Add diagram showing how AI Gateway Proxy integrates with upstream proxies -->

> [!NOTE]
> When an upstream proxy is configured, AI Gateway Proxy validates the destination IP before forwarding the request.
> However, the upstream proxy re-resolves DNS independently, so a small DNS rebinding window exists between the validation and the actual connection.
> Ensure your upstream proxy enforces its own restrictions on private and reserved IP ranges.

### Configuration

Configure the upstream proxy URL:

```shell
CODER_AIBRIDGE_PROXY_UPSTREAM=http://<corporate-proxy-url>:8080
```

For HTTPS upstream proxies, if the upstream proxy uses a certificate not trusted by the system, provide the CA certificate:

```shell
CODER_AIBRIDGE_PROXY_UPSTREAM=https://<corporate-proxy-url>:8080
CODER_AIBRIDGE_PROXY_UPSTREAM_CA=/path/to/corporate-ca.crt
```

If the system already trusts the upstream proxy's CA certificate, [`CODER_AIBRIDGE_PROXY_UPSTREAM_CA`](../../../reference/cli/server.md#--aibridge-proxy-upstream-ca) is not required.

<!-- TODO(ssncferreira): Add Client Configuration section -->

<!-- TODO(ssncferreira): Add Troubleshooting section -->

## Client Configuration

To use AI Gateway Proxy, AI tools must be configured to:

1. Route traffic through the proxy
1. Trust the proxy's CA certificate

### Configuring the proxy

The preferred approach is to configure the proxy directly in the AI tool's settings, as this avoids routing unnecessary traffic through the proxy.
Consult the tool's documentation for specific instructions.

Alternatively, most tools support the standard `HTTPS_PROXY` environment variable, though this is not guaranteed for all tools:

```shell
export HTTPS_PROXY="https://coder:${CODER_SESSION_TOKEN}@<proxy-host>:8888"
```

Note: if [TLS is not enabled](#proxy-tls-configuration) on the proxy, replace `https://` with `http://` in the proxy URL.

`HTTPS_PROXY` is used for requests to `https://` URLs, which includes all supported AI provider domains.

> [!NOTE]
> `HTTP_PROXY` is not required since AI providers only use `HTTPS`.
> Leaving it unset avoids routing unnecessary traffic through the proxy.

In order for AI tools that communicate with AI Gateway Proxy to authenticate with Coder via AI Gateway, the Coder session token needs to be passed in the proxy credentials as the password field.

### Trusting the CA certificate

The preferred approach is to configure the CA certificate directly in the AI tool's settings, as this limits the scope of the trusted certificate to that specific application.
Consult the tool's documentation for specific instructions.

> [!NOTE]
> If using a [corporate CA certificate](#corporate-ca-certificate) and the system already trusts your organization's root CA, no additional certificate configuration is required.

Download the certificate:

```shell
curl -o coder-aibridge-proxy-ca.pem \
  -H "Coder-Session-Token: ${CODER_SESSION_TOKEN}" \
  https://<coder-url>/api/v2/aibridge/proxy/ca-cert.pem
```

Replace `<coder-url>` with your Coder deployment URL.

When [TLS is enabled](#proxy-tls-configuration) on the proxy, AI tools must trust both the [MITM CA certificate](#ca-certificate) and the [TLS certificate](#proxy-tls-configuration).
Combine both certificates into a single PEM file:

```shell
cat coder-aibridge-proxy-ca.pem listener.crt > combined-ca.pem
```

Use this combined file for any of the environment variables listed below.

#### Environment variables

Different AI tools use different runtimes, each with their own environment variable for CA certificates:

| Environment Variable  | Runtime                   |
|-----------------------|---------------------------|
| `NODE_EXTRA_CA_CERTS` | Node.js                   |
| `SSL_CERT_FILE`       | OpenSSL, Python, curl     |
| `REQUESTS_CA_BUNDLE`  | Python `requests` library |
| `CURL_CA_BUNDLE`      | curl                      |

Set the environment variables associated with the AI tool's runtime.
If you're unsure which runtime the tool uses, or if you use multiple AI tools, the simplest approach is to set all of them:

```shell
export NODE_EXTRA_CA_CERTS="/path/to/coder-aibridge-proxy-ca.pem"
export SSL_CERT_FILE="/path/to/coder-aibridge-proxy-ca.pem"
export REQUESTS_CA_BUNDLE="/path/to/coder-aibridge-proxy-ca.pem"
export CURL_CA_BUNDLE="/path/to/coder-aibridge-proxy-ca.pem"
```

#### System trust store

When tool-specific or environment variable configuration is not possible, you can add the certificate to the system trust store.
This makes the certificate trusted by all applications on the system.

On Linux:

```shell
sudo cp coder-aibridge-proxy-ca.pem /usr/local/share/ca-certificates/
sudo update-ca-certificates
```

For other operating systems, refer to the system's documentation for instructions on adding trusted certificates.

### Coder workspaces

For AI tools running inside Coder workspaces, template administrators can pre-configure the proxy settings and CA certificate in the workspace template.
This provides a seamless experience where users don't need to configure anything manually.

<!-- TODO(ssncferreira): Add registry link for AI Gateway Proxy module for Coder workspaces: https://github.com/coder/internal/issues/1187 -->

For tool-specific configuration details, check the [client compatibility table](../clients/index.md#compatibility) for clients that require proxy-based integration.

---

# Auditing AI Sessions

Source: https://coder.com/docs/ai-coder/ai-gateway/audit

# Auditing AI Sessions

AI Gateway groups intercepted requests into **sessions** and **threads** to show
the causal relationships between human prompts and agent actions. This
structure gives auditors clear provenance over who initiated what, and why.

## Concepts

| Term             | Definition                                                                                                                                                                                                                                            |
|------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Interception** | A single intercepted request/response pair between client and provider.                                                                                                                                                |                                                                               |
| **Thread**       | A multi-part interaction starting with a human prompt that triggers one or more tool calls, forming an agentic loop.                                                                                                                                  |
| **Agentic loop** | A sequence of tool invocations the agent performs to satisfy a request. The model ends its turn with a tool call, the client invokes it, sends the result back, and the cycle repeats until the model has enough information to formulate a response. |
| **Session**      | A set of threads grouped by a client-provided session key. Claude Code and Codex provide session IDs automatically; other clients may not.                                                                                                            |

## Human vs. Agent attribution

AI Gateway distinguishes between human-initiated and agent-initiated requests
using the `role` property:

- A message with `role="user"` indicates a human-initiated action (i.e. prompt).
- A message with `role="assistant"` indicates a message generated by a model.
- A message with `role="system"` indicates the system prompt for the client.

The `user` role is currently overloaded by clients like Claude Code and Codex;
they inject system instructions
within `role="user"` blocks when using agents. AI Gateway applies a heuristic
of storing only the **last** prompt from a block of `role="user"` messages.

> [!NOTE]
> AI Gateway cannot declare with certainty whether a request was human- or
> agent-initiated.

## LLM reasoning capture

AI Gateway captures model reasoning and thinking content when available. Both
Anthropic (extended thinking) and OpenAI (reasoning summaries) support this
feature. Reasoning data gives auditors insight into **why** a tool was called,
not just what was called.

## Navigating the UI

### Sessions list

The sessions page (`http://<deployment-url>/aibridge/sessions`) lists all sessions in
reverse-chronological order. Each row shows the last prompt, initiator, provider,
client, token usage, thread count, and timestamp.

Select one to view its full details.

![Sessions](../../images/aibridge/sessions.png)

### Session detail

Click into a session to see a chronological causal chain of events.

Within a thread, each step shows token usage, tool call details (including
arguments and MCP server URLs), duration, and any errors or warnings.

![Session detail](../../images/aibridge/session_detail.png)

## Conducting a forensic audit

When investigating an incident (policy violation, destructive action, etc.):

1. **Identify the session.** Filter by user, time range, or client to find the
   relevant session.
1. **Locate the thread.** Each thread in a session shows the (likely) human prompt
   that initiated the chain of actions.
1. **Trace the causal chain.** Expand the thread to see every step in the
   agentic loop — each tool call and its arguments.
1. **Review model reasoning.** If extended thinking was enabled, check the
   model's reasoning at each step to understand why specific tools were called.
1. **Assess attribution.** The session identifies the human who
   initiated the action. Subsequent interceptions represent agent-driven actions
   that stem from that original prompt.

## What we store

AI Gateway captures the following data from each request/response:

- Last user prompt
- Token usage
- Tool calls (requests only, not responses)
  - Responses may be very large, and generally have lower audit value than requests
  - In future, we will support storing these results
- Model thinking/reasoning

Model-produced inference text is discarded, as generated text alone
cannot affect external systems. The retention philosophy prioritizes:

- **Human prompts** — capture intent and detect policy violations or
  exfiltration attempts.
- **Tool calls** — record how agents interact with external systems,
  which is critical for understanding how incidents occurred. For
  example, an agent might delete and recreate a database because it
  lacks permissions to satisfy a human request to query a table.
- **Model reasoning** — preserve thinking content that explains why
  specific tools were invoked, distinguishing between human instruction
  and model misunderstanding as the root cause.

See [data retention](./setup.md#data-retention) to configure how long
session data is kept.

## Next steps

- [Monitoring](./monitoring.md) — Dashboards, data export, and tracing
- [Setup](./setup.md) — Configure AI Gateway and data retention
- [Reference](./reference.md) — API and technical reference

---

# Monitoring

Source: https://coder.com/docs/ai-coder/ai-gateway/monitoring

# Monitoring

AI Gateway records the last `user` prompt, token usage, model reasoning, and every tool invocation for each intercepted request. Each capture is tied to a single "interception" that maps back to the authenticated Coder identity, making it easy to attribute spend and behaviour.

![User Prompt logging](../../images/aibridge/grafana_user_prompts_logging.png)

![User Leaderboard](../../images/aibridge/grafana_user_leaderboard.png)

We provide an example Grafana dashboard that you can import as a starting point for your metrics. See [the Grafana dashboard README](https://github.com/coder/coder/blob/main/examples/monitoring/dashboards/grafana/aibridge/README.md).

These logs and metrics can be used to determine usage patterns, track costs, and evaluate tooling adoption.

## Structured Logging

AI Bridge can emit structured logs for every interception event to your
existing log pipeline. This is useful for exporting data to external SIEM or
observability platforms. See [Structured Logging](./setup.md#structured-logging)
in the setup guide for configuration and a full list of record types.

## Exporting Data

AI Gateway interception data can be exported for external analysis, compliance reporting, or integration with log aggregation systems.

### REST API

You can retrieve AI Gateway sessions via the Coder API, with filtering and pagination support.

```sh
curl -X GET "https://coder.example.com/api/v2/aibridge/sessions" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```

Available query filters:

- `client` - Filter by client name.
  <details>
  <summary>Possible <code>client</code> values</summary>

  > [!NOTE]
  > Client classification is done on best effort basis using the `User-Agent` header;
  not all clients send these headers in an easily-identifiable manner.

  - `Claude Code`
  - `Codex`
  - `Zed`
  - `GitHub Copilot (VS Code)`
  - `GitHub Copilot (CLI)`
  - `Kilo Code`
  - `Coder Agents`
  - `Mux`
  - `Roo Code`
  - `Cursor`
  - `Unknown`

  </details><br>
- `initiator` - Filter by user ID or username
- `provider` - Filter by AI provider (e.g., `openai`, `anthropic`)
- `model` - Filter by model name
- `started_after` - Filter interceptions after a timestamp
- `started_before` - Filter interceptions before a timestamp

See the [API documentation](../../reference/api/aibridge.md) for full details.

### CLI

Export interceptions as JSON using the CLI:

```sh
coder aibridge interceptions list --initiator me --limit 1000
```

You can filter by time range, provider, model, and user:

```sh
coder aibridge interceptions list \
  --started-after "2025-01-01T00:00:00Z" \
  --started-before "2025-02-01T00:00:00Z" \
  --provider anthropic
```

See `coder aibridge interceptions list --help` for all options.

## Data Retention

AI Gateway data is retained for **60 days by default**. Configure the retention
period to balance storage costs with your organization's compliance and analysis
needs.

For configuration options and details, see [Data Retention](./setup.md#data-retention)
in the AI Gateway setup guide.

## Tracing

AI Gateway supports tracing via [OpenTelemetry](https://opentelemetry.io/),
providing visibility into request processing, upstream API calls, and MCP server
interactions.

### Enabling Tracing

AI Gateway tracing is enabled when tracing is enabled for the Coder server.
To enable tracing set `CODER_TRACE_ENABLE` environment variable or
[--trace](https://coder.com/docs/reference/cli/server#--trace) CLI flag:

```sh
export CODER_TRACE_ENABLE=true
```

```sh
coder server --trace
```

### What is Traced

AI Gateway creates spans for the following operations:

| Span Name                                   | Description                                          |
|---------------------------------------------|------------------------------------------------------|
| `CachedBridgePool.Acquire`                  | Acquiring a request bridge instance from the pool    |
| `Intercept`                                 | Top-level span for processing an intercepted request |
| `Intercept.CreateInterceptor`               | Creating the request interceptor                     |
| `Intercept.ProcessRequest`                  | Processing the request through the bridge            |
| `Intercept.ProcessRequest.Upstream`         | Forwarding the request to the upstream AI provider   |
| `Intercept.ProcessRequest.ToolCall`         | Executing a tool call requested by the AI model      |
| `Intercept.RecordInterception`              | Recording creating interception record               |
| `Intercept.RecordPromptUsage`               | Recording prompt/message data                        |
| `Intercept.RecordTokenUsage`                | Recording token consumption                          |
| `Intercept.RecordToolUsage`                 | Recording tool/function calls                        |
| `Intercept.RecordInterceptionEnded`         | Recording the interception as completed              |
| `ServerProxyManager.Init`                   | Initializing MCP server proxy connections            |
| `StreamableHTTPServerProxy.Init`            | Setting up HTTP-based MCP server proxies             |
| `StreamableHTTPServerProxy.Init.fetchTools` | Fetching available tools from MCP servers            |

Example trace of an interception using Jaeger backend:

![Trace of interception](../../images/aibridge/jaeger_interception_trace.png)

### Capturing Logs in Traces

> [!NOTE]
> Enabling log capture may generate a large volume of trace events.

To include log messages as trace events, enable trace log capture
by setting `CODER_TRACE_LOGS` environment variable or using
[--trace-logs](https://coder.com/docs/reference/cli/server#--trace-logs) flag:

```sh
export CODER_TRACE_ENABLE=true
export CODER_TRACE_LOGS=true
```

```sh
coder server --trace --trace-logs
```

---

# Reference

Source: https://coder.com/docs/ai-coder/ai-gateway/reference

# Reference

## Implementation Details

`coderd` runs an in-memory instance of `aibridged`, whose logic is mostly contained in https://github.com/coder/coder/tree/main/aibridge. In future releases we will support running external instances for higher throughput and complete memory isolation from `coderd`.

![AI Gateway implementation details](../../images/aibridge/aibridge-implementation-details.png)

## Supported APIs

API support is broken down into two categories:

- **Intercepted**: requests are intercepted, audited, and augmented - full AI Gateway functionality
- **Passthrough**: requests are proxied directly to the upstream, no auditing or augmentation takes place

Where relevant, both streaming and non-streaming requests are supported.

### OpenAI

#### Intercepted

- [`/v1/chat/completions`](https://platform.openai.com/docs/api-reference/chat/create)
- [`/v1/responses`](https://platform.openai.com/docs/api-reference/responses/create)

#### Passthrough

- [`/v1/models(/*)`](https://platform.openai.com/docs/api-reference/models/list)

### Anthropic

#### Intercepted

- [`/v1/messages`](https://docs.claude.com/en/api/messages)

#### Passthrough

- [`/v1/models(/*)`](https://docs.claude.com/en/api/models-list)

## Troubleshooting

To report a bug, file a feature request, or view a list of known issues, please visit our [GitHub repository](https://github.com/coder/coder/issues). If you encounter issues with AI Gateway, please reach out to us via [Discord](https://discord.gg/coder).

---

# Usage Data Reporting

Source: https://coder.com/docs/ai-coder/usage-data-reporting

# Usage Data Reporting

The [AI Governance Add-On](./ai-governance.md) requires reporting usage data to Tallyman, a Coder-managed server for billing and reporting purposes. Coder only captures and sends the following information, related to your deployment ID:

- number of agent workspace builds consumed
- number of AI Governance seats consumed

No user-identifiable information or additional metrics are sent to Tallyman. This information is also shared with [Metronome](https://metronome.com), a Stripe product and Coder partner for usage-based and reporting.

To send usage data, your Coder deployment must be able to make outbound HTTPS requests to `https://tallyman-prod.coder.com`. Usage data is sent approximately every 17 minutes and can be monitored via `coderd` logs.

Example of a successful request (requires debug logging enabled [`CODER_LOG_FILTER=.*`](../reference/cli/server.md#-l---log-filter)):

```sh
[debu] published usage events to tallyman accepted=5 rejected=0
```

Example of a request payload:

```sh
POST /api/v1/events/ingest HTTP/1.1
Host: tallyman-prod.coder.com
Content-Type: application/json
Coder-License-Key: <license-jwt> # your license JWT for verification
Coder-Deployment-ID: 8a4e92f1-3b7c-4d5e-9f12-abc123def456 # your deployment ID

{
  "events": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000", # unique event ID generated by Coder
      "event_type": "dc_managed_agents_v1", # aka. agent workspace builds
      "event_data": {
        "count": 1
      },
      "created_at": "2025-01-15T14:30:00Z"
    }
  ]
}
```

Example of a failed request (e.g. Tallyman Server is blocked by your network):

```sh
[warn] failed to send publish request to tallyman count=5 error="Post \"https://tallyman-prod.coder.com/api/v1/events/ingest\": dial tcp: lookup tallyman-prod.coder.com: no such host"
```

> [!NOTE]
> Air-gapped deployments and/or those with legal restrictions around usage reporting can [contact us](https://coder.com/contact) to discuss alternative methods.

---

# MCP Server

Source: https://coder.com/docs/ai-coder/mcp-server

# MCP Server

Power users can configure [claude.ai](https://claude.ai), Claude Desktop, Cursor, or other external agents to interact with Coder in order to:

- List workspaces
- Create/start/stop workspaces
- Run commands on workspaces
- Check in on agent activity

> [!NOTE]
> See our [toolsdk](https://pkg.go.dev/github.com/coder/coder/v2/codersdk/toolsdk#pkg-variables) documentation for a full list of tools included in the MCP server

In this model, any custom agent could interact with a remote Coder workspace, or Coder can be used in a remote pipeline or a larger workflow.

## Local MCP server

The Coder CLI has options to automatically configure MCP servers for you. On your local machine, run the following command:

```sh
# First log in to Coder. 
coder login <https://coder.example.com>

# Configure your client with the Coder MCP
coder exp mcp configure claude-desktop # Configure Claude Desktop to interact with Coder
coder exp mcp configure cursor # Configure Cursor to interact with Coder
```

For other agents, run the MCP server with this command:

```sh
coder exp mcp server
```

> [!NOTE]
> The MCP server is authenticated with the same identity as your Coder CLI and can perform any action on the user's behalf. Fine-grained permissions are in development. [Contact us](https://coder.com/contact) if this use case is important to you.

## Remote MCP server

Coder can expose an MCP server via HTTP. This is useful for connecting web-based agents, like https://claude.ai/, to Coder. This is an experimental feature and is subject to change.

To enable this feature, activate the `oauth2` and `mcp-server-http` experiments using an environment variable or a CLI flag:

```sh
CODER_EXPERIMENTS="oauth2,mcp-server-http" coder server
# or
coder server --experiments=oauth2,mcp-server-http
```

The Coder server will expose the MCP server at:

```txt
https://coder.example.com/api/experimental/mcp/http
```

> [!NOTE]
> At this time, the remote MCP server is not compatible with web-based ChatGPT.

Users can authenticate applications to use the remote MCP server with [OAuth2](../admin/integrations/oauth2-provider.md). An authenticated application can perform any action on the user's behalf. Fine-grained permissions are in development.

---

# Coder Tasks

Source: https://coder.com/docs/ai-coder/tasks

# Coder Tasks

> [!WARNING]
> Starting June 2, 2026, Coder Tasks will move to a 12-month Extended Support Release (ESR) for Premium customers.
>
> Tasks will be removed from new Coder releases beginning with v2.37 (September 1, 2026) and will only be available via the ESR during the support period.
>
> We recommend transitioning to [Coder Agents](./agents/index.md), the long-term replacement.

Coder Tasks is an interface for running & managing coding agents such as Claude Code and Aider, powered by Coder workspaces.

![Tasks UI](../images/guides/ai-agents/tasks-ui.png)

Coder Tasks is best for cases where the IDE is secondary, such as prototyping or running long-running background jobs. However, tasks run inside full workspaces so developers can [connect via an IDE](../user-guides/workspace-access) to take a task to completion.

You can also interact with Coder Tasks from your IDE. The [Coder extension for VS Code](https://marketplace.visualstudio.com/items?itemName=coder.coder-remote) (and compatible forks like Cursor) enables you to create, monitor, and manage Tasks directly from the IDE, eliminating the need to context-switch to a browser. After logging in, you get access to a dedicated Tasks view in the sidebar that lets you select a template, configure parameters, prompt an agent, and track task status or download logs. Your tasks run in Coder workspaces with access to your repos, credentials, and internal network.

![VS Code IDE Extension](../images/guides/ai-agents/vs_code_tasks_extension.png)

The Task details view shows the user's complete chat, workspace status and, build or startup logs so you can understand what the Task is doing and troubleshoot failures. This makes it easier to confirm progress and diagnose issues without leaving the Task workflow.

![VS Code IDE Extension Details View](../images/guides/ai-agents/vs_code_tasks_extension_details.png)

> [!NOTE]
> Both Community and Premium deployments include 1,000 Agent Workspace Builds for proof-of-concept use. Community deployments do not have access to [AI Gateway](./ai-gateway/index.md) or [Agent Firewall](./agent-firewall/index.md). To scale beyond the 1,000 build limit or enable AI Governance features, the [AI Governance Add-On](./ai-governance.md) provides expanded usage pools that grow with your user count. [Contact us](https://coder.com/contact) to discuss pricing.

## Supported Agents (and Models)

Any terminal-based agent that supports Model Context Protocol (MCP) can be integrated with Coder Tasks, including your own custom agents.

Out of the box, agents like Claude Code and Goose are supported with built-in modules that can be added to a template. [See all modules compatible with Tasks in the Registry](https://registry.coder.com/modules?search=tag%3Atasks).

Enterprise LLM Providers such as AWS Bedrock, GCP Vertex and proxies such as LiteLLM can be used as well in order to keep intellectual property private. Self-hosted models such as llama4 can also be configured with specific agents, such as Aider and Goose.

## Architecture

Each task runs inside its own Coder workspace for isolation purposes. Agents like Claude Code also run in the workspace, and can be pre-installed via a module in the Coder Template. Agents then communicate with your LLM provider, so no GPUs are directly required in your workspaces for inference.

![High-Level Architecture](../images/guides/ai-agents/architecture-high-level.png)

Coder's [built-in modules for agents](https://registry.coder.com/modules?search=tag%3Atasks) will pre-install the agent alongside [AgentAPI](https://github.com/coder/agentapi). AgentAPI is an open source project developed by Coder which improves status reporting and the Chat UI, regardless of which agent you use.

## Getting Started with Tasks

### Option 1&rpar; Import and Modify Our Example Template

Our example template is the best way to experiment with Tasks with a [real world demo app](https://github.com/gothinkster/realworld). The application is running in the background and you can experiment with coding agents.

![Tasks UI with realworld app](../images/guides/ai-agents/realworld-ui.png)

Try prompts such as:

- "rewrite the backend in go"
- "document the project structure"
- "change the primary color theme to purple"

To import the template and begin configuring it, import the example [Run Coder Tasks on Docker](https://github.com/coder/coder/tree/main/examples/templates/tasks-docker) template.

### Option 2&rpar; Create or Duplicate Your Own Template

A template becomes a Task-capable template if it defines a `coder_ai_task` resource. Coder analyzes template files during template version import to determine if these requirements are met. Try adding this terraform block to an existing template where you'll add our Claude Code module.

> [!NOTE]
> The `coder_ai_task` resource is not defined within the [Claude Code Module](https://registry.coder.com/modules/coder/claude-code?tab=readme). You need to define it yourself.

```hcl
terraform {
  required_providers {
    coder = {
      source = "coder/coder"
      version = ">= 2.13"
    }
  }
}

data "coder_parameter" "setup_script" {
  name         = "setup_script"
  display_name = "Setup Script"
  type         = "string"
  form_type    = "textarea"
  description  = "Script to run before running the agent"
  mutable      = false
  default      = ""
}

data "coder_task" "me" {}

resource "coder_ai_task" "task" {
  app_id = module.claude-code.task_app_id
}

# The Claude Code module does the automatic task reporting
# Other agent modules: https://registry.coder.com/modules?search=agent
# Or use a custom agent:
module "claude-code" {
  source   = "registry.coder.com/coder/claude-code/coder"
  version  = "4.0.0"
  agent_id = coder_agent.example.id
  workdir  = "/home/coder/project"

  claude_api_key = var.anthropic_api_key
  # OR
  # claude_code_oauth_token = var.anthropic_oauth_token

  claude_code_version = "1.0.82" # Pin to a specific version
  agentapi_version    = "v0.6.1"

  ai_prompt = data.coder_task.me.prompt
  model     = "sonnet"

  # Optional: run your pre-flight script
  # pre_install_script = data.coder_parameter.setup_script.value

  permission_mode = "plan"

  mcp = <<-EOF
  {
    "mcpServers": {
      "my-custom-tool": {
        "command": "my-tool-server",
        "args": ["--port", "8080"]
      }
    }
  }
  EOF
}

# Rename to `anthropic_oauth_token` if using the Oauth Token
variable "anthropic_api_key" {
  type        = string
  description = "Generate one at: https://console.anthropic.com/settings/keys"
  sensitive   = true
}
```

Because Tasks run unpredictable AI agents, often for background tasks, we recommend creating a separate template for Coder Tasks with limited permissions. You can always duplicate your existing template, then apply separate network policies/firewalls/permissions to the template. From there, follow the docs for one of our [built-in modules for agents](https://registry.coder.com/modules?search=tag%3Atasks) in order to add it to your template, configure your LLM provider.

Alternatively, follow our guide for [custom agents](./custom-agents.md).

> [!IMPORTANT]
> Upgrading from Coder v2.27 or earlier? See the [Tasks Migration Guide](./tasks-migration.md) for breaking changes in v2.28.0.

## Customizing the Task UI

The Task UI displays all workspace apps declared in a Task template. You can customize the app shown in the sidebar using the `app_id` field on the `coder_ai_task` resource.

If a workspace app has the special `"preview"` slug, a navbar will appear above it. This is intended for templates that let users preview a web app they’re working on.

We plan to introduce more customization options in future releases.

## Automatically name your tasks

Coder can automatically generate a name your tasks if you set the `ANTHROPIC_API_KEY` environment variable on the Coder server. Otherwise, tasks will be given randomly generated names.

## Opting out of Tasks

If you tried Tasks and decided you don't want to use it, you can hide the Tasks tab by starting `coder server` with the `CODER_HIDE_AI_TASKS=true` environment variable or the `--hide-ai-tasks` flag.

## Pausing and resuming tasks

Tasks automatically pause when the workspace reaches its idle timeout,
freeing compute resources. While paused, you can view a snapshot of the
last conversation messages. When you resume or send a new message, the
workspace restarts and the agent picks up where it left off if the agent
and template support session persistence.

For details on how pause and resume works and what your template needs,
see [Task lifecycle](./tasks-lifecycle.md).

## Command Line Interface

See [Tasks CLI](./cli.md).

## Next Steps

<children></children>

---

# Understanding Coder Tasks

Source: https://coder.com/docs/ai-coder/tasks-core-principles

# Understanding Coder Tasks

> [!WARNING]
> Starting June 2, 2026, Coder Tasks will move to a 12-month Extended Support Release (ESR) for Premium customers.
>
> Tasks will be removed from new Coder releases beginning with v2.37 (September 1, 2026) and will only be available via the ESR during the support period.
>
> We recommend transitioning to [Coder Agents](./agents/index.md), the long-term replacement.

## What is a Task?

Coder Tasks is Coder's platform for managing coding agents. With Coder Tasks, you can:

- Run an AI Agent like Claude Code or OpenAI's Codex in your Workspace to assist in day-to-day development and building
- Kick off AI-enabled workflows such as upgrading a vulnerable package and automatically opening a GitHub Pull Requests with the patch
- Configure a background operation where an automated agent can detect a failure in your CI/CD pipeline, spin up a Coder Workspace, apply a fix, and prepare a PR _without_ manual input

![Tasks UI](../images/guides/ai-agents/tasks-ui.png)Coder Tasks Dashboard view to see all available tasks.

Coder Tasks allows you and your organization to build and automate workflows to fully leverage AI. Tasks operate through Coder Workspaces. We support interacting with an agent through the Task UI and CLI. Some Tasks can also be accessed through the Coder Workspace IDE; see [connect via an IDE](../user-guides/workspace-access).

## Why Use Tasks?

Coder Tasks make both developer-driven _and_ autonomous agentic workflows first-class citizens within your organization. Without Coder Tasks, teams revert to ad-hoc scripts, one-off commands, or manual checklists even for tasks that LLMs could automate. These workarounds can help a single engineer, but don't scale or provide consistency across an organization that is attempting to use AI as a true force multiplier.

Coder Tasks exist to solve these types of problems:

- **Consistency:** Capture a known, safe, & secure workflow once that can then be run anywhere
- **Reproducibility:** Every task runs from a Coder Workspace, so results are reliable
- **Productivity:** Eliminate manual processes from developer processes enabling them to focus on less defined and harder-to-do issues
- **Scalability:** Once a workflow is captured in a task, it can be reused by other teams within your organization scaling with you as you grow
- **Flexibility:** Support both developer _AND_ autonomous agentic workflows

### Example Task Workflow

Coder Tasks aren't limited to manual operation. They can operate as event-driven automations triggered by your team's everyday activities. Tasks can be thought of through two different type of triggers: manual and event-driven. In the below diagram, the user reported bug could result in a task being spun up via:

- **Event-Driven:** An automatic hook in your git repository
- **Manual:** An engineer reviewing the bug backlog manually creates a task

Other common triggers for event-based workflows include PRs being created/updated, a failure in your CI/CD pipeline, or issues being created/updated in your repository.

![Example Background Task](../images/guides/ai-agents/background-task-example.png)Example of Background Coder Tasks operation.

## How to Make a Task Template

If you need a refresher on Coder Templates, check out our [starting guide here](https://coder.com/docs/tutorials/template-from-scratch).

### What Makes a Task Template

Task Templates are regular Coder Templates with a few additional resources defined. These resources include the logic that lets the Coder UI and infrastructure recognize a Task, and prepare the system for automated execution and AI-driven workflows rather than development environments for developers and builders.

There are two approaches to turning a Template into a Task Template:

#### Using a Registry Module

You can use a pre-existing agent module that [Coder maintains](https://registry.coder.com/modules). When using an agent module, you must define:

- `coder_ai_task` resource: links a `coder_app` to a Task.
- **Agentic Module** that defines the agent you want to use, e.g. Claude Code, Codex CLI, Gemini CLI

Coder maintains various agentic modules; see [Coder Labs](https://registry.coder.com/contributors/coder-labs). These modules, in addition to defining connection information for the specific agent, reference the [AgentAPI module](https://registry.coder.com/modules/coder/agentapi) which provides connection, reporting, and agent life cycle management operations. The modules also output the specific `coder_app` identifier for the specific agent running inside the workspace.

The following code snippet can be dropped into any existing template in Coder v2.28 or above to modify it into a Claude-Code enabled task template. This snippet also includes space for a setup script that will prime the agent for execution.

> [!NOTE]
> This requires at least version 2.13.0 of the `coder/coder` Terraform provider.

```hcl
data "coder_parameter" "setup_script" {
  name         = "setup_script"
  display_name = "Setup Script"
  type         = "string"
  form_type    = "textarea"
  description  = "Script to run before running the agent"
  mutable      = false
  default      = ""
}

data "coder_task" "me" {}

resource "coder_ai_task" "task" {
  app_id = module.claude-code.task_app_id
}

# The Claude Code module does the automatic task reporting
# Other agent modules: https://registry.coder.com/modules?search=agent
# Or use a custom agent:
module "claude-code" {
  source   = "registry.coder.com/coder/claude-code/coder"
  version  = "4.0.0"
  agent_id = coder_agent.example.id
  workdir  = "/home/coder/project"

  claude_api_key = var.anthropic_api_key
  # OR
  # claude_code_oauth_token = var.anthropic_oauth_token

  claude_code_version = "1.0.82" # Pin to a specific version
  agentapi_version    = "v0.6.1"

  ai_prompt = data.coder_task.me.prompt
  model     = "sonnet"

  # Optional: run your pre-flight script
  # pre_install_script = data.coder_parameter.setup_script.value

  permission_mode = "plan"

  mcp = <<-EOF
  {
    "mcpServers": {
      "my-custom-tool": {
        "command": "my-tool-server",
        "args": ["--port", "8080"]
      }
    }
  }
  EOF
}

# Rename to `anthropic_oauth_token` if using the Oauth Token
variable "anthropic_api_key" {
  type        = string
  description = "Generate one at: https://console.anthropic.com/settings/keys"
  sensitive   = true
}
```

Let's break down this snippet:

- The `module "claude-code"` sets up the Task template to use Claude Code. Coder's Registry supports many other agent modules like [OpenAI's Codex](https://registry.coder.com/modules/coder-labs/codex) or [Gemini CLI](https://registry.coder.com/modules/coder-labs/gemini)
- Each module defines its own specific inputs. Claude Code expects the `claude_api_key` input, but OpenAI based agents expect `OPENAI_API_KEY` for example. You'll want to check the specific module's defined variables to know what exactly needs to be defined. You will also generally need to pass `data.coder_task.me.prompt`
- Each module outputs the UUID of the `coder_app` related to the AI agent. In the above example, the output is named `task_app_id`. See the relevant documentation for the module for more detailed information.
- You can define specific scripts to run before the module is installed, `pre_install_script`, or after install, `pre_install_script`. For example, you could define a setup script that calls to AWS S3 and pulls specific files you want your agent to have access to

#### Using a Custom Agent

Coder allows you to define a custom agent. When doing so, you must define:

- A `coder_app` resource that uses [`coder/agentapi`](https://github.com/coder/agentapi) to run the custom agent. **AgentAPI** provides runtime execution logistics for the task.
- A `coder_ai_task` resource which associates the `coder_app` related to the AI agent with the Task.

You can find the latest [AgentAPI binary here](https://github.com/coder/agentapi/releases). You can alternatively import and use the [AgentAPI module](https://registry.coder.com/modules/coder/agentapi?tab=variables) Coder maintains.

Read more about [custom agents here](https://coder.com/docs/ai-coder/custom-agents).

#### Putting it all Together

Coder recommends using pre-existing agent modules when making a Task Template. Making a Task Template boils down to:

1. Identify the existing agent you want access to in our [Registry](https://registry.coder.com/modules).
1. Add the agent's module to your existing template.
1. Define the `coder_ai_task` resource and `coder_task` data source.
1. Wire in the module's inputs and outputs:
    - Pass the prompt from the `coder_task` data source into the module.
    - Pass the module's `task_app_id` output into the `coder_ai_task` resource.

and you're all set to go! If you want to build your own custom agent, read up on our [Custom Agents](https://coder.com/docs/ai-coder/custom-agents) documentation.

In summary, Task Templates are highly flexible. You can swap out modules depending on which agent you want to run, adjust their inputs based on the provider's requirements, and layer on custom setup scripts to tailor the environment to your workflow. Whether that means using a different LLM, pointing to a new API key, or pulling files from S3 at startup, the template structure makes it easy to adapt tasks without having to rebuild everything from scratch.

## Task Template Design Principles

Coder Tasks, being based in a given Workspace, operate on very similar principles:

- **Specificity & Refinability:** Tasks, just like Templates, are made to address a specific problem and evolve with that problem and your team over time
- **Security:** Because Tasks are defined through templates, you can define and restrict what access an agent running inside a Task has access to
- **Frugality:** Tasks only consume resources when running. You should design your Task Template to provide just enough compute and storage so that your task can effectively complete its job, reducing infrastructure cost
- **Model Applicability:** Task Templates can specify which model is most appropriate, meaning you can fine tune your Task based on its job, be that a code-focused model for fixing bugs or a generalized LLM to write summaries and updates on Pull Requests
- **Automation:** Coder Tasks provide a comprehensive set of built-in APIs, status monitoring, and notification systems. This allows for you and your team to build seamless integrations with external automation workflows

Together, these principles make up the core idea of designing task templates. Tasks are programmable, secure, and cost-efficient agents that integrate seamlessly into your team's workflow. By treating task templates as living and adaptable designs, you can evolve them with your team and needs without sacrificing clarity or control. The result is a system where automation, resource management, and security are baked into the foundation letting developers focus less on orchestration details and more on solving the problems that matter.

These design principles aren’t just technical guidelines; they're the lens through which to understand what Tasks are and how to use them effectively. By grounding Tasks in specificity, security, frugality, applicability, and automation, you ensure they remain reliable building blocks for both individual workflows and larger team processes.

### Practical Considerations

Tasks don't expose template parameters at runtime. If users need to choose different compute, region, or tooling options for example, you can define workspace presets in the template and have users select a preset when starting the Task. See workspace presets for details: ../admin/templates/extending-templates/parameters#workspace-presets.

### Identity, Security, and Access

By default, agents running with Coder Tasks always act as the authenticated developer. External auth tokens tie actions directly back to a specific user, so Git operations like cloning, pushing, or creating a PR are executed under the developer's personal OAuth tokens. Workspace SSH keys are generated per user, and external service integrations authenticate with the developer's personal credentials. This preserves audit trails and ensures actions stay traceable. Authentication (who the user is) subsequently stays separate from authorization (what the user can do), with identity providers acting as the source of truth. For human users, OIDC or SSO ensure sessions are consistent, centralized, and easy to govern.

For automated or background use cases, Tasks can also run under service identities. These behave like CI jobs: locked down, narrowly scoped, and managed by the organization. Service accounts or bot identities cover headless API-driven systems, while GitHub Apps enable fine-grained repository access under your organization's control. If long-lived API tokens are needed, they should be tied to service accounts with strict roles and rotation policies. In practice, the default should always be user-context execution for developer workflows while service accounts are reserved for production automation, CI/CD pipelines, and cross-team integrations. This balance keeps developer productivity high while aligning with organizational security requirements.

## How Tasks Fit Into Coder

Coder's platform is built around three core concepts that work together:

**Coder Templates** define the infrastructure and tool configurations that can be reused across your organization. They're the "blueprint" that ensures consistency and captures your team's working preferences.

**Coder Workspaces** are the individual development environments that are spun up from templates. They provide developers with consistent, reproducible environments to perform their job.

**Tasks** extend this model to AI agents and automated workflows. The same template-driven approach is now optimized to allow for autonomous execution that can be independent from human interaction.

### Platform Integration

Tasks aren't a separate system bolted onto Coder, but a natural extension of your existing infrastructure.

- **Security:** Tasks inherit the same access controls, secrets management, and network policies as developer workspaces
- **Resource Management:** Tasks have access to the same compute pools, storage, and scaling policies you've already configured
- **Observability:** Tasks use the same underlying infrastructure for monitoring, and appear in their own custom task-specific dashboards

### Developer Experience Continuity

Coder understands that every team is in a different place in its AI adoption plan. Some teams are still working with AI assistants to speed up development, while other teams are adopting background tasks to automate PR reviews and small bug fixes.

Naturally, your team might want to jump into a task, for example when the agent encounters an issue or needs human input. With Coder Tasks, you're able to jump into the existing Coder Workspace environment backing the task execution so that you can push the work forward. There's no context switching between tools; it's the same workspace you're already used to and the agent's work becomes yours.

---

# Custom Agents

Source: https://coder.com/docs/ai-coder/custom-agents

# Custom Agents

> [!WARNING]
> Starting June 2, 2026, Coder Tasks will move to a 12-month Extended Support Release (ESR) for Premium customers.
>
> Tasks will be removed from new Coder releases beginning with v2.37 (September 1, 2026) and will only be available via the ESR during the support period.
>
> We recommend transitioning to [Coder Agents](./agents/index.md), the long-term replacement.

Custom agents beyond the ones listed in the [Coder registry](https://registry.coder.com/modules?search=tag%3Aagent) can be used with Coder Tasks.

## Prerequisites

- A Coder deployment with v2.21 or later
- A [Coder workspace / template](../admin/templates/creating-templates.md)
- A custom agent that supports Model Context Protocol (MCP)

## Getting Started

Coder uses the [MCP protocol](https://modelcontextprotocol.io/introduction) to report activity back to the Coder control plane. From there, activity is displayed in the Coder dashboard.

First, your template will need a [coder_app](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app) for the agent. This can be a web app or command run in the terminal and ideally gives the user a UI to interact with or view more details about the agent.

From there, the agent can run the MCP server with the `coder exp mcp server` command. You will need to set the `CODER_MCP_APP_STATUS_SLUG` environment variable to match the slug in the coder_app resource. `CODER_AGENT_TOKEN` must also be set, but will be present inside a Coder workspace.

## Example

Inside a Coder workspace, run the following commands:

```sh
coder login
export CODER_MCP_APP_STATUS_SLUG=my-agent

# Use your own agent's logic and syntax here:
any-custom-agent configure-mcp --name "coder" --command "coder exp mcp server"
```

This will start the MCP server and report activity back to the Coder control plane on behalf of the coder_app resource.

> [!NOTE]
> See [this version of the Goose module](https://github.com/coder/registry/blob/release/coder/goose/v1.3.0/registry/coder/modules/goose/main.tf) source code for a real-world example of configuring reporting via MCP. Note that in addition to setting up reporting, you'll need to make your template [compatible with Tasks](./tasks.md#option-2-create-or-duplicate-your-own-template), which is not shown in the example.

## Pause and resume

Custom agents can support task pause and resume by enabling state
persistence on the agentapi module. Set `enable_state_persistence = true`
so that AgentAPI saves and restores conversation history across pause and
resume cycles:

```hcl
module "agentapi" {
  source                   = "registry.coder.com/coder/agentapi/coder"
  version                  = ">= 2.2.0"
  agent_id                 = coder_agent.main.id
  enable_state_persistence = true
  # ...
}
```

Your template also needs persistent storage and a sufficient graceful
shutdown timeout. See [Task lifecycle](./tasks-lifecycle.md) for the full
requirements.

## Contributing

We welcome contributions for various agents via the [Coder registry](https://registry.coder.com/modules?tag=agent)! See our [contributing guide](https://github.com/coder/registry/blob/main/CONTRIBUTING.md) for more information.

---

# Task Lifecycle

Source: https://coder.com/docs/ai-coder/tasks-lifecycle

# Task lifecycle

> [!WARNING]
> Starting June 2, 2026, Coder Tasks will move to a 12-month Extended Support Release (ESR) for Premium customers.
>
> Tasks will be removed from new Coder releases beginning with v2.37 (September 1, 2026) and will only be available via the ESR during the support period.
>
> We recommend transitioning to [Coder Agents](./agents/index.md), the long-term replacement.

Tasks can pause when idle and resume when you interact with them again.
Pausing frees compute resources while preserving conversation context, so
the agent can pick up where it left off. This page covers how pause and
resume work, what gets preserved, and what your template needs.

> [!NOTE]
> Task pause and resume is in beta. Some details may change in future releases.

## How tasks pause

Tasks pause in two ways:

- **Auto-pause**: The workspace idle timeout expires. Tasks use the
  template's existing `default_ttl` and `activity_bump` settings, the same
  ones that control regular workspace auto-stop. When a task auto-pauses,
  the build reason is recorded as "idle timeout" and a notification is sent
  to the task owner.
- **Manual pause**: You can pause a task through the CLI with
  `coder task pause`, the API, or the pause button in the Tasks UI.

When a task pauses, the workspace stops. Compute resources are freed and
persistent storage remains intact. Stopping a task workspace manually (via
the workspace UI or `coder stop`) triggers the same pause behavior,
including log snapshot capture and state persistence. Similarly, starting
the workspace (`coder start`) resumes the task.

### Activity detection for tasks

AI agent activity extends the workspace deadline just like SSH or IDE
connections do. When an agent reports "working" status through Coder Tasks,
the workspace deadline is bumped by the template's `activity_bump` duration.
This prevents auto-pause while the agent is actively working.

See [Workspace scheduling](../user-guides/workspace-scheduling.md) for the
full list of activity types.

## What gets preserved

Three things survive a pause:

1. **Log snapshot**: Up to 30 of the last messages from the conversation
   are captured during shutdown and stored server-side. While paused,
   `coder task logs` and the Tasks UI show this snapshot so you can see
   what the agent was working on.

1. **AgentAPI state**: When state persistence is enabled, the full
   conversation history is saved to a file on persistent storage. After
   resume, the Tasks UI shows the complete chat history.

1. **AI agent session**: Agents that support session persistence (such as
   Claude Code via `~/.claude/`) retain their own context on persistent
   storage. On resume, the agent picks up where it left off with full
   memory of the previous conversation.

> [!NOTE]
> Log snapshots and AgentAPI state persistence are best-effort. If the
> shutdown script is interrupted or times out, the workspace still stops
> normally, but the snapshot may not be captured and chat history may be
> empty after resume.

If `enable_state_persistence` is true but the AI agent does not support
session resume, the UI shows previous messages but the agent starts fresh
with no memory of the conversation. This is expected behavior. See
[Agent compatibility](./agent-compatibility.md) for which agents support
full session resume.

## Resuming a task

You can resume a paused task in several ways:

- **CLI**: `coder task resume <task>`
- **UI**: Click the **Resume** button on the task page or in the tasks list

Resume starts the workspace, runs startup scripts, starts AgentAPI (which
loads its state file if state persistence is enabled), and starts the AI
agent (which resumes its session if supported).

> [!NOTE]
> Resume requires a full workspace build, which can take several minutes
> depending on your template.

## Requirements

### Persistent storage

Templates must have persistent storage (Docker volume, Kubernetes PVC, or
similar) that survives workspace stop and start cycles. Without it, the AI
agent's session files and the AgentAPI state file are lost on stop.

See
[Resource persistence](../admin/templates/extending-templates/resource-persistence.md)
for configuration patterns.

### Compatible module version

AI agent registry modules handle shutdown scripts and state persistence
through the agentapi base module. To enable pause and resume, use a module
version that includes this support.

For Claude Code, update the module version in your template:

```hcl
module "claude-code" {
  source   = "registry.coder.com/coder/claude-code/coder"
  version  = ">= 4.8.0" # Minimum version with pause/resume support
  agent_id = coder_agent.main.id
  # ...
}
```

Versions 4.8.0 and above set `enable_state_persistence = true`, which
configures the shutdown script and state file automatically.

See [Agent compatibility](./agent-compatibility.md) for the minimum module
version per agent.

#### The `enable_state_persistence` variable

The `enable_state_persistence` variable controls whether AgentAPI saves and
restores conversation history across pause and resume cycles. It defaults to
`false` in the agentapi base module. Agent modules that support session
persistence, like `claude-code`, override this to `true` in their module
definition.

When `enable_state_persistence` is `false`, the shutdown script still runs to
capture log snapshots, but skips saving AgentAPI state. On resume, chat
history is not restored.

If you are building a [custom agent](./custom-agents.md#pause-and-resume),
set this variable on the agentapi module directly.

### Graceful shutdown timeout

> [!WARNING]
> Without this configuration, log snapshots and state persistence may
> silently fail. The container runtime can terminate the container before
> the shutdown script finishes.

The shutdown script runs inside the workspace container. The container
runtime controls how long the process has to shut down before it is
force-terminated. The defaults are often too short:

- **Docker**: 10 seconds
- **Kubernetes**: 30 seconds

The grace period covers not just this shutdown script but also the workspace
agent's own graceful shutdown and any other modules that run shutdown
scripts. Set at least **1 minute** as a baseline. **5 minutes** is
recommended to account for slow disks, multiple shutdown scripts, and other
modules performing cleanup.

**Docker**: Add to your `docker_container` resource:

```hcl
resource "docker_container" "workspace" {
  # Both attributes are needed for graceful shutdown.
  destroy_grace_seconds = 300 # 5 minutes
  stop_timeout          = 300
  stop_signal           = "SIGINT"
  # ...
}
```

**Kubernetes**: Add to your `kubernetes_pod` resource:

```hcl
resource "kubernetes_pod" "main" {
  timeouts {
    delete = "6m" # Must exceed the grace period below.
  }
  spec {
    termination_grace_period_seconds = 300 # 5 minutes
  }
}
```

If the container is terminated before the shutdown script finishes, the workspace
still stops normally but log snapshots may be missing and chat history may
not be restored after resume.

## Next steps

- [Agent compatibility](./agent-compatibility.md) for session persistence
  support and minimum module versions.
- [Resource persistence](../admin/templates/extending-templates/resource-persistence.md)
  for configuring persistent storage in templates.
- [Workspace scheduling](../user-guides/workspace-scheduling.md) for how
  auto-stop and activity detection work.

---

# Agent Compatibility

Source: https://coder.com/docs/ai-coder/agent-compatibility

# Agent compatibility

> [!WARNING]
> Starting June 2, 2026, Coder Tasks will move to a 12-month Extended Support Release (ESR) for Premium customers.
>
> Tasks will be removed from new Coder releases beginning with v2.37 (September 1, 2026) and will only be available via the ESR during the support period.
>
> We recommend transitioning to [Coder Agents](./agents/index.md), the long-term replacement.

Coder Tasks works with a range of AI coding agents, each with different levels
of support for preserving conversation context across pause and resume cycles.
This page covers which agents support resume, what session data they store,
and what to watch out for when configuring persistent storage.

## Compatibility levels

Agents with **full support** automatically resume the previous session when a
task resumes. The conversation history, tool calls, and context are all
preserved, so the agent picks up exactly where it left off.

Agents with **partial support** have resume wiring in the module but it is
either off by default or has known bugs. A module update is needed before resume
works reliably. See the linked tracking issue for details.

Agents with **planned support** have native session persistence but the registry
module does not wire it yet. These agents start a fresh conversation on each
resume until the module is updated.

Agents marked **not supported** cannot resume a previous session. They start a
fresh conversation on each resume, even if some chat history is visible in the
UI.

## Compatibility matrix

| Agent           | Module                                                                           | Min version | Support       | Tracking                                                     | Session data paths                                   | Min storage               |
|-----------------|----------------------------------------------------------------------------------|-------------|---------------|--------------------------------------------------------------|------------------------------------------------------|---------------------------|
| Claude Code     | [claude-code](https://registry.coder.com/modules/coder/claude-code)              | >= 4.8.0    | Full          | -                                                            | `~/.claude/`                                         | 100 MB (can grow to GB)   |
| Codex           | [codex](https://registry.coder.com/modules/coder-labs/codex)                     | >= 4.2.0    | Full          | -                                                            | `~/.codex/`, `~/.codex-module/`                      | 100 MB                    |
| Copilot         | [copilot](https://registry.coder.com/modules/coder-labs/copilot)                 | -           | Partial       | [registry#741](https://github.com/coder/registry/issues/741) | `~/.copilot/`                                        | 50 MB                     |
| OpenCode        | [opencode](https://registry.coder.com/modules/coder-labs/opencode)               | -           | Partial       | [registry#742](https://github.com/coder/registry/issues/742) | `~/.local/share/opencode/`, `~/.config/opencode/`    | 50 MB                     |
| Auggie          | [auggie](https://registry.coder.com/modules/coder-labs/auggie)                   | -           | Planned       | [registry#743](https://github.com/coder/registry/issues/743) | `~/.augment/`                                        | 50 MB                     |
| Goose           | [goose](https://registry.coder.com/modules/coder/goose)                          | -           | Planned       | [registry#744](https://github.com/coder/registry/issues/744) | `~/.local/share/goose/sessions/`, `~/.config/goose/` | 50 MB                     |
| Amazon Q        | [amazon-q](https://registry.coder.com/modules/coder/amazon-q)                    | -           | Planned       | [registry#746](https://github.com/coder/registry/issues/746) | `~/.local/share/amazon-q/`, `~/.aws/amazonq/`        | 50 MB                     |
| Gemini          | [gemini](https://registry.coder.com/modules/coder-labs/gemini)                   | -           | Planned       | [registry#745](https://github.com/coder/registry/issues/745) | `~/.gemini/`                                         | 200 MB (can reach 400 MB) |
| Cursor CLI      | [cursor-cli](https://registry.coder.com/modules/coder-labs/cursor-cli)           | -           | Planned       | [registry#747](https://github.com/coder/registry/issues/747) | `~/.cursor/`                                         | 50 MB                     |
| Sourcegraph Amp | [sourcegraph-amp](https://registry.coder.com/modules/coder-labs/sourcegraph-amp) | -           | Planned       | [registry#748](https://github.com/coder/registry/issues/748) | `~/.config/amp/` (config only)                       | 10 MB                     |
| Aider           | [aider](https://registry.coder.com/modules/coder/aider)                          | -           | Not supported | [registry#739](https://github.com/coder/registry/issues/739) | `.aider.chat.history.md` (workdir)                   | 50 MB                     |

## Persistent storage

Every agent's session data lives under the home directory, so persisting the
home directory with a volume mount is the simplest way to cover all agents at
once. This also preserves the AgentAPI state file that Coder uses to stream chat
content between the agent and the Tasks UI.

See
[Resource persistence](../admin/templates/extending-templates/resource-persistence.md)
for configuration patterns.

## Agent-specific notes

**Claude Code**: Session files are JSONL and grow unbounded. Long-running
tasks can accumulate multiple gigabytes of data in `~/.claude/projects/`.
Monitor disk usage and consider periodic cleanup.

**Goose**: Sessions are stored in a SQLite database with WAL mode enabled. You
must preserve the `-wal` and `-shm` sidecar files alongside the main database,
or the session database may become corrupted.

**Amazon Q**: The Amazon Q Developer CLI has been rebranded to Kiro CLI. The
existing module pins a specific CLI version. An authentication tarball is stored
alongside session data; if it is lost, the agent must re-authenticate.

**Gemini**: Session data can reach 400 MB for long-running tasks. You can set
the `general.sessionRetention` configuration value to control how long sessions
are retained.

**Sourcegraph Amp**: Conversation threads are stored server-side on
Sourcegraph servers, so only local configuration in `~/.config/amp/` needs
persistence. The workspace must have network connectivity to Sourcegraph for
resume to work.

**Auggie**: May require connectivity to the Augment cloud backend for session
resume. Behavior in fully headless or network-restricted environments is not
fully verified.

**Aider**: The `--restore-chat-history` flag performs a lossy reconstruction
from a Markdown log file, but the agent loses full conversation context on each
restart and does not support MCP for status reporting. When
`enable_state_persistence` is enabled in the module, the Coder UI preserves chat
history across pause and resume, but Aider itself starts each session fresh with no
memory of previous conversations.

## Next steps

- [Task lifecycle](./tasks-lifecycle.md) for how pause and resume work and
  what your template needs.
- [Set up Coder Tasks](./tasks.md) in your template.
- [Build a custom agent](./custom-agents.md) with MCP support.

---

# Tasks Migration Guide

Source: https://coder.com/docs/ai-coder/tasks-migration

# Migrating Task Templates for Coder version 2.28.0

> [!WARNING]
> Starting June 2, 2026, Coder Tasks will move to a 12-month Extended Support Release (ESR) for Premium customers.
>
> Tasks will be removed from new Coder releases beginning with v2.37 (September 1, 2026) and will only be available via the ESR during the support period.
>
> We recommend transitioning to [Coder Agents](./agents/index.md), the long-term replacement.

Prior to Coder version 2.28.0, the definition of a Coder task was different to the above. It required the following to be defined in the template:

1. A Coder parameter specifically named `"AI Prompt"`,
2. A `coder_workspace_app` that runs the `coder/agentapi` binary,
3. A `coder_ai_task` resource in the template that sets `sidebar_app.id`. This was generally defined in Coder modules specific to AI Tasks.

Note that 2 and 3 were generally handled by the `coder/agentapi` Terraform module.

> [!IMPORTANT]
> The pre-2.28.0 definition is no longer supported as of Coder 2.30.0. You must update your Tasks-enabled templates to use the new format described below.

You can view an [example migration here](https://github.com/coder/coder/pull/20420). Alternatively, follow the steps below:

## Upgrade Steps

1. Update the Coder Terraform provider to at least version 2.13.0:

```diff
terraform {
  required_providers {
    coder = {
      source = "coder/coder"
-      version = "x.y.z"
+      version = ">= 2.13"
    }
  }
}
```

1. Define a `coder_ai_task` resource and `coder_task` data source in your template:

```diff
+data "coder_task" "me" {}
+resource "coder_ai_task" "task" {}
```

1. Update the version of the respective AI agent module (e.g. `claude-code`) to at least 4.0.0 and provide the prompt from `data.coder_task.me.prompt` instead of the "AI Prompt" parameter.

```diff
module "claude-code" {
  source              = "registry.coder.com/coder/claude-code/coder"
-  version             = "4.0.0"
+  version             = "4.0.0"
    ...
-  ai_prompt           = data.coder_parameter.ai_prompt.value
+  ai_prompt           = data.coder_task.me.prompt
}
```

1. Add the `coder_ai_task` resource and set `app_id` to the `task_app_id` output of the Claude module.

> [!NOTE]
> Refer to the documentation for the specific module you are using for the exact name of the output.

```diff
resource "coder_ai_task" "task" {
+ app_id = module.claude-code.task_app_id
}
```

## Coder Tasks format pre-2.28

Below is a minimal illustrative example of a Coder Tasks template pre-2.28.0.
**Note that this is NOT a full template.**

```hcl
terraform {
  required_providers {
    coder = {
      source = "coder/coder
    }
  }
}

data "coder_workspace" "me" {}

resource "coder_agent" "main" { ... }

# The prompt is passed in via the specifically named "AI Prompt" parameter.
data "coder_parameter" "ai_prompt" {
  name    = "AI Prompt"
  mutable = true
}

# This coder_app is the interface to the Coder Task.
# This is assumed to be a running instance of coder/agentapi
resource "coder_app" "ai_agent" {
  ...
}

# Assuming that the below script runs `coder/agentapi` with the prompt
# defined in ARG_AI_PROMPT
resource "coder_script" "agentapi" {
  agent_id     = coder_agent.main.id
  run_on_start = true
  script       = <<EOT
    #!/usr/bin/env bash
    ARG_AI_PROMPT=${data.coder_parameter.ai_prompt.value} \
    /tmp/run_agentapi.sh
  EOT
  ...
}

# The coder_ai_task resource associates the task to the app.
resource "coder_ai_task" "task" {
  sidebar_app {
    id = coder_app.ai_agent.id
  }
}
```

## Tasks format from 2.28 onwards

In v2.28 and above, the following changes were made:

- The explicitly named "AI Prompt" parameter is no longer supported. The task prompt is now available in the `coder_ai_task` resource (provider version 2.12 and above) and `coder_task` data source (provider version 2.13 and above).
- Modules no longer define the `coder_ai_task` resource. These must be defined explicitly in the template.
- The `sidebar_app` field of the `coder_ai_task` resource is now deprecated. In its place, use `app_id`.

Example (**not** a full template):

```hcl
terraform {
  required_providers {
    coder = {
      source = "coder/coder
      version = ">= 2.13.0
    }
  }
}

data "coder_workspace" "me" {}

# The prompt is now available in the coder_task data source.
data "coder_task" "me" {}

resource "coder_agent" "main" { ... }

# This coder_app is the interface to the Coder Task.
# This is assumed to be a running instance of coder/agentapi (for instance, started via `coder_script`).
resource "coder_app" "ai_agent" {
  ...
}

# Assuming that the below script runs `coder/agentapi` with the prompt
# defined in ARG_AI_PROMPT
resource "coder_script" "agentapi" {
  agent_id     = coder_agent.main.id
  run_on_start = true
  script       = <<EOT
    #!/usr/bin/env bash
    ARG_AI_PROMPT=${data.coder_task.me.prompt} \
    /tmp/run_agentapi.sh
  EOT
  ...
}

# The coder_ai_task resource associates the task to the app.
resource "coder_ai_task" "task" {
  app_id = coder_app.ai_agent.id
}
```

---

# Security & Agent Firewall

Source: https://coder.com/docs/ai-coder/security

As the AI landscape is evolving, we are working to ensure Coder remains a secure
platform for running AI agents just as it is for other cloud development
environments.

## Use Trusted Models

Most agents can be configured to either use a local LLM (e.g. llama3), an agent
proxy (e.g. OpenRouter), or a Cloud-Provided LLM (e.g. AWS Bedrock). Research
which models you are comfortable with and configure your Coder templates to use
those.

## Set up Firewalls and Proxies

Many enterprises run Coder workspaces behind a firewall or a proxy to prevent
threats or bad actors. These same protections can be used to ensure AI agents do
not access or upload sensitive information.

## Separate API keys and scopes for agents

Many agents require API keys to access external services. It is recommended to
create a separate API key for your agent with the minimum permissions required.
This will likely involve editing your template for Agents to set different
scopes or tokens from the standard one.

Additional guidance and tooling is coming in future releases of Coder.

## Set Up Agent Firewall

Agent Firewall is a process-level firewall that lets you restrict and
audit what AI agents can access within Coder workspaces. To learn more about
this feature, see [Agent Firewall](./agent-firewall/index.md).

---

# Create a GitHub to Coder Tasks Workflow

Source: https://coder.com/docs/ai-coder/github-to-tasks

# Guide: Create a GitHub to Coder Tasks Workflow

> [!WARNING]
> Starting June 2, 2026, Coder Tasks will move to a 12-month Extended Support Release (ESR) for Premium customers.
>
> Tasks will be removed from new Coder releases beginning with v2.37 (September 1, 2026) and will only be available via the ESR during the support period.
>
> We recommend transitioning to [Coder Agents](./agents/index.md), the long-term replacement.

## Background

Most software engineering organizations track and manage their codebase through GitHub, and use project management tools like Asana, Jira, or even GitHub's Projects to coordinate work. Across these systems, engineers are frequently performing the same repetitive workflows: triaging and addressing bugs, updating documentation, or implementing well-defined changes for example.

Coder Tasks provides a method for automating these repeatable workflows. With a Task, you can direct an agent like Claude Code to update your documentation or even diagnose and address a bug. By connecting GitHub to Coder Tasks, you can build out a GitHub workflow that will for example:

1. Trigger an automation to take a pre-existing issue
1. Automatically spin up a Coder Task with the context from that issue and direct an agent to work on it
1. Focus on other higher-priority needs, while the agent addresses the issue
1. Get notified that the issue has been addressed, and you can review the proposed solution

This guide walks you through how to configure GitHub and Coder together so that you can tag Coder in a GitHub issue comment, and securely delegate work to coding agents in a Coder Task.

## Implementing the GHA

The below steps outline how to use the Coder [Create Task Action GHA](https://github.com/coder/create-task-action) in a GitHub workflow to solve a bug. The guide makes the following assumptions:

- You have access to a Coder Server that is running. If you don't have a Coder Server running, follow our [Quickstart Guide](https://coder.com/docs/tutorials/quickstart)
- Your Coder Server is accessible from GitHub
- You have an AI-enabled Task Template that can successfully create a Coder Task. If you don't have a Task Template available, follow our [Getting Started with Tasks Guide](https://coder.com/docs/ai-coder/tasks#getting-started-with-tasks)
- Check the [Requirements section of the GHA](https://github.com/coder/create-task-action?tab=readme-ov-file#requirements) for specific version requirements for your Coder deployment and the following
  - GitHub OAuth is configured in your Coder Deployment
  - Users have linked their GitHub account to Coder via `/settings/external-auth`

This guide can be followed for other use cases beyond bugs like updating documentation or implementing a small feature, but may require minor changes to file names and the prompts provided to the Coder Task.

### Step 1: Create a GitHub Workflow file

In your repository, create a new file in the `./.github/workflows/` directory named `triage-bug.yaml`. Within that file, add the following code:

```yaml
name: Start Coder Task

on:
  issues:
    types:
      - labeled

permissions:
  issues: write

jobs:
  coder-create-task:
    runs-on: ubuntu-latest
    if: github.event.label.name == 'coder'
    steps:
      - name: Coder Create Task
        uses: coder/create-task-action@v0
        with:
          coder-url: ${{ secrets.CODER_URL }}
          coder-token: ${{ secrets.CODER_TOKEN }}
          coder-organization: "default"
          coder-template-name: "my-template"
          coder-task-name-prefix: "gh-task"
          coder-task-prompt: "Use the gh CLI to read ${{ github.event.issue.html_url }}, write an appropriate plan for solving the issue to PLAN.md, and then wait for feedback."
          github-user-id: ${{ github.event.sender.id }}
          github-issue-url: ${{ github.event.issue.html_url }}
          github-token: ${{ github.token }}
          comment-on-issue: true
```

This code will perform the following actions:

- Create a Coder Task when you apply the `coder` label to an existing GitHub issue
- Pass as a prompt to the Coder Task:

    1. Use the GitHub CLI to access and read the content of the linked GitHub issue
    1. Generate an initial implementation plan to solve the bug
    1. Write that plan to a `PLAN.md` file
    1. Wait for additional input

- Post an update on the GitHub ticket with a link to the task

The prompt text can be modified to not wait for additional human input, but continue with implementing the proposed solution and creating a PR for example. Note that this example prompt uses the GitHub CLI `gh`, which must be installed in your Coder template. The CLI will automatically authenticate using the user's linked GitHub account via Coder's external auth.

### Step 2: Setup the Required Secrets & Inputs

The GHA has multiple required inputs that require configuring before the workflow can successfully operate.

You must set the following inputs as secrets within your repository:

- `coder-url`: the URL of your Coder deployment, e.g. https://coder.example.com
- `coder-token`: follow our [API Tokens documentation](https://coder.com/docs/admin/users/sessions-tokens#long-lived-tokens-api-tokens) to generate a token. Note that the token must be an admin/org-level with the "Read users in organization" and "Create tasks for any user" permissions

You must also set `coder-template-name` as part of this. The GHA example has this listed as a secret, but the value doesn't need to be stored as a secret. The template name can be determined the following ways:

- By viewing the URL of the template in the UI, e.g. `https://<your-coder-url>/templates/<org-name>/<template-name>`
- Using the Coder CLI:

```bash
# List all templates in your organization
coder templates list

# List templates in a specific organization
coder templates list --org your-org-name
```

You can also choose to modify the other [input parameters](https://github.com/coder/create-task-action?tab=readme-ov-file#inputs) to better fit your desired workflow.

#### Template Requirements for GitHub CLI

If your prompt uses the GitHub CLI `gh`, your template must pass the user's GitHub token to the agent. Add this to your template's Terraform:

```terraform
data "coder_external_auth" "github" {
  id = "github" # Must match your CODER_EXTERNAL_AUTH_0_ID
}

resource "coder_agent" "dev" {
  # ... other config ...
  env = {
    GITHUB_TOKEN = data.coder_external_auth.github.access_token
  }
}
```

Note that tokens passed as environment variables represent a snapshot at task creation time and are not automatically refreshed during task execution.

- If your GitHub external auth is configured as a GitHub App with token expiration enabled (the default), tokens expire after 8 hours
- If configured as a GitHub OAuth App or GitHub App with expiration disabled, tokens remain valid unless unused for 1 year

Because of this, we recommend to:

- Keep tasks under 8 hours to avoid token expiration issues
- For longer workflows, break work into multiple sequential tasks
- If authentication fails mid-task, users must re-authenticate at /settings/external-auth and restart the task

For more information, see our [External Authentication documentation](https://coder.com/docs/admin/external-auth#configure-a-github-oauth-app).

### Step 3: Test Your Setup

Create a new GitHub issue for a bug in your codebase. We recommend a basic bug, for this test, like “The sidebar color needs to be red” or “The text ‘Coder Tasks are Awesome’ needs to appear in the top left corner of the screen”. You should adapt the phrasing to be specific to your codebase.

Add the `coder` label to that GitHub issue. You should see the following things occur:

- A comment is made on the issue saying `Task created: https://<your-coder-url>/tasks/username/task-id`
- A Coder Task will spin up, and you'll receive a Tasks notification to that effect
- You can click the link to follow the Task's progress in creating a plan to solve your bug

Depending on the complexity of the task and the size of your repository, the Coder Task may take minutes or hours to complete. Our recommendation is to rely on Task Notifications to know when the Task completes, and further action is required.

And that’s it! You may now enjoy all the hours you have saved because of this easy integration.

### Step 4: Adapt this Workflow to your Processes

Following the above steps sets up a GitHub Workflow that will

1. Allow you to label bugs with `coder`
1. A coding agent will determine a plan to address the bug
1. You'll receive a notification to review the plan and prompt the agent to proceed, or change course

We recommend that you further adapt this workflow to better match your process. For example, you could:

- Modify the prompt to implement the plan it came up with, and then create a PR once it has a solution
- Update your GitHub issue template to automatically apply the `coder` label to attempt to solve bugs that have been logged
- Modify the underlying use case to handle updating documentation, implementing a small feature, reviewing bug reports for completeness, or even writing unit tests
- Modify the workflow trigger for other scenarios such as:

```yml
# Comment-based trigger slash commands
on:
  issue_comment:
    types: [created]

jobs:
  trigger-on-comment:
    runs-on: ubuntu-latest
    if: startsWith(github.event.comment.body, '/coder')

# On Pull Request Creation
jobs:
  on-pr-opened:
    runs-on: ubuntu-latest
    # No if needed - just runs on PR open

# On changes to a specific directory
on:
  pull_request:
    paths:
      - 'docs/**'
      - 'src/api/**'
      - '*.md'

jobs:
  on-docs-changed:
    runs-on: ubuntu-latest
    # Runs automatically when files in these paths change
```

## Summary

This guide shows you how to automatically delegate routine engineering work to AI coding agents by connecting GitHub issues to Coder Tasks. When you label an issue (like a bug report or documentation update), a coding agent spins up in a secure Coder workspace, reads the issue context, and works on solving it while you focus on higher-priority tasks. The agent reports back with a proposed solution for you to review and approve, turning hours of repetitive work into minutes of oversight. This same pattern can be adapted to handle documentation updates, test writing, code reviews, and other automatable workflows across your development process.

## Troubleshooting

### "No Coder user found with GitHub user ID X"

**Cause:** The user who triggered the workflow hasn't linked their GitHub account to Coder.

**Solution:**

1. Ensure GitHub OAuth is configured in your Coder deployment (see [External Authentication docs](https://coder.com/docs/admin/external-auth#configure-a-github-oauth-app))
1. Have the user visit `https://<your-coder-url>/settings/external-auth` and link their GitHub account
1. Retry the workflow by re-applying the `coder` label or however else the workflow is triggered

### "Failed to create task: 403 Forbidden"

**Cause:** The `coder-token` doesn't have the required permissions.

**Solution:** The token must have:

- Read users in organization
- Create tasks for any user

Generate a new token with these permissions at `https://<your-coder-url>/deployment/general`. See the [Coder Create Task GHA requirements](https://github.com/coder/create-task-action?tab=readme-ov-file#requirements) for more specific information.

### "Template 'my-template' not found"

**Cause:** The `coder-template-name` is incorrect or the template doesn't exist in the specified organization.

**Solution:**

1. Verify the template name using: `coder templates list --org your-org-name`
1. Update the `coder-template-name` input in your workflow file to match exactly, or input secret or variable saved in GitHub
1. Ensure the template exists in the organization specified by `coder-organization`

### Task fails with "authentication failed" or "Bad credentials" after running for hours

**Symptoms:**

- Task starts successfully and works initially
- After some time passes, `gh` CLI commands fail with:

  - `authentication failed`
  - `Bad credentials`
  - `HTTP 401 Unauthorized`
  - `error getting credentials` from git operations

**Cause:** The GitHub token expired during task execution. Tokens passed as environment variables are captured at task creation time and expire after 8 hours (for GitHub Apps with expiration enabled). These tokens are not automatically refreshed during task execution.

**Diagnosis:**

From within the running task workspace, check if the token is still valid:

```bash
# Check if the token still works
curl -H "Authorization: token ${GITHUB_TOKEN}" \
  https://api.github.com/user
```

If this returns 401 Unauthorized or Bad credentials, the token has expired.

**Solution:**

1. Have the user re-authenticate at https://<your-coder-url>/settings/external-auth
1. Verify the GitHub provider shows "Authenticated" with a green checkmark
1. Re-trigger the workflow to create a new task with a fresh token

---

# Tasks to Chats API Migration

Source: https://coder.com/docs/ai-coder/agents/tasks-to-chats-migration

# Migrating from the Tasks API to the Chats API

The [Tasks API](../../reference/api/tasks.md) (`/api/v2/tasks`) and the
[Chats API](../../reference/api/chats.md) (`/api/experimental/chats`) serve similar
goals (programmatic access to AI-powered coding agents) but they differ
significantly in architecture, capabilities, and usage patterns.

This guide walks you through updating your integrations from the Tasks API
to the Chats API.

> [!NOTE]
> The Chats API is experimental in current Coder releases. Endpoints live under `/api/experimental/chats` and may change without notice until the feature graduates to GA.

## When to migrate

Coder Tasks is being deprecated. Support continues on the ESR release and
through Coder v2.36. See the deprecation notice on the [Coder Tasks](../tasks.md) page for the full timeline.

If you currently run workflows on the Tasks API, you should plan to
migrate to the Chats API and [Coder Agents](./index.md). Coder Agents
runs the agent loop in the Coder control plane rather than inside the
workspace, and is the supported path going forward.

The two systems are not interchangeable. Tasks and Chats are separate
resources with separate APIs, so plan to update your integrations rather
than expecting a drop-in replacement.

## Key architectural differences

Before mapping individual endpoints, understand the structural changes:

| Aspect                 | Tasks API                                                                        | Chats API                                                  |
|------------------------|----------------------------------------------------------------------------------|------------------------------------------------------------|
| Agent execution        | Agent runs **inside the workspace** (via AgentAPI)                               | Agent loop runs **in the control plane**                   |
| LLM credentials        | Injected into workspace environment                                              | Stored in control plane only; never enters the workspace   |
| Workspace provisioning | You specify a `template_version_id` at creation                                  | The agent auto-selects a template and provisions on demand |
| Template requirements  | Requires `coder_ai_task` resource, `coder_task` data source, and an agent module | Any template with a clear description works                |
| Chat state             | Stored in the workspace (AgentAPI state file)                                    | Persisted in the Coder database                            |
| Conversation model     | Single prompt with optional follow-up input                                      | Multi-turn chat with message history, queuing, and editing |
| Real-time updates      | HTTP polling (`GET .../logs`)                                                    | WebSocket streaming (`GET .../stream`)                     |
| Sub-agents             | Not supported                                                                    | Built-in sub-agent delegation                              |

## Endpoint mapping

The table below maps each Tasks API endpoint to its Chats API equivalent.

| Operation         | Tasks API                                 | Chats API                                                           |
|-------------------|-------------------------------------------|---------------------------------------------------------------------|
| List              | `GET /api/v2/tasks`                       | `GET /api/experimental/chats`                                       |
| Create            | `POST /api/v2/tasks/{user}`               | `POST /api/experimental/chats`                                      |
| Get by ID         | `GET /api/v2/tasks/{user}/{task}`         | `GET /api/experimental/chats/{chat}`                                |
| Delete            | `DELETE /api/v2/tasks/{user}/{task}`      | `PATCH /api/experimental/chats/{chat}` with `{"archived": true}`    |
| Send follow-up    | `POST /api/v2/tasks/{user}/{task}/send`   | `POST /api/experimental/chats/{chat}/messages`                      |
| Update input      | `PATCH /api/v2/tasks/{user}/{task}/input` | `PATCH /api/experimental/chats/{chat}/messages/{message}`           |
| Get logs / stream | `GET /api/v2/tasks/{user}/{task}/logs`    | `GET /api/experimental/chats/{chat}/stream` (WebSocket)             |
| Pause             | `POST /api/v2/tasks/{user}/{task}/pause`  | `POST /api/experimental/chats/{chat}/interrupt`                     |
| Resume            | `POST /api/v2/tasks/{user}/{task}/resume` | `POST /api/experimental/chats/{chat}/messages` (send a new message) |
| Watch all         | n/a                                       | `GET /api/experimental/chats/watch` (WebSocket)                     |
| Get messages      | n/a                                       | `GET /api/experimental/chats/{chat}/messages`                       |
| List models       | n/a                                       | `GET /api/experimental/chats/models`                                |
| Upload file       | n/a                                       | `POST /api/experimental/chats/files`                                |

## Migration steps

### 1. Configure an LLM provider

With Tasks, LLM credentials are injected into the workspace as environment
variables (e.g. `ANTHROPIC_API_KEY`). With Coder Agents, credentials are
configured once in the control plane:

1. Navigate to the **Agents** page in the Coder dashboard.
1. Open **Settings** > **Manage Agents** > **Providers**, pick a provider,
   enter your API key, and save.
1. Under **Models**, add at least one model and set it as the default.

You no longer pass API keys in template variables or workspace environment. See https://coder.com/docs/ai-coder/agents/getting-started for more information.

### 2. Update task creation calls

**Tasks API**. You specify the user, template version, and a prompt
string:

```sh
# Tasks API: create a task
curl -X POST https://coder.example.com/api/v2/tasks/me \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "template_version_id": "<template-version-uuid>",
    "input": "Fix the failing tests in the auth service"
  }'
```

**Chats API**. You send structured content parts. No template or user
path segment is required:

```sh
# Chats API: create a chat
curl -X POST https://coder.example.com/api/experimental/chats \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "<your-org-id>",
    "content": [
      {"type": "text", "text": "Fix the failing tests in the auth service"}
    ]
  }'
```

Key differences:

- The `{user}` path parameter is removed. The authenticated user is
  inferred from the session token.
- `organization_id` is required in the request body. The caller must be a
  member of that organization.
- The prompt is now an array of `ChatInputPart` objects (supporting `text`,
  `file`, and `file-reference` types) instead of a plain string.
- `template_version_id` and `template_version_preset_id` are removed. The
  agent selects a template automatically based on the prompt and available
  template descriptions. To pin to a specific workspace, pass
  `workspace_id` instead.
- Optionally pass `model_config_id` to override the default model, or
  `mcp_server_ids` to attach MCP servers.

### 3. Update follow-up message calls

**Tasks API**. Follow-ups use the send endpoint with a plain string:

```sh
# Tasks API: send input
curl -X POST https://coder.example.com/api/v2/tasks/me/my-task/send \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"input": "Now also update the integration tests"}'
```

**Chats API**. Follow-ups use the messages endpoint with content parts:

```sh
# Chats API: send a message
curl -X POST \
  https://coder.example.com/api/experimental/chats/$CHAT_ID/messages \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [
      {"type": "text", "text": "Now also update the integration tests"}
    ]
  }'
```

The Chats API supports message queuing. If the agent is busy, the message
is queued automatically and delivered when the agent finishes its current
step. The response includes a `queued` field indicating whether the message
was delivered immediately or queued.

### 4. Switch from log polling to WebSocket streaming

**Tasks API**. You poll for logs:

```sh
# Tasks API: get logs
curl https://coder.example.com/api/v2/tasks/me/my-task/logs \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```

**Chats API**. You open a one-way WebSocket connection:

```text
GET wss://coder.example.com/api/experimental/chats/{chat}/stream
```

The WebSocket sends JSON envelopes with a `type` field (`"ping"`,
`"data"`, or `"error"`). Data envelopes contain batches of events:

| Event type     | Description                                             |
|----------------|---------------------------------------------------------|
| `message_part` | A chunk of the agent's response (text, tool call, etc.) |
| `message`      | A complete message has been persisted                   |
| `status`       | The chat status changed (e.g. `running` → `waiting`)    |
| `error`        | An error occurred during processing                     |
| `retry`        | The server is retrying a failed LLM call                |
| `queue_update` | The queued message list changed                         |

Use `after_id` as a query parameter when reconnecting to skip messages the
client already has.

### 5. Update status handling

Task and chat statuses use different values. The Chats API status set is
defined in `codersdk.ChatStatus`:

| Tasks API status | Chats API status  | Notes                                                                                                                                                                                                                         |
|------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `pending`        | `pending`         | Queued for processing.                                                                                                                                                                                                        |
| `running`        | `running`         | Agent is actively working.                                                                                                                                                                                                    |
| `complete`       | `waiting`         | Idle. Newly created, finished successfully, or interrupted. This is the default idle state.                                                                                                                                   |
| `paused`         | n/a               | The Tasks API pause stops the workspace; the Chats API equivalent is `interrupt` plus separate workspace lifecycle. The `paused` enum value exists in code but no production path on `main` transitions a chat into it today. |
| `failed`         | `error`           | Agent encountered an error.                                                                                                                                                                                                   |
| n/a              | `requires_action` | Agent invoked a client-provided tool and is waiting for the result before continuing.                                                                                                                                         |

The Chats API uses `waiting` as the default idle state (not `complete`).
A chat enters `waiting` when it is first created (before any message is
queued) and again whenever a run finishes or is interrupted, so treat
`waiting` as "the agent is not currently working" rather than only "the
agent just finished." The `completed` enum value is also defined but is
not currently set by any production code path on `main`.

### 6. Replace delete with archive

The Tasks API uses `DELETE` to remove a task. The Chats API uses archiving:

```diff
- curl -X DELETE https://coder.example.com/api/v2/tasks/me/my-task \
-   -H "Coder-Session-Token: $CODER_SESSION_TOKEN"

+ curl -X PATCH https://coder.example.com/api/experimental/chats/$CHAT_ID \
+   -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
+   -H "Content-Type: application/json" \
+   -d '{"archived": true}'
```

Archived chats can be restored by setting `archived` to `false`.

### 7. Replace pause/resume with interrupt and messaging

**Tasks API**. Pause and resume stop and start the workspace:

```sh
# Tasks API
curl -X POST \
  https://coder.example.com/api/v2/tasks/me/my-task/pause \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"

curl -X POST \
  https://coder.example.com/api/v2/tasks/me/my-task/resume \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```

**Chats API**. Interrupt stops the current agent loop. Sending a new
message resumes processing:

```sh
# Chats API: interrupt
curl -X POST \
  https://coder.example.com/api/experimental/chats/$CHAT_ID/interrupt \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"

# Chats API: resume by sending a new message
curl -X POST \
  https://coder.example.com/api/experimental/chats/$CHAT_ID/messages \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [
      {"type": "text", "text": "Continue where you left off"}
    ]
  }'
```

In the Tasks API, pausing stops the workspace and frees compute. In the
Chats API, interrupt stops the agent loop in the control plane; the
workspace may remain running. The workspace lifecycle is managed
independently.

### 8. Update GitHub Actions integrations

If you use the
[Create Task Action](https://github.com/coder/create-task-action) GitHub
Action, replace it with the dedicated
[`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action).
It handles the API call, the GitHub user lookup, and the optional issue
comment, so most existing workflows can swap one `uses:` line and rename
a few inputs.

We are actively shipping new features for `create-agent-chat-action`, so
pin to a major version (for example `@v0`) and watch the
[releases](https://github.com/coder/create-agent-chat-action/releases) for
updates.

```diff
# .github/workflows/triage-bug.yaml
jobs:
  coder-create-task:
    runs-on: ubuntu-latest
    if: github.event.label.name == 'coder'
    steps:
-     - name: Coder Create Task
-       uses: coder/create-task-action@v0
-       with:
-         coder-url: ${{ secrets.CODER_URL }}
-         coder-token: ${{ secrets.CODER_TOKEN }}
-         coder-organization: "default"
-         coder-template-name: "my-template"
-         coder-task-name-prefix: "gh-task"
-         coder-task-prompt: >-
-           Use the gh CLI to read
-           ${{ github.event.issue.html_url }},
-           fix the issue, and create a PR.
-         github-user-id: ${{ github.event.sender.id }}
-         github-issue-url: ${{ github.event.issue.html_url }}
-         github-token: ${{ github.token }}
-         comment-on-issue: true
+     - name: Coder Create Agent Chat
+       uses: coder/create-agent-chat-action@v0
+       with:
+         coder-url: ${{ secrets.CODER_URL }}
+         coder-token: ${{ secrets.CODER_TOKEN }}
+         chat-prompt: >-
+           Use the gh CLI to read
+           ${{ github.event.issue.html_url }},
+           fix the issue, and create a PR.
+         github-user-id: ${{ github.event.sender.id }}
+         github-issue-url: ${{ github.event.issue.html_url }}
+         github-token: ${{ github.token }}
+         comment-on-issue: true
```

Key differences from the Tasks GHA:

- No `coder-template-name` or `coder-task-name-prefix`. The agent
  auto-provisions a workspace; pass `workspace-id` if you want to pin to
  an existing workspace instead.
- The prompt input is renamed from `coder-task-prompt` to `chat-prompt`.
- LLM credentials are no longer passed through the template. They are
  configured in the Coder control plane.
- Identify the user with `github-user-id` (the action resolves it to a
  Coder user via the GitHub OAuth link) or with `coder-username`
  directly.

See the
[action README](https://github.com/coder/create-agent-chat-action#inputs)
for the full input and output reference, including the `existing-chat-id`
input for sending follow-up messages on a previous chat.

## Template recommendations

<!-- NEEDS REVIEW: This section contains initial recommendations based on
     the current Coder Agents architecture. Platform teams should validate
     these against their own deployment patterns before adopting them. -->

> [!NOTE]
> This section contains recommendations that may evolve as Coder Agents
> matures. Review these against your deployment requirements.

With Coder Tasks, every task-capable template requires specific Terraform
resources (`coder_ai_task`, `coder_task`, agent modules, and LLM API
keys). With Coder Agents, templates no longer need any of these. The
agent runs in the control plane and treats the workspace as plain compute.

However, **we still recommend creating dedicated templates for agent
workloads** rather than reusing your standard developer templates
unchanged. The reasons are different from Tasks, but the principle holds:

### Why dedicated agent templates still matter

- **Network boundaries.** Agent workspaces inherit whatever network access
  the template allows. Because the agent does not need outbound access to
  LLM providers (that happens in the control plane), you can lock down
  agent templates to only reach the Coder control plane and your git
  provider. Standard developer templates typically allow broader access.
- **No IDE tooling overhead.** The agent connects via the workspace
  daemon's HTTP API, not through VS Code or JetBrains. Removing IDE
  extensions, desktop environments, and similar tooling from agent
  templates reduces image size and startup time.
- **Scoped credentials.** Agent workloads may warrant more restrictive
  credentials than interactive developer sessions. A dedicated template
  lets you provide a separate, narrower-scoped git token or service
  account without affecting your developers' workflow.
- **Cost control.** Agent workspaces can often use smaller compute
  resources than developer workspaces since they don't need to run IDEs,
  language servers, or other interactive tooling. A dedicated template lets
  you right-size the infrastructure.

### What to include in agent templates

<!-- TODO: Expand this section with concrete Terraform examples once
     template patterns stabilize. -->

- **Clear descriptions.** The agent selects templates by reading names and
  descriptions. Include the target language, framework, repository, and
  type of work. For example: *"Python backend services for the payments
  repo. Includes Poetry, Python 3.12, and PostgreSQL."*
- **Pre-installed dependencies.** Language runtimes, build tools, `git`,
  and project-specific dependencies should be baked into the image. Time
  the agent spends installing tools is time not spent on the task.
- **Git configuration.** Ensure `git` is configured with credentials and
  author information so the agent can commit and push without additional
  setup.
- **Minimal parameters.** Use sensible defaults so the agent can provision
  workspaces without guessing. Avoid required parameters with opaque
  identifiers.

### What to remove from migrated task templates

If you are converting an existing task template for use with Coder Agents,
you can safely remove the Tasks-specific Terraform resources. They are
unused when the chat is driven by the Chats API:

```diff
  terraform {
    required_providers {
      coder = {
        source  = "coder/coder"
-       version = ">= 2.13"
+       version = ">= 2.13"
      }
    }
  }

- data "coder_task" "me" {}
-
- resource "coder_ai_task" "task" {
-   app_id = module.claude-code.task_app_id
- }
-
- module "claude-code" {
-   source         = "registry.coder.com/coder/claude-code/coder"
-   version        = "4.0.0"
-   agent_id       = coder_agent.main.id
-   ai_prompt      = data.coder_task.me.prompt
-   claude_api_key = var.anthropic_api_key
- }
-
- variable "anthropic_api_key" {
-   type        = string
-   description = "Anthropic API key"
-   sensitive   = true
- }

  resource "coder_agent" "main" {
    os   = "linux"
    arch = "amd64"
+   # No agent modules, no AgentAPI, no LLM keys needed.
+   # The Coder Agents control plane handles the agent loop.
  }
```

> [!TIP]
> You do not have to remove these resources immediately. Templates can
> serve both Tasks and Chats simultaneously during a transition period.
> The Tasks-specific resources are simply unused when work comes through
> the Chats API.

See
[Template Optimization](./platform-controls/template-optimization.md)
for the full guide on writing discoverable descriptions, configuring
network boundaries, scoping credentials, and pre-installing dependencies.

### Pre-creating a workspace for deterministic results

Letting the agent pick a template and provision a workspace works well
for exploratory chats. If your workflow requires deterministic results like:

- Automations
- Recurring processes
- Generally any case that needs a known reproducible environment

pre-create the workspace yourself and attach it when you create the chat.

The pattern is two API calls:

1. Create a workspace from a specific template via
   [`POST /api/v2/users/{user}/workspaces`](../../reference/api/workspaces.md#create-user-workspace).
   You control the template, the version, and any rich parameters.
2. Create the chat with `workspace_id` set to the workspace you just
   created. The agent runs against that workspace instead of selecting
   one heuristically.

```sh
# 1. Provision the workspace from the exact template you want.
WORKSPACE_ID=$(curl -s -X POST \
  https://coder.example.com/api/v2/users/me/workspaces \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "<your-agent-template-uuid>",
    "name": "agent-run-${GITHUB_RUN_ID}"
  }' | jq -r '.id')

# 2. Create the chat bound to that workspace.
curl -s -X POST https://coder.example.com/api/experimental/chats \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"organization_id\": \"<your-org-id>\",
    \"workspace_id\": \"$WORKSPACE_ID\",
    \"content\": [
      {\"type\": \"text\", \"text\": \"Fix the failing tests in the auth service\"}
    ]
  }"
```

This pattern is the closest analogue to the Tasks API behavior of
`template_version_id` plus `coder-template-name`: you decide which
template runs, the agent decides what to do inside it. The same approach
works from the
[`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action)
GHA, which exposes the same pin via its `workspace-id` input.

## How to test your migration

After completing the migration steps above, walk through these checks to
confirm the Chats API integration is working end-to-end.

### 1. Confirm LLM provider connectivity

List available models to verify at least one provider is configured and
reachable:

```sh
curl -s https://coder.example.com/api/experimental/chats/models \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '.[].display_name'
```

If this returns an empty list or an error, revisit
[Step 1: Configure an LLM provider](#1-configure-an-llm-provider).

### 2. Create a chat and confirm the response

Create a simple chat that does not require a workspace:

```sh
curl -s -X POST https://coder.example.com/api/experimental/chats \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [{"type": "text", "text": "What is 2 + 2?"}]
  }' | jq '{id, status, title}'
```

You should receive a `Chat` object with `status` set to `"waiting"` or
`"pending"`. Save the `id` for subsequent steps.

### 3. Stream the response

Open a WebSocket connection to verify the agent processes the prompt and
returns a response. Using [websocat](https://github.com/vi/websocat):

```sh
websocat -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  "wss://coder.example.com/api/experimental/chats/$CHAT_ID/stream"
```

You should see JSON envelopes with `"type": "data"` containing
`message_part` and `status` events. The chat should eventually reach
`"waiting"` status, indicating the agent completed its response.

### 4. Send a follow-up message

Verify multi-turn conversation works:

```sh
curl -s -X POST \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID/messages" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": [{"type": "text", "text": "Now multiply that by 10"}]
  }' | jq '{queued}'
```

The response should include `"queued": false` (delivered immediately) or
`"queued": true` (agent was busy. The message is queued and will be
processed next).

### 5. Test workspace provisioning

Create a workspace from your converted agent template through the
standard Coder UI, then attach it to a new chat from the chat composer:

1. In the Coder dashboard, create a workspace from the agent template
   you migrated.
2. Open **Agents** and start a new chat.
3. In the composer, use the workspace picker to attach the workspace you
   just created.
4. Send a prompt that exercises the workspace, for example: *"List the
   files in the root directory of this workspace."*

The response stream should show the agent invoking workspace tools (such
as `execute`) against the attached workspace. After the chat finishes,
verify the chat is bound to the workspace via the API:

```sh
curl -s "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '{workspace_id, status}'
```

A `workspace_id` matching the workspace you attached confirms the chat
is driving that workspace end-to-end. Auto-provisioning from the chat
flow is also supported but is easier to verify once the manual-attach
path is working.

### 6. Verify interrupt works

Start a long-running chat and interrupt it:

```sh
curl -s -X POST \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID/interrupt" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```

Then confirm the chat status returns to `"waiting"`:

```sh
curl -s "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '.status'
```

### 7. Validate archive and restore

```sh
# Archive
curl -s -X PATCH \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"archived": true}'

# Confirm it no longer appears in the default list
curl -s "https://coder.example.com/api/experimental/chats" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  | jq --arg id "$CHAT_ID" '[.[] | select(.id == $id)] | length'
# Should return 0

# Restore
curl -s -X PATCH \
  "https://coder.example.com/api/experimental/chats/$CHAT_ID" \
  -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"archived": false}'
```

### Quick checklist

Use this checklist to confirm each part of your integration:

- [ ] At least one LLM model is configured and returned by `/chats/models`
- [ ] `POST /chats` creates a chat and returns a valid `Chat` object
- [ ] WebSocket stream at `/chats/{chat}/stream` delivers events
- [ ] Follow-up messages via `/chats/{chat}/messages` are accepted
- [ ] Chat attached to a workspace from the converted template runs
      tools against that workspace
- [ ] `POST /chats/{chat}/interrupt` stops the agent and returns to `waiting`
- [ ] Archive and restore via `PATCH /chats/{chat}` works
- [ ] (If applicable) GitHub Actions workflow creates chats successfully

## Features available only in the Chats API

The Chats API includes capabilities that have no equivalent in the Tasks
API:

| Feature                              | Description                                                                    |
|--------------------------------------|--------------------------------------------------------------------------------|
| **WebSocket streaming**              | Real-time event stream via `GET /chats/{chat}/stream` instead of HTTP polling  |
| **Watch all chats**                  | `GET /chats/watch` pushes events for all chats owned by the user               |
| **Message editing**                  | `PATCH /chats/{chat}/messages/{message}` to edit a sent message and re-process |
| **Message queuing**                  | Follow-up messages are automatically queued when the agent is busy             |
| **File uploads**                     | Attach images via `POST /chats/files` and reference them in messages           |
| **Model selection**                  | `GET /chats/models` to discover models; override per-chat or per-message       |
| **MCP server attachment**            | Attach MCP servers to a chat for tool augmentation                             |
| **Labels**                           | Key-value metadata on chats for filtering (`label` query parameter)            |
| **Sub-agents**                       | Agent can spawn child agents for parallel work                                 |
| **Diff/PR tracking**                 | `GET /chats/{chat}/diff` returns change tracking and PR metadata               |
| **Title regeneration**               | `POST /chats/{chat}/title/regenerate`                                          |
| **Pinning**                          | Pin and reorder chats via the `pin_order` field                                |
| **Automatic workspace provisioning** | No workspace needed for Q&A. Provisioned only when the agent needs to act      |

## Response schema changes

The Tasks API returns a `Task` object with workspace-centric fields. The
Chats API returns a `Chat` object with conversation-centric fields:

| Tasks API field    | Chats API equivalent                          | Notes                                                            |
|--------------------|-----------------------------------------------|------------------------------------------------------------------|
| `id`               | `id`                                          | Both are UUIDs                                                   |
| `initial_prompt`   | First message in `GET /chats/{chat}/messages` | Prompt is a message, not a top-level field                       |
| `display_name`     | `title`                                       | Auto-generated or set via `PATCH`                                |
| `status`           | `status`                                      | Different enum values (see status table above)                   |
| `current_state`    | Latest `status` event from the stream         | No equivalent top-level field                                    |
| `workspace_id`     | `workspace_id`                                | Nullable in Chats. May be `null` if no workspace was provisioned |
| `workspace_status` | n/a                                           | Manage workspace lifecycle separately                            |
| `template_id`      | n/a                                           | Not exposed; the agent selects templates internally              |
| `owner_id`         | `owner_id`                                    | Same concept                                                     |
| `name`             | n/a                                           | Chats use `id` for identification, not human-readable names      |

## CLI changes

The Tasks CLI (`coder task`) and the Coder Agents CLI are separate. Coder
ships an experimental TUI for Coder Agents at `coder exp agents` (planned
to graduate to `coder agents` in the May Beta release per
[#24432](https://github.com/coder/coder/pull/24432)). The TUI talks to the
same `/api/experimental/chats` endpoints documented in this guide; for
automation, prefer direct API calls.

| Tasks CLI           | Chats equivalent                        |
|---------------------|-----------------------------------------|
| `coder task create` | `coder exp agents` TUI or `POST /chats` |
| `coder task list`   | `coder exp agents` TUI or `GET /chats`  |
| `coder task logs`   | `GET /chats/{chat}/stream` (WebSocket)  |
| `coder task pause`  | `POST /chats/{chat}/interrupt`          |
| `coder task resume` | Send a follow-up message to the chat    |

> [!NOTE]
> The Coder Agents CLI today is an interactive TUI rather than a set of
> per-action subcommands like `coder task`. Use `curl`, the SDK, or your
> HTTP client of choice for non-interactive automation. Dedicated
> non-interactive subcommands may be added in a future release.

---

# Tutorials

Source: https://coder.com/docs/tutorials

# Guides and Tutorials

Here you can find a list of employee-written guides on Coder. These tutorials
are hosted on our [GitHub](https://github.com/coder/coder/) where you can leave
feedback or request new topics to be covered.

<children>
  This page is rendered on <https://coder.com/docs/tutorials>. Refer to the other documents in the `docs/tutorials/` directory for specific employee-written guides.
</children>

---

# Quickstart

Source: https://coder.com/docs/tutorials/quickstart

# Quickstart

Follow this guide to get your first Coder development environment
running in under 10 minutes. This guide covers the essential concepts and shows
you how to create your first workspace and open it in your preferred editor.
This workspace includes a basic set of tools to edit most code bases.

## What you'll do

In this quickstart, you'll:

- ✅ Install Coder server.
- ✅ Create a **template** (blueprint for dev environments).
- ✅ Launch a **workspace** (your actual dev environment).
- ✅ Connect from your favorite IDE.

## A 30-second metaphor for Coder

Before diving in, the following table breaks down the core concepts that power Coder,
explained through a cooking analogy:

| Component      | What It Is                                                                           | Real-World Analogy             |
|----------------|--------------------------------------------------------------------------------------|--------------------------------|
| **You**        | The engineer/developer/builder working                                               | The head chef cooking the meal |
| **Templates**  | A Terraform blueprint that defines your dev environment (OS, tools, resources)       | Recipe for a meal              |
| **Workspaces** | The actual running environment created from the template                             | The cooked meal                |
| **Users**      | A developer who launches the workspace from a template and does their work inside it | The people eating the meal     |

**Putting it Together:** Coder separates who _defines_ environments from who _uses_ them. Admins create and manage Templates, the recipes, while developers use those Templates to launch Workspaces, the meals.

## Prerequisites

- A machine with 2+ CPU cores and 4GB+ RAM
- Familiarity with running commands in the terminal
- 10 minutes of your time

## Step 1: Install Docker and set up permissions

<div class="tabs">

### Linux

1. Install Docker:

   ```bash
   curl -sSL https://get.docker.com | sh
   ```

   For more details, visit [Docker's docs on installing Docker on Linux](https://docs.docker.com/desktop/install/linux-install/).

1. Assign your user to the Docker group:

   ```shell
   sudo usermod -aG docker $USER
   ```

1. Run `newgrp` to activate the groups changes:

   ```shell
   newgrp docker
   ```

   You might need to log out of and back into your machine or restart your
   machine for changes to take effect.

1. Launch the Docker daemon:

   ```shell
   sudo systemctl start docker
   ```

### macOS

1. [Install Docker](https://docs.docker.com/desktop/setup/install/mac-install/).
There is a Homebrew formula for the Docker command and a Homebrew cask of Docker
Desktop if you prefer:

   ```shell
   brew install --cask docker-desktop
   ```

1. Open Docker Desktop.

### Windows

If you plan to use the built-in PostgreSQL database, ensure that the
[Visual C++ Runtime](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist#latest-microsoft-visual-c-redistributable-version)
is installed.

1. [Install Docker](https://docs.docker.com/desktop/install/windows-install/).

1. Open Docker Desktop.

</div>

## Step 2: Install and start Coder

Install the `coder` CLI to get started:

<div class="tabs">

### Linux/macOS

1. Install Coder:

   ```shell
   curl -L https://coder.com/install.sh | sh
   ```

   - For standalone binaries, system packages, or other alternate installation
     methods, refer to the
     [latest release on GitHub](https://github.com/coder/coder/releases/latest).

1. Start Coder:

   ```shell
   coder server
   ```

### Windows

If you plan to use the built-in PostgreSQL database, ensure that the
[Visual C++ Runtime](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist#latest-microsoft-visual-c-redistributable-version)
is installed.

1. Use the
   [`winget`](https://learn.microsoft.com/en-us/windows/package-manager/winget/#use-winget)
   package manager to install Coder:

   ```powershell
   winget install Coder.Coder
   ```

1. Start Coder:

   ```shell
   coder server
   ```

</div>

Coder will attempt to open the setup page in your browser. If it doesn't open
automatically, go to <http://localhost:3000>.

- If you get a browser warning similar to `Secure Site Not Available`, you can
  ignore the warning and continue to the setup page.

If your Coder server is on a network or cloud device, or you are having trouble
viewing the page, locate the web UI URL in Coder logs in your terminal. It looks
like `https://<CUSTOM-STRING>.<TUNNEL>.try.coder.app`. It's one of the first
lines of output, so you might have to scroll up to find it.

## Step 3: Initial setup

1. Create your admin account:
   - Email: `your.email@example.com`
   - Password: Choose a strong password.

   You can also choose to **Continue with GitHub** instead of creating an admin
   account. Coder automatically grants admin permissions to the first user that signs in.

   ![Welcome to Coder - Create admin user](../images/screenshots/welcome-create-admin-user.png)

## Step 4: Create your first template and workspace

> [!TIP]
> If you use an AI coding assistant, the [coder-templates](https://github.com/coder/registry/blob/main/.agents/skills/coder-templates/SKILL.md) agent skill can guide you through creating and customizing templates with best practices built-in.

Templates define what's in your development environment. The following is a basic example:

1. Select **Templates** → **New Template**.

2. Select the **Coder Quickstart** template from the list of starter templates.

   **Note:** running this template requires Docker to be running in the background, so make sure Docker is running!

3. Name your template:
   - Name: `quickstart`
   - Display name: `quickstart doc template`
   - Description: `Provision Docker containers as Coder workspaces`

4. Select **Save**.

   ![Create template](../images/screenshots/create-template.png)

**What just happened?** You defined a template — a reusable blueprint for dev
environments — in your Coder deployment. It's now stored in your organization's
template list, where you and any teammates in the same org can create workspaces
from it. Now it's time launch a workspace.

## Step 5: Launch your workspace

1. After the template is ready, select **+ Create Workspace**.

2. Give the workspace a name. If you need a suggestion for a workspace, you can select the automatically generated name next to the **Need a suggestion?** label.

3. In this window are [parameters](../admin/templates/extending-templates/parameters.md) that customize the workspace's behavior. Set the following based on your needs:

   - **Programming Languages**: the languages to pre-install in your workspace. You can use more than one if you want.
   - **IDEs & Editors**: the IDEs and editors you want to configure for quick access once the workspace is running. You can choose more than one if you want.
   - **Git Repository (Optional)**: the Git repository you want to clone into your workspace. Leave this field blank to skip it.

   **Note:** If you use any of the JetBrains IDEs as your preferred IDE (such as PyCharm, GoLand, or RustRover), select **JetBrains IDEs** as the value. A new parameter will appear, with which you can choose your preferred JetBrains IDE.

4. Launch your workspace by selecting **Create workspace**.

After a short wait (10-15 seconds on most modern computers), Coder will start your new workspace:

![getting-started-workspace is running](../images/screenshots/workspace-running-with-topbar.png)_Workspace is running_

## Step 6: Connect your IDE

Each of the buttons in the workspace view is a different **agent app**
(more on this in a later section). Select your preferred IDE from the
list of agent apps. This guide assumes you'll use Visual Studio Code,
but the process is similar for other IDEs and editors.

After VS Code loads the remote environment, you can select **Open Folder** to
explore directories in the Docker container or work on something new.

![Changing directories in VS Code](../images/screenshots/change-directory-vscode.png)

If you didn't clone an existing Git repository when you created your
workspace, you can clone it manually if you want:

1. Select **Clone Repository** and enter the repository URL.

   For example, to clone the Coder repo, enter
   `https://github.com/coder/coder.git`.

   Learn more about how to find the repository URL in the
   [GitHub documentation](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository).

2. Choose the folder to which VS Code should clone the repo. It will be in its
   own directory within this folder.

   Note that you cannot create a new parent directory in this step.

3. After VS Code completes the clone, select **Open** to open the directory.

4. You are now using VS Code in your Coder environment!

## Success! You're coding in Coder

You now have:

- A Coder server running locally.
- A template defining your environment.
- A workspace running that environment.
- IDE access to code remotely.

### What's next?

Now that you have your own workspace running, you can start exploring more
advanced capabilities that Coder offers.

- [Try Coder Agents](../ai-coder/agents/getting-started.md), the chat
  interface and API for delegating development work to coding agents in your
  Coder deployment.

- [Read about managing Workspaces for your team](../user-guides/workspace-management.md)

- [Read about implementing monitoring tools for your Coder Deployment](../admin/monitoring/index.md)

## Troubleshooting

### Cannot connect to the Docker daemon

When creating a workspace from a Docker template, you may see an error like:

```text
Error: Error pinging Docker server: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

This means Docker is either not installed or not running on the machine where
Coder is running. Docker must be running before you create a workspace from a
Docker-based template.

<div class="tabs">

#### macOS

1. If Docker Desktop is not installed,
   [install it](https://docs.docker.com/desktop/setup/install/mac-install/) or
   use Homebrew:

   ```shell
   brew install --cask docker-desktop
   ```

1. Open Docker Desktop and verify that it is running.

#### Linux

1. Install Docker, if you haven't already:

   ```shell
   curl -sSL https://get.docker.com | sh
   ```

1. Start the Docker daemon:

   ```shell
   sudo systemctl start docker
   ```

1. Assign your user to the `docker` group so Coder can access the daemon
   without root:

   ```shell
   sudo usermod -aG docker $USER
   newgrp docker
   ```

1. Confirm the group membership:

   ```console
   $ groups
   docker sudo users
   ```

#### Windows

1. If Docker Desktop is not installed,
   [install it](https://docs.docker.com/desktop/install/windows-install/).

1. Open Docker Desktop and verify that it is running.

</div>

### Can't start Coder server: Address already in use

```shell
Encountered an error running "coder server", see "coder server --help" for more information
error: configure http(s): listen tcp 127.0.0.1:3000: bind: address already in use
```

Another process is already listening on port 3000. Identify and stop it,
then start the server again.

#### Linux

1. Stop the process:

   ```shell
   sudo systemctl stop coder
   ```

1. Start Coder:

   ```shell
   coder server
   ```

#### macOS

1. Identify the process using port 3000:

   ```shell
   lsof -i :3000
   ```

1. Stop the process using the PID from the previous command:

   ```shell
   kill <PID>
   ```

   If the process does not exit, force-kill it:

   ```shell
   kill -9 <PID>
   ```

1. Start Coder:

   ```shell
   coder server
   ```

#### Windows

1. Identify the process using port 3000 in PowerShell:

   ```powershell
   Get-NetTCPConnection -LocalPort 3000 | Select-Object OwningProcess
   ```

1. Stop the process using the PID from the previous command:

   ```powershell
   Stop-Process -Id <PID>
   ```

1. Start Coder:

   ```shell
   coder server
   ```

---

# Write a Template from Scratch

Source: https://coder.com/docs/tutorials/template-from-scratch

# Write a template from scratch

A template is a common configuration that you use to deploy workspaces.

This tutorial teaches you how to create a template that provisions a workspace
as a Docker container with Ubuntu.

## Before you start

You'll need a computer or cloud computing instance with both
[Docker](https://docs.docker.com/get-docker/) and [Coder](../install/index.md)
installed on it.

## What's in a template

The main part of a Coder template is a [Terraform](https://terraform.io) `tf`
file. A Coder template often has other files to configure the other resources
that the template needs. In this tour you'll also create a `Dockerfile`.

Coder can provision all Terraform modules, resources, and properties. The Coder
server essentially runs a `terraform apply` every time a workspace is created,
started, or stopped.

> [!TIP]
> Haven't written Terraform before? Check out Hashicorp's
> [Getting Started Guides](https://developer.hashicorp.com/terraform/tutorials).

Here's a simplified diagram that shows the main parts of the template we'll
create:

![Template architecture](../images/templates/template-architecture.png)

## 1. Create template files

On your local computer, create a directory for your template and create the
`Dockerfile`. You will upload the files to your Coder instance later.

```sh
mkdir -p template-tour/build && cd $_
```

Enter content into a `Dockerfile` that starts with the
[official Ubuntu image](https://hub.docker.com/_/ubuntu/). In your editor, enter
and save the following text in `Dockerfile` then exit the editor:

```dockerfile
FROM ubuntu

RUN apt-get update \
    && apt-get install -y \
    sudo \
    curl \
    && rm -rf /var/lib/apt/lists/*

ARG USER=coder
RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \
    && echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${USER} \
    && chmod 0440 /etc/sudoers.d/${USER}
USER ${USER}
WORKDIR /home/${USER}
```

`Dockerfile` adds a few things to the parent `ubuntu` image, which your template
needs later:

- It installs the `sudo` and `curl` packages.
- It adds a `coder` user, including a home directory.

## 2. Set up template providers

Edit the Terraform `main.tf` file to provision the workspace's resources.

Start by setting up the providers. At a minimum, we need the `coder` provider.
For this template, we also need the `docker` provider:

```tf
terraform {
  required_providers {
    coder = {
      source  = "coder/coder"
    }
    docker = {
      source  = "kreuzwerker/docker"
    }
  }
}

locals {
  username = data.coder_workspace_owner.me.name
}

data "coder_provisioner" "me" {
}

provider "docker" {
}

provider "coder" {
}

data "coder_workspace" "me" {
}

data "coder_workspace_owner" "me" {
}
```

Notice that the `provider` blocks for `coder` and `docker` are empty. In a more
practical template, you would add arguments to these blocks to configure the
providers, if needed.

The
[`coder_workspace`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace)
data source provides details about the state of a workspace, such as its name,
owner, and so on. The data source also lets us know when a workspace is being
started or stopped. We'll use this information in later steps to:

- Set some environment variables based on the workspace owner.
- Manage ephemeral and persistent storage.

## 3. coder_agent

All templates need to create and run a
[Coder agent](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent).
This lets developers connect to their workspaces. The `coder_agent` resource
runs inside the compute aspect of your workspace, typically a VM or container.
In our case, it will run in Docker.

You do not need to have any open ports on the compute aspect, but the agent
needs `curl` access to the Coder server.

Add this snippet after the last closing `}` in `main.tf` to create the agent:

```tf
resource "coder_agent" "main" {
  arch                   = data.coder_provisioner.me.arch
  os                     = "linux"
  startup_script         = <<-EOT
    set -e

    # install and start code-server
    curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server
    /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
  EOT

  env = {
    GIT_AUTHOR_NAME     = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
    GIT_AUTHOR_EMAIL    = "${data.coder_workspace_owner.me.email}"
    GIT_COMMITTER_NAME  = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
    GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}"
  }

  metadata {
    display_name = "CPU Usage"
    key          = "0_cpu_usage"
    script       = "coder stat cpu"
    interval     = 10
    timeout      = 1
  }

  metadata {
    display_name = "RAM Usage"
    key          = "1_ram_usage"
    script       = "coder stat mem"
    interval     = 10
    timeout      = 1
  }
}
```

Because Docker is running locally in the Coder server, there is no need to
authenticate `coder_agent`. But if your `coder_agent` is running on a remote
host, your template will need
[authentication credentials](../admin/external-auth/index.md).

This template's agent also runs a startup script, sets environment variables,
and provides metadata.

- [`startup script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)

  - Installs [code-server](https://coder.com/docs/code-server), a browser-based
    [VS Code](https://code.visualstudio.com/) app that runs in the workspace.

    We'll give users access to code-server through `coder_app` later.

- [`env` block](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#env)

  - Sets environments variables for the workspace.

    We use the data source from `coder_workspace` to set the environment
    variables based on the workspace's owner. This way, the owner can make git
    commits immediately without any manual configuration.

- [`metadata`](../admin/templates/extending-templates/agent-metadata.md) blocks

  - Your template can use metadata to show information to the workspace owner
    Coder displays this metadata in the Coder dashboard.

    Our template has `metadata` blocks for CPU and RAM usage.

## 4. coder_app

A
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
resource lets a developer use an app from the workspace's Coder dashboard.

![Apps in a Coder workspace](../images/templates/workspace-apps.png)

This is commonly used for
[web IDEs](../user-guides/workspace-access/web-ides.md) such as
[code-server](https://coder.com/docs/code-server), RStudio, and JupyterLab.

We installed code-server in the `startup_script` argument. To add code-server to
the workspace, make it available in the workspace with a `coder_app` resource.
See [web IDEs](../user-guides/workspace-access/web-ides.md) for more examples:

```tf
resource "coder_app" "code-server" {
  agent_id     = coder_agent.main.id
  slug         = "code-server"
  display_name = "code-server"
  url          = "http://localhost:13337/?folder=/home/${local.username}"
  icon         = "/icon/code.svg"
  subdomain    = false
  share        = "owner"

  healthcheck {
    url       = "http://localhost:13337/healthz"
    interval  = 5
    threshold = 6
  }
}
```

You can also use a `coder_app` resource to link to external apps, such as links
to wikis or cloud consoles:

```tf
resource "coder_app" "coder-server-doc" {
  agent_id     = coder_agent.main.id
  icon         = "/emojis/1f4dd.png"
  slug         = "getting-started"
  url          = "https://coder.com/docs/code-server"
  external     = true
}
```

## 5. Persistent and ephemeral resources

Managing the lifecycle of template resources is important. We want to make sure
that workspaces use computing, storage, and other services efficiently.

We want our workspace's home directory to persist after the workspace is stopped
so that a developer can continue their work when they start the workspace again.

We do this in 2 parts:

- Our `docker_volume` resource uses the `lifecycle` block with the
  `ignore_changes = all` argument to prevent accidental deletions.
- To prevent Terraform from destroying persistent Docker volumes in case of a
  workspace name change, we use an immutable parameter, like
  `data.coder_workspace.me.id`.

Later, we use the Terraform
[count](https://developer.hashicorp.com/terraform/language/meta-arguments/count)
meta-argument to make sure that our Docker container is ephemeral.

```tf
resource "docker_volume" "home_volume" {
  name = "coder-${data.coder_workspace.me.id}-home"
  # Protect the volume from being deleted due to changes in attributes.
  lifecycle {
    ignore_changes = all
  }
}
```

For details, see
[Resource persistence](../admin/templates/extending-templates/resource-persistence.md).

## 6. Set up the Docker container

To set up our Docker container, our template has a `docker_image` resource that
uses `build/Dockerfile`, which we created earlier:

```tf
resource "docker_image" "main" {
  name = "coder-${data.coder_workspace.me.id}"
  build {
    context = "./build"
    build_args = {
      USER = local.username
    }
  }
  triggers = {
    dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)]))
  }
}
```

Our `docker_container` resource uses `coder_workspace` `start_count` to start
and stop the Docker container:

```tf
resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = docker_image.main.name
  # Uses lower() to avoid Docker restriction on container names.
  name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
  # Hostname makes the shell more user friendly: coder@my-workspace:~$
  hostname = data.coder_workspace.me.name
  # Use the docker gateway if the access URL is 127.0.0.1
  entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")]
  env = [
    "CODER_AGENT_TOKEN=${coder_agent.main.token}",
  ]
  host {
    host = "host.docker.internal"
    ip   = "host-gateway"
  }
  volumes {
    container_path = "/home/${local.username}"
    volume_name    = docker_volume.home_volume.name
    read_only      = false
  }
}
```

## 7. Create the template in Coder

Save `main.tf` and exit the editor.

Now that we've created the files for our template, we can add them to our Coder
deployment.

We can do this with the Coder CLI or the Coder dashboard. In this example, we'll
use the Coder CLI.

1. Log in to your Coder deployment from the CLI. This is where you need the URL
   for your deployment:

   ```console
   $ coder login https://coder.example.com
   Attempting to authenticate with config URL: 'https://coder.example.com'
   Open the following in your browser:

       https://coder.example.com/cli-auth

   > Paste your token here:
   ```

1. In your web browser, enter your credentials:

   ![Log in to your Coder deployment](../images/screenshots/coder-login.png)

1. Copy the session token to the clipboard:

   ![Copy session token](../images/templates/coder-session-token.png)

1. Paste it into the CLI:

   ```output
   > Welcome to Coder, marc! You're authenticated.
   $
   ```

### Add the template files to Coder

Add your template files to your Coder deployment. You can upload the template
through the CLI, or through the Coder dashboard:

<div class="tabs">

#### CLI

1. Run `coder templates create` from the directory with your template files:

   ```console
   $ pwd
   /home/docs/template-tour
   $ coder templates push
   > Upload "."? (yes/no) yes
   ```

1. The Coder CLI tool gives progress information then prompts you to confirm:

   ```console
   > Confirm create? (yes/no) yes

   The template-tour template has been created! Developers can provision a workspace with this template using:

   coder create --template="template-tour" [workspace name]
   ```

1. In your web browser, log in to your Coder dashboard, select **Templates**.

1. Once the upload completes, select **Templates** from the top to deploy it to
   a new workspace.

   ![Your new template, ready to use](../images/templates/template-tour.png)

#### Dashboard

1. Create a `.zip` of the template files.

   - On Mac or Windows, highlight the files and then right click. A "compress"
     option is available through the right-click context menu.

   - To zip the files through the command line:

     ```shell
     zip templates.zip Dockerfile main.tf
     ```

1. Select **Templates** from the top of the Coder dashboard, then **Create
   Template**.
1. Select **Upload template**:

   ![Upload your first template](../images/templates/upload-create-your-first-template.png)

1. Drag the `.zip` file into the **Upload template** section and fill out the
   details, then select **Create template**.

   ![Upload the template files](../images/templates/upload-create-template-form.png)

1. Once the upload completes, select **Templates** from the top to deploy it to
   a new workspace.

   ![Your new template, ready to use](../images/templates/template-tour.png)

</div>

### Next steps

- [Setting up templates](../admin/templates/index.md)
- [Customizing templates](../admin/templates/extending-templates/index.md)
- [Troubleshooting template](../admin/templates/troubleshooting.md)

---

# Using an External Database

Source: https://coder.com/docs/tutorials/external-database

# Using Coder with an external database

## Recommendation

For production deployments, we recommend using an external
[PostgreSQL](https://www.postgresql.org/) database (version 13 or higher).

## Basic configuration

Before starting the Coder server, prepare the database server by creating a role
and a database. Remember that the role must have access to the created database.

With `psql`:

```sql
CREATE ROLE coder LOGIN SUPERUSER PASSWORD 'secret42';
```

With `psql -U coder`:

```sql
CREATE DATABASE coder;
```

Coder configuration is defined via
[environment variables](../admin/setup/index.md). The database client requires
the connection string provided via the `CODER_PG_CONNECTION_URL` variable.

```shell
export CODER_PG_CONNECTION_URL="postgres://coder:secret42@localhost/coder?sslmode=disable"
```

## Custom schema

For installations with elevated security requirements, it's advised to use a
separate [schema](https://www.postgresql.org/docs/current/ddl-schemas.html)
instead of the public one.

With `psql -U coder`:

```sql
CREATE SCHEMA myschema;
```

Once the schema is created, you can list all schemas with `\dn`:

```text
List of schemas
 Name      | Owner
-----------+----------
 myschema  | coder
 public    | postgres
(2 rows)
```

In this case the database client requires the modified connection string:

```shell
export CODER_PG_CONNECTION_URL="postgres://coder:secret42@localhost/coder?sslmode=disable&search_path=myschema"
```

The `search_path` parameter determines the order of schemas in which they are
visited while looking for a specific table. The first schema named in the search
path is called the current schema. By default `search_path` defines the
following schemas:

```sql
SHOW search_path;

search_path
--------------
 "$user", public
```

Using the `search_path` in the connection string corresponds to the following
`psql` command:

```sql
ALTER ROLE coder SET search_path = myschema;
```

## Troubleshooting

### Coder server fails startup with "current_schema: converting NULL to string is unsupported"

Please make sure that the schema selected in the connection string
`...&search_path=myschema` exists and the role has granted permissions to access
it. The schema should be present on this listing:

```shell
psql -U coder -c '\dn'
```

---

# Image Management

Source: https://coder.com/docs/admin/templates/managing-templates/image-management

# Image Management

While Coder provides example
[base container images](https://github.com/coder/enterprise-images) for
workspaces, it's often best to create custom images that matches the needs of
your users. This document serves a guide to operational maturity with some best
practices around managing workspaces images for Coder.

1. Create a minimal base image
2. Create golden image(s) with standard tooling
3. Allow developers to bring their own images and customizations with Dev
   Containers

An image is just one of the many properties defined within the template.
Templates can pull images from a public image registry (e.g. Docker Hub) or an
internal one, thanks to Terraform.

## Create a minimal base image

While you may not use this directly in Coder templates, it's useful to have a
minimal base image is a small image that contains only the necessary
dependencies to work in your network and work with Coder. Here are some things
to consider:

- `curl`, `wget`, or `busybox` is required to download and run
  [the agent](https://github.com/coder/coder/blob/main/provisionersdk/scripts/bootstrap_linux.sh)
- `git` is recommended so developers can clone repositories
- If the Coder server is using a certificate from an internal certificate
  authority (CA), you'll need to add or mount these into your image
- Other generic utilities that will be required by all users, such as `ssh`,
  `docker`, `bash`, `jq`, and/or internal tooling
- Consider creating (and starting the container with) a non-root user

See Coder's
[example base image](https://github.com/coder/enterprise-images/tree/main/images/minimal)
for reference.

## Create general-purpose golden image(s) with standard tooling

It's often practical to have a few golden images that contain standard tooling
for developers. These images should contain a number of languages (e.g. Python,
Java, TypeScript), IDEs (VS Code, JetBrains, PyCharm), and other tools (e.g.
`docker`). Unlike project-specific images (which are also important), general
purpose images are great for:

- **Scripting:** Developers may just want to hop in a Coder workspace to run
  basic scripts or queries.
- **Day 1 Onboarding:** New developers can quickly get started with a familiar
  environment without having to browse through (or create) an image
- **Basic Projects:** Developers can use these images for simple projects that
  don't require any specific tooling outside of the standard libraries. As the
  project gets more complex, its best to move to a project-specific image.
- **"Golden Path" Projects:** If your developer platform offers specific tech
  stacks and types of projects, the golden image can be a good starting point
  for those projects.

This is often referred to as a "sandbox" or "kitchen sink" image. Since large
multi-purpose container images can quickly become difficult to maintain, it's
important to keep the number of general-purpose images to a minimum (2-3 in
most cases) with a well-defined scope.

Examples:

- [Universal Dev Containers Image](https://github.com/devcontainers/images/tree/main/src/universal)

## Allow developers to bring their own images and customizations with Dev Containers

While golden images are great for general use cases, developers will often need
specific tooling for their projects. The [Dev Container](https://containers.dev)
specification allows developers to define their projects dependencies within a
`devcontainer.json` in their Git repository.

- [Configure a template for Dev Containers](../../integrations/devcontainers/integration.md) (recommended)
- [Learn about Envbuilder](../../integrations/devcontainers/envbuilder/index.md) (alternative for environments without Docker)

---

# Configuring Okta

Source: https://coder.com/docs/tutorials/configuring-okta

# Configuring Custom Claims/Scopes with Okta for group/role

<div style="pad: 0px; margin: 0px;">
  <span style="vertical-align:middle;">Author: </span>
  <a href="https://github.com/Emyrk" style="text-decoration: none; color: inherit; margin-bottom: 0px;">
    <span style="vertical-align:middle;">Steven Masley</span>
  </a>
</div>
Updated: June, 2025

---

Okta is an identity provider that can be used for OpenID Connect (OIDC) Single
Sign On (SSO) on Coder.

To configure custom claims in Okta to support syncing roles and groups with
Coder, you must first have setup an Okta application with
[OIDC working with Coder](../admin/users/oidc-auth/index.md).
From here, we will add additional claims for Coder to use for syncing groups and
roles.

You may use a hybrid of the following approaches.

## (Easiest) Sync using Okta Groups

If the Coder roles & Coder groups can be inferred from
[Okta groups](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-about-groups.htm),
Okta has a simple way to send over the groups as a `claim` in the `id_token`
payload.

In Okta, go to the application **Sign On** settings page.

**Applications** > **Select Application** > **General** > **Sign On**

In the **OpenID Connect ID Token** section, turn on **Groups Claim Type** and set
the **Claim name** to `groups`.
Optionally, configure a filter for which groups to be sent.

> [!IMPORTANT]
> If the user does not belong to any groups, the claim will not be sent.
> Make sure the user authenticating for testing is in at least one group.

![Okta OpenID Connect ID Token](../images/guides/okta/oidc_id_token.png)

Configure Coder to use these claims for group sync.
These claims are present in the `id_token`.
For more group sync configuration options, consult the [IDP sync documentation](../admin/users/idp-sync.md#group-sync).

```bash
# Add the 'groups' scope and include the 'offline_access' scope for refresh tokens
CODER_OIDC_SCOPES=openid,profile,email,offline_access,groups
# This name needs to match the "Claim name" in the configuration above.
CODER_OIDC_GROUP_FIELD=groups
```

> [!NOTE]
> The `offline_access` scope is required in Coder v2.23.0+ to prevent hourly session timeouts.

These groups can also be used to configure role syncing based on group
membership:

```bash
CODER_OIDC_SCOPES=openid,profile,email,offline_access,groups
# This name needs to match the "Claim name" in the configuration above.
CODER_OIDC_USER_ROLE_FIELD=groups
# Example configuration to map a group to some roles
CODER_OIDC_USER_ROLE_MAPPING='{"admin-group":["template-admin","user-admin"]}'
```

## (Easy) Mapping Okta profile attributes

If roles or groups cannot be completely inferred from Okta group memberships,
another option is to source them from a user's attributes.
The user attribute list can be found in **Directory** > **Profile Editor** > **User (default)**.

Coder can query an Okta profile for the application from the `/userinfo` OIDC endpoint.
To pass attributes to Coder, create the attribute in your application,
then add a mapping from the Okta profile to the application.

**Directory** > **Profile Editor** > {Your Application} > **Add Attribute**

Create the attribute for the roles, groups, or both. Make sure the attribute
is of type `string array`:

![Okta Add Attribute view](../images/guides/okta/add_attribute.png)

On the **Okta User to {Your Application}** tab, map a `roles` or `groups`
attribute you have configured to the application:

![Okta Add Claim view](../images/guides/okta/add_claim.png)

Configure using these new attributes in Coder:

```bash
# This must be set to false. Coder uses this endpoint to grab the attributes.
CODER_OIDC_IGNORE_USERINFO=false
# Include offline_access for refresh tokens
CODER_OIDC_SCOPES=openid,profile,email,offline_access
# Configure the group/role field using the attribute name in the application.
CODER_OIDC_USER_ROLE_FIELD=approles
# See our docs for mapping okta roles to coder roles.
CODER_OIDC_USER_ROLE_MAPPING='{"admin-group":["template-admin","user-admin"]}'

# If you added an attribute for groups, set that here.
# CODER_OIDC_GROUP_FIELD=...
```

> [!NOTE]
> The `offline_access` scope is required in Coder v2.23.0+ to prevent hourly session timeouts.

## (Advanced) Custom scopes to retrieve custom claims

Okta does not support setting custom scopes and claims in the default
authorization server used by your application.
If you require this functionality, you must create (or modify) an authorization server.

To see your custom authorization servers go to **Security** > **API**.
Note the `default` authorization server is not the authorization server your app is using.
You can configure this default authorization server, or create a new one specifically for your application.

Authorization servers also give more refined controls over things such as token/session lifetimes.

![Okta API view](../images/guides/okta/api_view.png)

To get custom claims working, map them to a custom scope.
Click the authorization server you wish to use (likely just using the default).

Go to **Scopes**, and **Add Scope**.
Feel free to create one for roles, groups, or both:

![Okta Add Scope view](../images/guides/okta/add_scope.png)

Create the claim to go with the said scope.
Go to **Claims**, then **Add Claim**.
Make sure to select **ID Token** for the token type.
The **Value** expression is up to you based on where you are sourcing the role information.
Configure it to only be a claim with the requested scope.
This is so if other applications exist, we do not send them information they do not care about:

![Okta Add Claim with Roles view](../images/guides/okta/add_claim_with_roles.png)

Now we have a custom scope and claim configured under an authorization server.
Configure Coder to use this:

```bash
# Grab this value from the Authorization Server > Settings > Issuer
# DO NOT USE the application issuer URL. Make sure to use the newly configured
# authorization server.
CODER_OIDC_ISSUER_URL=https://dev-12222860.okta.com/oauth2/default
# Add the new scope you just configured and offline_access for refresh tokens
CODER_OIDC_SCOPES=openid,profile,email,roles,offline_access
# Use the claim you just configured
CODER_OIDC_USER_ROLE_FIELD=roles
# See our docs for mapping okta roles to coder roles.
CODER_OIDC_USER_ROLE_MAPPING='{"admin-group":["template-admin","user-admin"]}'
```

> [!NOTE]
> The `offline_access` scope is required in Coder v2.23.0+ to prevent hourly session timeouts.

You can use the "Token Preview" page to verify it has been correctly configured
and verify the `roles` is in the payload.

![Okta Token Preview](../images/guides/okta/token_preview.png)

## Troubleshooting

### Users Are Logged Out Every Hour

**Symptoms**: Users experience session timeouts approximately every hour and must re-authenticate
**Cause**: Missing `offline_access` scope in `CODER_OIDC_SCOPES`
**Solution**:

1. Add `offline_access` to your `CODER_OIDC_SCOPES` configuration
1. Restart your Coder deployment
1. All existing users must logout and login once to receive refresh tokens

### Refresh Tokens Not Working After Configuration Change

**Symptoms**: Hourly timeouts, even after adding `offline_access`
**Cause**: Existing user sessions don't have refresh tokens stored
**Solution**: Users must logout and login again to get refresh tokens stored in the database

### Verify Refresh Token Configuration

To confirm that refresh tokens are working correctly:

1. Check that `offline_access` is included in your `CODER_OIDC_SCOPES`
1. Verify users can stay logged in beyond Okta's access token lifetime (typically one hour)
1. Monitor Coder logs for any OIDC refresh errors during token renewal

---

# Persistent Shared Workspaces

Source: https://coder.com/docs/tutorials/persistent-shared-workspaces

# Persistent Shared Workspaces with Service Accounts

> [!NOTE]
> This guide requires a
> [Premium license](https://coder.com/pricing#compare-plans) because service
> accounts are a Premium feature. For more details,
> [contact your account team](https://coder.com/contact).

This guide walks through setting up a long-lived workspace that is owned by a
service account and shared with a rotating set of users. Because no single
person owns the workspace, it persists across team changes and every user
authenticates as themselves.

This pattern is useful for any scenario where a workspace outlives the people
who use it:

- **On-call rotations** — Engineers share a workspace pre-loaded with runbooks,
  dashboards, and monitoring tools. Access rotates with the shift schedule.
- **Shared staging or QA** — A team workspace hosts a persistent staging
  environment. Testers and reviewers are added and removed as sprints change.
- **Pair programming** — A service-account-owned workspace gives two or more
  developers a shared environment without either one owning (and accidentally
  deleting) it.
- **Contractor onboarding** — An external team gets scoped access to a workspace
  for the duration of an engagement, then access is revoked.

The steps below use an **on-call SRE workspace** as a running example, but the
same commands apply to any of the scenarios above. Substitute the usernames,
group names, and template to match your use case.

## Prerequisites

- A running Coder deployment (v2.32+) with workspace sharing enabled. Sharing
  is on by default for OSS; Premium deployments may require
  [admin configuration](../user-guides/shared-workspaces.md#policies).
- The [Coder CLI](../install/index.md) installed and authenticated.
- An account with the `Owner` or `User Admin` role.
- [OIDC authentication](../admin/users/oidc-auth/index.md) configured so
  shared users log in with their corporate SSO identity. Configure
  [refresh tokens](../admin/users/oidc-auth/refresh-tokens.md) to prevent
  session timeouts during long work sessions.
- A [wildcard access URL](../admin/networking/wildcard-access-url.md) configured
  (e.g. `*.coder.example.com`) so that shared users can access workspace apps
  without a 404.
- (Recommended) [IdP Group Sync](../admin/users/idp-sync.md#group-sync)
  configured if your identity provider manages group membership for the teams
  that will share the workspace.

## 1. Create a service account

Create a dedicated service account that will own the shared workspace. Service
accounts are non-human accounts intended for automation and shared ownership.
Because no individual user owns the workspace, there are no personal
credentials to expose and the shared environment is not affected when any user
leaves the team or the organization.

```shell
# On-call example — substitute a name that fits your use case
coder users create \
  --username oncall-sre \
  --service-account
```

## 2. Generate an API token for the service account

Generate a long-lived API token so you can create and manage workspaces on
behalf of the service account:

```shell
coder tokens create \
  --user oncall-sre \
  --name oncall-automation \
  --lifetime 8760h
```

Store this token securely (e.g. in a secrets manager like Vault or AWS Secrets
Manager).

> [!IMPORTANT]
> Never distribute this token to end users. The token is for workspace
> administration only. Shared users authenticate as themselves and reach the
> workspace through sharing.

## 3. Create the workspace

Authenticate as the service account and create the workspace:

```shell
export CODER_SESSION_TOKEN="<token-from-step-2>"

coder create oncall-sre/oncall-workspace \
  --template your-oncall-template \
  --use-parameter-defaults \
  --yes
```

> [!TIP]
> Design a dedicated template for the workspace with the tools your team
> needs pre-installed (e.g. monitoring dashboards for on-call, test runners
> for QA). Set `subdomain = true` on workspace apps so that shared users can
> access web-based tools without a 404. See
> [Accessing workspace apps in shared workspaces](../user-guides/shared-workspaces.md#accessing-workspace-apps-in-shared-workspaces).

## 4. Share the workspace

Use `coder sharing share` to grant access to users who need the workspace:

```shell
coder sharing share oncall-sre/oncall-workspace --user alice
```

This gives `alice` the default `use` role, which allows connection via SSH and
workspace apps, starting and stopping the workspace, and viewing logs and stats.

To grant `admin` permissions (which includes all `use` permissions as well as renaming, updating, and inviting
others to join with the `use` role):

```shell
coder sharing share oncall-sre/oncall-workspace --user alice:admin
```

To share with multiple users at once:

```shell
coder sharing share oncall-sre/oncall-workspace --user alice:admin,bob
```

To share with an entire Coder group:

```shell
coder sharing share oncall-sre/oncall-workspace --group sre-oncall
```

> [!NOTE]
> Groups can be synced from your identity provider using
> [IdP Sync](../admin/users/idp-sync.md#group-sync). If your IdP already
> manages team membership, sharing with a group is the simplest approach.

## 5. Rotate access

When team membership changes, remove outgoing users and add incoming ones:

```shell
# Remove outgoing user
coder sharing remove oncall-sre/oncall-workspace --user alice

# Add incoming user
coder sharing share oncall-sre/oncall-workspace --user carol
```

> [!IMPORTANT]
> The workspace must be restarted for user removal to take effect.

Verify current sharing status at any time:

```shell
coder sharing status oncall-sre/oncall-workspace
```

## 6. Automate access changes (optional)

For use cases with frequent rotation (such as on-call shifts), you can integrate
the share/remove commands into external tooling like PagerDuty, Opsgenie, or a
cron job.

### Rotation script

```shell
#!/bin/bash
# rotate-access.sh
# Usage: ./rotate-access.sh <outgoing-user> <incoming-user>

WORKSPACE="oncall-sre/oncall-workspace"
OUTGOING="$1"
INCOMING="$2"

if [ -n "$OUTGOING" ]; then
  echo "Removing access for $OUTGOING..."
  coder sharing remove "$WORKSPACE" --user "$OUTGOING"
fi

echo "Granting access to $INCOMING..."
coder sharing share "$WORKSPACE" --user "$INCOMING"

echo "Restarting workspace to apply changes..."
coder restart "$WORKSPACE" --yes

echo "Current sharing status:"
coder sharing status "$WORKSPACE"
```

### Group-based rotation with IdP Sync

If your identity provider manages group membership (e.g. an `sre-oncall` group
in Okta or Azure AD), you can skip manual share/remove commands entirely:

1. Configure [Group Sync](../admin/users/idp-sync.md#group-sync) to
   synchronize the group from your IdP to Coder.

1. Share the workspace with the group once:

   ```shell
   coder sharing share oncall-sre/oncall-workspace --group sre-oncall
   ```

1. When your IdP rotates group membership, Coder group membership updates on
   next login. All current members have access; removed members lose access
   after a workspace restart.

## Finding shared workspaces

Shared users can find workspaces shared with them:

```shell
# List all workspaces shared with you
coder list --search shared:true

# List workspaces shared with a specific user
coder list --search shared_with_user:alice

# List workspaces shared with a specific group
coder list --search shared_with_group:sre-oncall
```

## Troubleshooting

### Shared user sees 404 on workspace apps

Workspace apps using path-based routing block non-owners by default. Configure a
[wildcard access URL](../admin/networking/wildcard-access-url.md) and set
`subdomain = true` on the workspace app in your template.

### Removed user still has access

Access removal requires a workspace restart. Run
`coder restart <workspace>` after removing a user or group.

### Group sync not updating membership

Group membership changes in your IdP are not reflected until the user logs out
and back in. Group sync runs at login time, not on a polling schedule. Check the
Coder server logs with
`CODER_LOG_FILTER=".*userauth.*|.*groups returned.*"` for details. See
[Troubleshooting group sync](../admin/users/idp-sync.md#troubleshooting-grouproleorganization-sync)
for more information.

## Next steps

- [Shared Workspaces](../user-guides/shared-workspaces.md) — full reference
  for workspace sharing features and UI
- [IdP Sync](../admin/users/idp-sync.md) — group, role, and organization
  sync configuration
- [Configuring Okta](./configuring-okta.md) — Okta-specific OIDC setup with
  custom claims and scopes
- [Security Best Practices](./best-practices/security-best-practices.md) —
  deployment-wide security hardening
- [Sessions and Tokens](../admin/users/sessions-tokens.md) — API token
  management and scoping

---

# Google to AWS Federation

Source: https://coder.com/docs/tutorials/gcp-to-aws

# Federating a Google Cloud service account to AWS

<div>
  <a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Eric Paulsen</span>
  </a>
</div>
January 4, 2024

---

This guide will walkthrough how to use a Google Cloud service account to
authenticate the Coder control plane to AWS and create an EC2 workspace. The
below steps assume your Coder control plane is running in Google Cloud and has
the relevant service account assigned.

For steps on assigning a service account to a resource like Coder, visit the
[Google documentation](https://cloud.google.com/iam/docs/attach-service-accounts#attaching-new-resource).

## 1. Get your Google service account OAuth Client ID

Navigate to the Google Cloud console, and select **IAM & Admin** > **Service
Accounts**. View the service account you want to use, and copy the **OAuth 2
Client ID** value shown on the right-hand side of the row.

Optionally: If you do not yet have a service account, use the
[Google IAM documentation on creating a service account](https://cloud.google.com/iam/docs/service-accounts-create) to create one.

## 2. Create AWS role

Create an AWS role that is configured for Web Identity Federation, with Google
as the identity provider, as shown below:

![AWS Create Role](../images/guides/gcp-to-aws/aws-create-role.png)

Once created, edit the **Trust Relationship** section to look like the
following:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "accounts.google.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "accounts.google.com:aud": "<enter-OAuth-client-ID-here"
                }
            }
        }
    ]
}
```

## 3. Assign permissions to the AWS role

In this example, Coder will need permissions to create the EC2 instance. Add the
following policy to the role:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:GetDefaultCreditSpecification",
                "ec2:DescribeIamInstanceProfileAssociations",
                "ec2:DescribeTags",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceTypes",
                "ec2:CreateTags",
                "ec2:RunInstances",
                "ec2:DescribeInstanceCreditSpecifications",
                "ec2:DescribeImages",
                "ec2:ModifyDefaultCreditSpecification",
                "ec2:DescribeVolumes"
            ],
            "Resource": "*"
        },
        {
            "Sid": "CoderResources",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstanceAttribute",
                "ec2:UnmonitorInstances",
                "ec2:TerminateInstances",
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:DeleteTags",
                "ec2:MonitorInstances",
                "ec2:CreateTags",
                "ec2:RunInstances",
                "ec2:ModifyInstanceAttribute",
                "ec2:ModifyInstanceCreditSpecification"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Coder_Provisioned": "true"
                }
            }
        }
    ]
}
```

## 4. Generate the identity token for the service account

Run the following `gcloud` command to generate the service account identity
token. This is a JWT token with a payload that includes the service account
email, audience, issuer, and expiration.

```console
gcloud auth print-identity-token --audiences=https://aws.amazon.com --impersonate-service-account 12345-compute@de
veloper.gserviceaccount.com  --include-email
```

> [!NOTE]
> Your `gcloud` client may needed elevated permissions to run this
> command.

## 5. Set identity token in Coder control plane

You will need to set the token created in the previous step on a location in the
Coder control plane. Follow the below steps for your specific deployment type:

### VM control plane

- Write the token to a file on the host, preferably inside the `/home/coder`
  directory:

```console
/home/coder/.aws/gcp-identity-token
```

### Kubernetes control plane

- Create the Kubernetes secret to house the token value:

```console
kubectl create secret generic gcp-identity-token -n coder --from-literal=token=<enter-token-here>
```

Make sure the secret is created inside the same namespace where Coder is
running.

- Mount the token file into the Coder pod using the values below:

```yaml
coder:
  volumes:
    - name: "gcp-identity-mount"
      secret:
        secretName: "gcp-identity-token"
  volumeMounts:
    - name: "gcp-identity-mount"
      mountPath: "/home/coder/.aws/gcp-identity-token"
      readOnly: true
```

## 6. Configure the AWS Terraform provider

Navigate to your EC2 workspace template in Coder, and configure the AWS provider
using the block below:

```tf
provider "aws" {
  assume_role_with_web_identity {
    # enter role ARN here - copy from AWS console
    role_arn = "arn:aws:iam::123456789:role/gcp-to-aws"
    # arbitrary value for logging
    session_name = "coder-session"
    # define location of token file on control plane here
    web_identity_token_file = "/home/coder/.aws/gcp-identity-token"
  }
}
```

This provider block is equivalent to running this `aws` CLI command:

```console
aws sts assume-role-with-web-identity \
  --role-arn arn:aws:iam::123456789:role/gcp-to-aws \
  --role-session-name coder-session \
  --web-identity-token xxx
```

You can run this command with the identity token string to validate or
troubleshoot the call to AWS.

---

# JFrog Artifactory Integration

Source: https://coder.com/docs/admin/integrations/jfrog-artifactory

# JFrog Artifactory Integration

Use Coder and JFrog Artifactory together to secure your development environments
without disturbing your developers' existing workflows.

This guide will demonstrate how to use JFrog Artifactory as a package registry
within a workspace.

## Requirements

- A JFrog Artifactory instance
- 1:1 mapping of users in Coder to users in Artifactory by email address or
  username
- Repositories configured in Artifactory for each package manager you want to
  use

## Provisioner Authentication

The most straight-forward way to authenticate your template with Artifactory is
by using our official Coder [modules](https://registry.coder.com). We publish
two type of modules that automate the JFrog Artifactory and Coder integration.

1. [JFrog-OAuth](https://registry.coder.com/modules/jfrog-oauth)
1. [JFrog-Token](https://registry.coder.com/modules/jfrog-token)

### JFrog-OAuth

This module is usable by JFrog self-hosted (on-premises) Artifactory as it
requires configuring a custom integration. This integration benefits from Coder's [external-auth](../external-auth/index.md) feature allows each user to authenticate with Artifactory using an OAuth flow and issues user-scoped tokens to each user.

To set this up, follow these steps:

1. Add the following to your Helm chart `values.yaml` for JFrog Artifactory. Replace `CODER_URL` with your JFrog Artifactory base URL:

   ```yaml
   artifactory:
     enabled: true
     frontend:
     extraEnvironmentVariables:
       - name: JF_FRONTEND_FEATURETOGGLER_ACCESSINTEGRATION
         value: "true"
     access:
     accessConfig:
       integrations-enabled: true
       integration-templates:
         - id: "1"
           name: "CODER"
           redirect-uri: "https://CODER_URL/external-auth/jfrog/callback"
           scope: "applied-permissions/user"
   ```

1. Create a new Application Integration by going to
   `https://JFROG_URL/ui/admin/configuration/integrations/app-integrations/new` and select the
   Application Type as the integration you created in step 1 or `Custom Integration` if you are using SaaS instance i.e. example.jfrog.io.

1. Add a new [external authentication](../external-auth/index.md) to Coder by setting these
   environment variables in a manner consistent with your Coder deployment. Replace `JFROG_URL` with your JFrog Artifactory base URL:

   ```env
   # JFrog Artifactory External Auth
   CODER_EXTERNAL_AUTH_1_ID="jfrog"
   CODER_EXTERNAL_AUTH_1_TYPE="jfrog"
   CODER_EXTERNAL_AUTH_1_CLIENT_ID="YYYYYYYYYYYYYYY"
   CODER_EXTERNAL_AUTH_1_CLIENT_SECRET="XXXXXXXXXXXXXXXXXXX"
   CODER_EXTERNAL_AUTH_1_DISPLAY_NAME="JFrog Artifactory"
   CODER_EXTERNAL_AUTH_1_DISPLAY_ICON="/icon/jfrog.svg"
   CODER_EXTERNAL_AUTH_1_AUTH_URL="https://JFROG_URL/ui/authorization"
   CODER_EXTERNAL_AUTH_1_SCOPES="applied-permissions/user"
   ```

1. Create or edit a Coder template and use the [JFrog-OAuth](https://registry.coder.com/modules/jfrog-oauth) module to configure the integration:

   ```tf
   module "jfrog" {
     count          = data.coder_workspace.me.start_count
     source         = "registry.coder.com/modules/jfrog-oauth/coder"
     version        = "1.0.19"
     agent_id       = coder_agent.example.id
     jfrog_url      = "https://example.jfrog.io"
     username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"

     package_managers = {
       npm    = ["npm", "@scoped:npm-scoped"]
       go     = ["go", "another-go-repo"]
       pypi   = ["pypi", "extra-index-pypi"]
       docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"]
     }
   }
   ```

### JFrog-Token

This module makes use of the [Artifactory terraform
provider](https://registry.terraform.io/providers/jfrog/artifactory/latest/docs) and an admin-scoped token to create
user-scoped tokens for each user by matching their Coder email or username with
Artifactory. This can be used for both SaaS and self-hosted (on-premises)
Artifactory instances.

To set this up, follow these steps:

1. Get a JFrog access token from your Artifactory instance. The token must be an [admin token](https://registry.terraform.io/providers/jfrog/artifactory/latest/docs#access-token) with scope `applied-permissions/admin`.

1. Create or edit a Coder template and use the [JFrog-Token](https://registry.coder.com/modules/jfrog-token) module to configure the integration and pass the admin token. It is recommended to store the token in a sensitive Terraform variable to prevent it from being displayed in plain text in the terraform state:

   ```tf
   variable "artifactory_access_token" {
     type      = string
     sensitive = true
   }

   module "jfrog" {
     source                   = "registry.coder.com/modules/jfrog-token/coder"
     version                  = "1.0.30"
     agent_id                 = coder_agent.example.id
     jfrog_url                = "https://XXXX.jfrog.io"
     artifactory_access_token = var.artifactory_access_token
     package_managers = {
       npm    = ["npm", "@scoped:npm-scoped"]
       go     = ["go", "another-go-repo"]
       pypi   = ["pypi", "extra-index-pypi"]
       docker = ["example-docker-staging.jfrog.io", "example-docker-production.jfrog.io"]
     }
   }
   ```

> [!NOTE]
> The admin-level access token is used to provision user tokens and is never exposed to developers or stored in workspaces.

If you don't want to use the official modules, you can read through the [example template](https://github.com/coder/coder/tree/main/examples/jfrog/docker), which uses Docker as the underlying compute. The
same concepts apply to all compute types.

## Air-Gapped Deployments

See the [air-gapped deployments](../templates/extending-templates/modules.md#offline-installations) section for instructions on how to use Coder modules in an offline environment with Artifactory.

## Next Steps

- See the [full example Docker template](https://github.com/coder/coder/tree/main/examples/jfrog/docker).

- To serve extensions from your own VS Code Marketplace, check out
  [code-marketplace](https://github.com/coder/code-marketplace#artifactory-storage).

---

# Mirror Coder Registry with Artifactory

Source: https://coder.com/docs/install/registry-mirror-artifactory

# Mirror the Coder Registry with JFrog Artifactory

This guide shows you how to use JFrog Artifactory to mirror the
[Coder Registry](https://registry.coder.com) for air-gapped or restricted
network deployments.

By configuring Artifactory as a Remote Terraform Repository, you can:

- **Proxy and cache** all Coder modules automatically
- **Keep modules updated** without manual synchronization
- **Support offline access** once modules are cached

## Prerequisites

- JFrog Artifactory instance (Cloud or self-hosted)
- Admin access to create repositories
- Artifactory user token for Terraform authentication

## Step 1: Create the Remote Terraform Repository

1. In Artifactory, go to **Administration > Repositories > Remote**

1. Click **New Remote Repository** and select **Terraform** as the package type

1. Configure the repository with these settings:

   | Setting                | Value                        |
   |------------------------|------------------------------|
   | Repository Key         | `coder-registry`             |
   | URL                    | `https://registry.coder.com` |
   | Terraform Registry URL | `https://registry.coder.com` |

1. Click **Create Remote Repository**

## Step 2: Verify the Repository Configuration

Test that Artifactory can proxy the Coder registry by querying the module
versions API:

```sh
curl -u '<username>:<token>' \
  'https://<your-artifactory-host>/artifactory/api/terraform/coder-registry/v1/modules/coder/code-server/coder/versions'
```

You should see a JSON response listing all available versions of the
`code-server` module.

## Step 3: Configure Terraform CLI

Create or update your Terraform CLI configuration file to use Artifactory.

On Linux/macOS, create `~/.terraformrc`. On Windows, create `%APPDATA%\terraform.rc`.

```hcl
host "<your-artifactory-host>" {
  services = {
    "modules.v1" = "https://<your-artifactory-host>/artifactory/api/terraform/coder-registry/v1/modules/"
  }
}

credentials "<your-artifactory-host>" {
  token = "<your-artifactory-token>"
}
```

Replace:

- `<your-artifactory-host>` with your Artifactory hostname (e.g.,
  `artifactory.example.com` or `mycompany.jfrog.io`)
- `<your-artifactory-token>` with your Artifactory access token with read permissions to the `coder-registry` repository

> [!NOTE]
> The `host` block with `services` is required because Artifactory's global
> service discovery endpoint doesn't include the repository name in the modules
> path. This explicitly tells Terraform where to find modules in your specific
> repository.

## Step 4: Update Template Module Sources

Update your Coder templates to use Artifactory instead of the public registry:

```tf
# Before: Direct from Coder registry
module "code-server" {
  source   = "registry.coder.com/coder/code-server/coder"
  version  = "1.4.2"
  agent_id = coder_agent.main.id
}

# After: Through Artifactory mirror
module "code-server" {
  source   = "https://<your-artifactory-host>/coder/code-server/coder"
  version  = "1.4.2"
  agent_id = coder_agent.main.id
}
```

## Step 5: Configure Coder Server or Provisioners

For Coder to use the Artifactory mirror, configure the Terraform CLI on your
Coder server or external provisioners.

<div class="tabs">

### Kubernetes Deployment

Create a secret with the Terraform configuration:

```sh
kubectl create secret generic terraform-config \
  --from-file=.terraformrc=./terraformrc \
  -n coder
```

Update your Helm values:

```yaml
coder:
  volumes:
    - name: terraform-config
      secret:
        secretName: terraform-config
  volumeMounts:
    - name: terraform-config
      mountPath: /home/coder/.terraformrc
      subPath: .terraformrc
      readOnly: true
  env:
    - name: TF_CLI_CONFIG_FILE
      value: /home/coder/.terraformrc
```

### Docker Deployment

Mount the `.terraformrc` file into the Coder container:

```yaml
# docker-compose.yaml
services:
  coder:
    volumes:
      - ./terraformrc:/home/coder/.terraformrc:ro
    environment:
      TF_CLI_CONFIG_FILE: /home/coder/.terraformrc
```

</div>

## Caching Behavior

Artifactory uses **lazy caching**, meaning modules are cached on first request.
For fully air-gapped deployments, pre-warm the cache while connected to the
internet:

1. Create a test template that references all modules you need
1. Run `terraform init` to trigger downloads
1. Verify modules appear in Artifactory under `coder-registry-cache`

Once cached, modules remain available even without internet connectivity.

## Supported Namespaces

The Artifactory mirror supports all namespaces from the Coder registry:

| Namespace    | Description               | Example Module                     |
|--------------|---------------------------|------------------------------------|
| `coder`      | Official Coder modules    | `code-server`, `jetbrains-gateway` |
| `coder-labs` | Experimental modules      | `cursor-cli`, `copilot`            |
| Community    | Third-party contributions | Various                            |

All modules use the same source format:

```tf
source = "<your-artifactory-host>/<namespace>/<module>/coder"
```

## Troubleshooting

### Module not found errors

Verify your `.terraformrc` includes both the `host` block with `services` and
the `credentials` block. The `host.services` configuration is required for
Artifactory.

### 401 Unauthorized errors

Check that your Artifactory token is valid and has read access to the
`coder-registry` repository.

### Modules not caching

Ensure the remote repository URL is set to `https://registry.coder.com` and not other paths.

## Next Steps

- [Coder Module Registry](https://registry.coder.com/modules)
- [JFrog Terraform Registry Documentation](https://jfrog.com/help/r/jfrog-artifactory-documentation/terraform-registry)
- [Air-gapped Deployments](./airgap.md)

---

# Istio Integration

Source: https://coder.com/docs/admin/integrations/istio

# Integrate Coder with Istio

Use Istio service mesh for your Coder workspace traffic to implement access
controls, encrypt service-to-service communication, and gain visibility into
your workspace network patterns. This guide walks through the required steps to
configure the Istio service mesh for use with Coder.

While Istio is platform-independent, this guide assumes you are leveraging
Kubernetes. Ensure you have a running Kubernetes cluster with both Coder and
Istio installed, and that you have administrative access to configure both
systems. Once you have access to your Coder cluster, apply the following
manifest:

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: tailscale-behind-istio-ingress
  namespace: istio-system
spec:
  configPatches:
    - applyTo: NETWORK_FILTER
      match:
        listener:
          filterChain:
            filter:
              name: envoy.filters.network.http_connection_manager
      patch:
        operation: MERGE
        value:
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
            upgrade_configs:
              - upgrade_type: derp
```

---

# Island Secure Browser Integration

Source: https://coder.com/docs/admin/integrations/island

# Island Browser Integration

<div>
  <a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Eric Paulsen</span>
  </a>
</div>
April 24, 2024

---

[Island](https://www.island.io/) is an enterprise-grade browser, offering a Chromium-based experience
similar to popular web browsers like Chrome and Edge. It includes built-in
security features for corporate applications and data, aiming to bridge the gap
between consumer-focused browsers and the security needs of the enterprise.

Coder natively integrates with Island's feature set, which include data
loss protection (DLP), application awareness, browser session recording, and
single sign-on (SSO). This guide intends to document these feature categories
and how they apply to your Coder deployment.

## General Configuration

### Create an Application Group for Coder

We recommend creating an Application Group specific to Coder in the Island
Management console. This Application Group object will be referenced when
creating browser policies.

[See the Island documentation for creating an Application Group](https://documentation.island.io/docs/create-and-configure-an-application-group-object).

## Advanced Data Loss Protection

Integrate Island's advanced data loss prevention (DLP) capabilities with
Coder's cloud development environment (CDE), enabling you to control the
"last mile" between developers' CDE and their local devices,
ensuring that sensitive IP remains in your centralized environment.

### Block cut, copy, paste, printing, screen share

1. [Create a Data Sandbox Profile](https://documentation.island.io/docs/create-and-configure-a-data-sandbox-profile).

1. Configure the following actions to allow/block (based on your security
   requirements).

   - Screenshot and Screen Share
   - Printing
   - Save Page
   - Clipboard Limitations

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Data Sandbox Profile.

1. Define the Coder Application group as the Destination Object.

1. Define the Data Sandbox Profile as the Action in the Last Mile Protection
   section.

### Conditionally allow copy on Coder's CLI authentication page

1. [Create a URL Object](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) with the following configuration.

   - **Include**
   - **URL type**: Wildcard
   - **URL address**: `coder.example.com/cli-auth`
   - **Casing**: Insensitive

1. [Create a Data Sandbox Profile](https://documentation.island.io/docs/create-and-configure-a-data-sandbox-profile).

1. Configure action to allow copy/paste.

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Data Sandbox Profile.

1. Define the URL Object you created as the Destination Object.

1. Define the Data Sandbox Profile as the Action in the Last Mile Protection
   section.

### Prevent file upload/download from the browser

1. Create a Protection Profiles for both upload/download.

   - [Upload documentation](https://documentation.island.io/docs/create-and-configure-an-upload-protection-profile)
   - [Download documentation](https://documentation.island.io/v1/docs/en/create-and-configure-a-download-protection-profile)

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Protection Profiles.

1. Define the Coder Application group as the Destination Object.

1. Define the applicable Protection Profile as the Action in the Data Protection
   section.

### Scan files for sensitive data

1. [Create a Data Loss Prevention scanner](https://documentation.island.io/docs/create-a-data-loss-prevention-scanner).

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the DLP Scanner.

1. Define the Coder Application group as the Destination Object.

1. Define the DLP Scanner as the Action in the Data Protection section.

## Application Awareness and Boundaries

Ensure that Coder is only accessed through the Island browser, guaranteeing that
your browser-level DLP policies are always enforced, and developers can't
sidestep such policies simply by using another browser.

### Configure browser enforcement, conditional access policies

Create a conditional access policy for your configured identity provider.

Note that the configured IdP must be the same for both Coder and Island.

- [Azure Active Directory/Entra ID](https://documentation.island.io/docs/configure-browser-enforcement-for-island-with-azure-ad#create-and-apply-a-conditional-access-policy)
- [Okta](https://documentation.island.io/docs/configure-browser-enforcement-for-island-with-okta)
- [Google](https://documentation.island.io/docs/configure-browser-enforcement-for-island-with-google-enterprise)

## Browser Activity Logging

Govern and audit in-browser terminal and IDE sessions using Island, such as
screenshots, mouse clicks, and keystrokes.

### Activity Logging Module

1. [Create an Activity Logging Profile](https://documentation.island.io/docs/create-and-configure-an-activity-logging-profile). Supported browser
   events include:

   - Web Navigation
   - File Download
   - File Upload
   - Clipboard/Drag & Drop
   - Print
   - Save As
   - Screenshots
   - Mouse Clicks
   - Keystrokes

1. [Create a Policy Rule](https://documentation.island.io/docs/create-and-configure-a-policy-rule-general) to apply the Activity Logging Profile.

1. Define the Coder Application group as the Destination Object.

1. Define the Activity Logging Profile as the Action in the Security &
   Visibility section.

## Identity-aware logins (SSO)

Integrate Island's identity management system with Coder's
authentication mechanisms to enable identity-aware logins.

### Configure single sign-on (SSO) seamless authentication between Coder and Island

Configure the same identity provider (IdP) for both your Island and Coder
deployment. Upon initial login to the Island browser, the user's session
token will automatically be passed to Coder and authenticate their Coder
session.

---

# Template ImagePullSecrets

Source: https://coder.com/docs/tutorials/image-pull-secret

# Defining ImagePullSecrets for Coder workspaces

<div>
  <a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Eric Paulsen</span>
  </a>
</div>
January 12, 2024

---

Coder workspaces are commonly run as Kubernetes pods. When run inside of an
enterprise, the pod image is typically pulled from a private image registry.
This guide walks through creating an ImagePullSecret to use for authenticating
to your registry, and defining it in your workspace template.

## 1. Create Docker Config JSON File

Create a Docker configuration JSON file containing your registry credentials.
Replace `<your-registry>`, `<your-username>`, and `<your-password>` with your
actual Docker registry URL, username, and password.

```json
{
    "auths": {
        "<your-registry>": {
            "username": "<your-username>",
            "password": "<your-password>"
        }
    }
}
```

## 2. Create Kubernetes Secret

Run the below `kubectl` command in the K8s cluster where you intend to run your
Coder workspaces:

```console
kubectl create secret generic regcred \
  --from-file=.dockerconfigjson=<path-to-docker-config.json> \
  --type=kubernetes.io/dockerconfigjson \
  --namespace=<workspaces-namespace>
```

Inspect the secret to confirm its contents:

```console
kubectl get secret -n <workspaces-namespace> regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
```

The output should look similar to this:

```json
{
    "auths": {
        "your.private.registry.com": {
            "username": "ericpaulsen",
            "password": "xxxx",
            "auth": "c3R...zE2"
        }
    }
}
```

## 3. Define ImagePullSecret in Terraform template

With the ImagePullSecret now created, we can add the secret into the workspace
template. In the example below, we define the secret via the
`image_pull_secrets` argument. Note that this argument is nested at the same
level as the `container` argument:

```tf
resource "kubernetes_pod" "dev" {
  metadata {
    # this must be the same namespace where workspaces will be deployed
    namespace = "workspaces-namespace"
  }

  spec {
    image_pull_secrets {
      name = "regcred"
    }
    container {
      name  = "dev"
      image = "your-image:latest"
    }
  }
}
```

## 4. Push New Template Version

Update your template by running the following commands:

```console
coder login <access-url>
coder templates push <template-name>
```

---

# Postgres SSL

Source: https://coder.com/docs/tutorials/postgres-ssl

# Configure Coder to connect to PostgreSQL using SSL

<div>
  <a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Eric Paulsen</span>
  </a>
</div>
February 24, 2024

---

Your organization may require connecting to the database instance over SSL. To
supply Coder with the appropriate certificates, and have it connect over SSL,
follow the steps below:

## Client verification (server verifies the client)

1. Create the certificate as a secret in your Kubernetes cluster, if not already
   present:

```shell
kubectl create secret tls postgres-certs -n coder --key="postgres.key" --cert="postgres.crt"
```

1. Define the secret volume and volumeMounts in the Helm chart:

```yaml
coder:
  volumes:
    - name: "pg-certs-mount"
      secret:
        secretName: "postgres-certs"
  volumeMounts:
    - name: "pg-certs-mount"
      mountPath: "$HOME/.postgresql"
      readOnly: true
```

1. Lastly, your PG connection URL will look like:

```shell
postgres://<user>:<password>@databasehost:<port>/<db-name>?sslmode=require&sslcert="$HOME/.postgresql/postgres.crt&sslkey=$HOME/.postgresql/postgres.key"
```

## Server verification (client verifies the server)

1. Download the CA certificate chain for your database instance, and create it
   as a secret in your Kubernetes cluster, if not already present:

```shell
kubectl create secret tls postgres-certs -n coder --key="postgres-root.key" --cert="postgres-root.crt"
```

1. Define the secret volume and volumeMounts in the Helm chart:

```yaml
coder:
  volumes:
    - name: "pg-certs-mount"
      secret:
        secretName: "postgres-certs"
  volumeMounts:
    - name: "pg-certs-mount"
      mountPath: "$HOME/.postgresql/postgres-root.crt"
      readOnly: true
```

1. Lastly, your PG connection URL will look like:

```shell
postgres://<user>:<password>@databasehost:<port>/<db-name>?sslmode=verify-full&sslrootcert="/home/coder/.postgresql/postgres-root.crt"
```

More information on connecting to PostgreSQL databases using certificates can
be found in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-CLIENTCERT).

---

# Azure Federation

Source: https://coder.com/docs/tutorials/azure-federation

# Federating Coder's control plane to Azure

<div>
  <a href="https://github.com/ericpaulsen" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Eric Paulsen</span>
  </a>
</div>
January 26, 2024

---

This guide will walkthrough how to authenticate a Coder Provisioner to Microsoft
Azure, using a Service Principal with a client certificate. You can use this
guide for authenticating Coder to Azure, regardless of where Coder is run,
either on-premise or in a non-Azure cloud. This method is one of several
[recommended by Terraform](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure).

## Step 1: Generate Client Certificate & PKCS bundle

We'll need to create the certificate Coder will use for authentication. Run the
below command to generate a private key and self-signed certificate:

```console
openssl req -subj '/CN=myclientcertificate/O=MyCompany, Inc./ST=CA/C=US' \
  -new -newkey rsa:4096 -sha256 -days 730 -nodes -x509 -keyout client.key -out client.crt
```

Next, generate a `.pfx` file to be used by Coder's Provisioner to authenticate
the AzureRM provider:

```console
openssl pkcs12 -export -password pass:"Pa55w0rd123" -out client.pfx -inkey client.key -in client.crt
```

## Step 2: Create Azure Application & Service Principal

Navigate to the Azure portal, and into the Microsoft Entra ID section. Select
the App Registration blade, and register a new application. Fill in the
following fields:

- **Name**: this is a friendly identifier and can be anything (e.g. "Coder")
- **Supported Account Types**: - set to "Accounts in this organizational
  directory only (single-tenant)"

The **Redirect URI** field does not need to be set in this case. Take note of
the `Application (client) ID` and `Directory (tenant) ID` values, which will be
used by Coder.

## Step 3: Assign Client Certificate to the Azure Application

To upload the certificate we created in Step 1, select **Certificates &
secrets** on the left-hand side, and select **Upload Certificate**. Upload the
public key file, which is `service-principal.crt` from the example above.

## Step 4: Set Permissions on the Service Principal

Now that the Application is created in Microsoft Entra ID, we need to assign
permissions to the Service Principal so it can provision Azure resources for
Coder users. Navigate to the Subscriptions blade in the Azure Portal, select the
**Subscription > Access Control (IAM) > Add > Add role assignment**.

Set the **Role** that grants the appropriate permissions to create the Azure
resources you need for your Coder workspaces. `Contributor` will provide
Read/Write on all Subscription resources. For more information on the available
roles, see the
[Microsoft documentation](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles).

## Step 5: Configure Coder to use the Client Certificate

Now that the client certificate is uploaded to Azure, we need to mount the
certificate files into the Coder deployment. If running Coder on Kubernetes, you
will need to create the `.pfx` file as a Kubernetes secret, and mount it into
the Helm chart.

Run the below command to create the secret:

```console
kubectl create secret generic -n coder azure-client-cert-secret --from-file=client.pfx=/path/to/your/client.pfx
```

In addition, create secrets for each of the following values from your Azure
Application:

- Client ID
- Tenant ID
- Subscription ID
- Certificate password

Next, set the following values in Coder's Helm chart:

```yaml
coder:
  env:
    - name: ARM_CLIENT_ID
      valueFrom:
        secretKeyRef:
          key: id
          name: arm-client-id
    - name: ARM_CLIENT_CERTIFICATE_PATH
      value: /home/coder/az/
    - name: ARM_CLIENT_CERTIFICATE_PASSWORD
      valueFrom:
        secretKeyRef:
          key: password
          name: arm-client-cert-password
    - name: ARM_TENANT_ID
      valueFrom:
        secretKeyRef:
          key: id
          name: arm-tenant-id
    - name: ARM_SUBSCRIPTION_ID
      valueFrom:
        secretKeyRef:
          key: id
          name: arm-subscription-id
  volumes:
    - name: "azure-client-cert"
      secret:
        secretName: "azure-client-cert-secret"
  volumeMounts:
    - name: "azure-client-cert"
      mountPath: "/home/coder/az/"
      readOnly: true
```

Upgrade the Coder deployment using the following `helm` command:

```console
helm upgrade coder coder-v2/coder -n coder -f values.yaml
```

---

# Deploy Coder on Azure with an Application Gateway

Source: https://coder.com/docs/install/kubernetes/kubernetes-azure-app-gateway

# Deploy Coder on Azure with an Application Gateway

In certain enterprise environments, the [Azure Application Gateway](https://learn.microsoft.com/en-us/azure/application-gateway/ingress-controller-overview) is required.

These steps serve as a proof-of-concept example so that you can get Coder running with Kubernetes on Azure. Your deployment might require a separate Postgres server or signed certificates.

The Application Gateway supports:

- Websocket traffic (required for workspace connections)
- TLS termination

Refer to Microsoft's documentation on how to [enable application gateway ingress controller add-on for an existing AKS cluster with an existing application gateway](https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-existing).
The steps here follow the Microsoft tutorial for a Coder deployment.

## Deploy Coder on Azure with an Application Gateway

1. Create Azure resource group:

   ```sql
   az group create --name myResourceGroup --location eastus
   ```

1. Create AKS cluster:

   ```sql
   az aks create --name myCluster --resource-group myResourceGroup --network-plugin azure --enable-managed-identity --generate-ssh-keys
   ```

1. Create public IP:

   ```sql
   az network public-ip create --name myPublicIp --resource-group myResourceGroup --allocation-method Static --sku Standard
   ```

1. Create VNet and subnet:

   ```sql
   az network vnet create --name myVnet --resource-group myResourceGroup --address-prefix 10.0.0.0/16 --subnet-name mySubnet --subnet-prefix 10.0.0.0/24
   ```

1. Create Azure application gateway, attach VNet, subnet and public IP:

   ```sql
   az network application-gateway create --name myApplicationGateway --resource-group myResourceGroup --sku Standard_v2 --public-ip-address myPublicIp --vnet-name myVnet --subnet mySubnet --priority 100
   ```

1. Get app gateway ID:

   ```sql
   appgwId=$(az network application-gateway show --name myApplicationGateway --resource-group myResourceGroup -o tsv --query "id")
   ```

1. Enable app gateway ingress to AKS cluster:

   ```sql
   az aks enable-addons --name myCluster --resource-group myResourceGroup --addon ingress-appgw --appgw-id $appgwId
   ```

1. Get AKS node resource group:

   ```sql
   nodeResourceGroup=$(az aks show --name myCluster --resource-group myResourceGroup -o tsv --query "nodeResourceGroup")
   ```

1. Get AKS VNet name:

   ```sql
   aksVnetName=$(az network vnet list --resource-group $nodeResourceGroup -o tsv --query "[0].name")
   ```

1. Get AKS VNet ID:

   ```sql
   aksVnetId=$(az network vnet show --name $aksVnetName --resource-group $nodeResourceGroup -o tsv --query "id")
   ```

1. Peer VNet to AKS VNet:

   ```sql
   az network vnet peering create --name AppGWtoAKSVnetPeering --resource-group myResourceGroup --vnet-name myVnet --remote-vnet $aksVnetId --allow-vnet-access
   ```

1. Get app gateway VNet ID:

   ```sql
   appGWVnetId=$(az network vnet show --name myVnet --resource-group myResourceGroup -o tsv --query "id")
   ```

1. Peer AKS VNet to app gateway VNet:

   ```sql
   az network vnet peering create --name AKStoAppGWVnetPeering --resource-group $nodeResourceGroup --vnet-name $aksVnetName --remote-vnet $appGWVnetId --allow-vnet-access
   ```

1. Get AKS credentials:

   ```sql
   az aks get-credentials --name myCluster --resource-group myResourceGroup
   ```

1. Create Coder namespace:

   ```shell
   kubectl create ns coder
   ```

1. Deploy non-production PostgreSQL instance to AKS cluster:

   ```shell
   helm repo add bitnami https://charts.bitnami.com/bitnami
   helm install coder-db bitnami/postgresql \
   --set image.repository=bitnamilegacy/postgresql \
   --namespace coder \
   --set auth.username=coder \
   --set auth.password=coder \
   --set auth.database=coder \
   --set persistence.size=10Gi
   ```

1. Create the PostgreSQL secret:

   ```shell
   kubectl create secret generic coder-db-url -n coder --from-literal=url="postgres://coder:coder@coder-db-postgresql.coder.svc.cluster.local:5432/coder?sslmode=disable"
   ```

1. Deploy Coder to AKS cluster:

   ```shell
   helm repo add coder-v2 https://helm.coder.com/v2
   helm install coder coder-v2/coder \
       --namespace coder \
    --values values.yaml \
    --version 2.25.2
   ```

1. Clean up Azure resources:

   ```sql
   az group delete --name myResourceGroup
   az group delete --name MC_myResourceGroup_myCluster_eastus
   ```

1. Deploy the gateway - this needs clarification

1. After you deploy the gateway, add the following entries to Helm's `values.yaml` file before you deploy Coder:

   ```yaml
     service:
       enable: true
       type: ClusterIP
       sessionAffinity: None
       externalTrafficPolicy: Cluster
       loadBalancerIP: ""
       annotations: {}
       httpNodePort: ""
       httpsNodePort: ""

     ingress:
       enable: true
       className: "azure-application-gateway"
       host: ""
       wildcardHost: ""
       annotations: {}
       tls:
         enable: false
         secretName: ""
         wildcardSecretName: ""
   ```

---

# Cloning Git Repositories

Source: https://coder.com/docs/tutorials/cloning-git-repositories

# Cloning Git Repositories

<div style="padding: 0px; margin: 0px;">
  <span style="vertical-align:middle;">Author: </span>
  <a href="https://github.com/BrunoQuaresma" style="text-decoration: none; color: inherit; margin-bottom: 0px;">
    <span style="vertical-align:middle;">Bruno Quaresma</span>
  </a>
</div>
August 06, 2024

---

When starting to work on a project, engineers usually need to clone a Git
repository. Even though this is often a quick step, it can be automated using
the [Coder Registry](https://registry.coder.com/) to make a seamless Git-first
workflow.

The first step to enable Coder to clone a repository is to provide
authorization. This can be achieved by using the Git provider, such as GitHub,
as an authentication method. If you don't know how to do that, we have written
documentation to help you:

- [GitHub](../admin/external-auth/index.md#github)
- [GitLab self-managed](../admin/external-auth/index.md#gitlab-self-managed)
- [Self-managed git providers](../admin/external-auth/index.md#self-managed-git-providers)

With the authentication in place, it is time to set up the template to use the
[Git Clone module](https://registry.coder.com/modules/git-clone) from the
[Coder Registry](https://registry.coder.com/) by adding it to our template's
Terraform configuration.

```tf
module "git-clone" {
  source   = "registry.coder.com/modules/git-clone/coder"
  version  = "1.0.12"
  agent_id = coder_agent.example.id
  url      = "https://github.com/coder/coder"
}
```

You can edit the template using an IDE or terminal of your preference, or by
going into the
[template editor UI](../admin/templates/creating-templates.md#web-ui).

You can also use
[template parameters](../admin/templates/extending-templates/parameters.md) to
customize the Git URL and make it dynamic for use cases where a template
supports multiple projects.

```tf
data "coder_parameter" "git_repo" {
  name         = "git_repo"
  display_name = "Git repository"
  default      = "https://github.com/coder/coder"
}

module "git-clone" {
  source   = "registry.coder.com/modules/git-clone/coder"
  version  = "1.0.12"
  agent_id = coder_agent.example.id
  url      = data.coder_parameter.git_repo.value
}
```

If you need more customization, you can read the
[Git Clone module](https://registry.coder.com/modules/git-clone) documentation
to learn more about the module.

Don't forget to build and publish the template changes before creating a new
workspace. You can check if the repository is cloned by accessing the workspace
terminal and listing the directories.

---

# Test Templates Through CI/CD

Source: https://coder.com/docs/tutorials/testing-templates

# Test and Publish Coder Templates Through CI/CD

<div>
  <a href="https://github.com/matifali" style="text-decoration: none; color: inherit;">
    <span style="vertical-align:middle;">Muhammad Atif Ali</span>
  </a>
</div>
November 15, 2024

---

## Overview

This guide demonstrates how to test and publish Coder templates in a Continuous
Integration (CI) pipeline using the
[coder/setup-action](https://github.com/coder/setup-coder). This workflow
ensures your templates are validated, tested, and promoted seamlessly.

## Prerequisites

- Install and configure Coder CLI in your environment.
- Install Terraform CLI in your CI environment.
- Create a [headless user](../admin/users/headless-auth.md) with the
  [user roles and permissions](../admin/users/groups-roles.md#roles) to manage
  templates and run workspaces.

## Creating the headless user

> [!WARNING]
> Creating users with `--login-type none` is deprecated.
> For [Premium](https://coder.com/pricing) deployments, use
> [service accounts](../admin/users/headless-auth.md) instead.
> For OSS deployments, use a regular account with password, GitHub, or OIDC
> authentication.

For Premium deployments, create a service account:

```shell
coder users create \
  --username machine-user \
  --service-account

coder tokens create --user machine-user --lifetime 8760h
# Copy the token and store it in a secret in your CI environment with the name `CODER_SESSION_TOKEN`
```

For OSS deployments, create a regular user:

```shell
coder users create \
  --username machine-user \
  --email machine-user@example.com \
  --login-type password

coder tokens create --user machine-user --lifetime 8760h
# Copy the token and store it in a secret in your CI environment with the name `CODER_SESSION_TOKEN`
```

## Example GitHub Action Workflow

This example workflow tests and publishes a template using GitHub Actions.

The workflow:

1. Validates the Terraform template.
1. Pushes the template to Coder without activating it.
1. Tests the template by creating a workspace.
1. Promotes the template version to active upon successful workspace creation.

### Workflow File

Save the following workflow file as `.github/workflows/publish-template.yaml` in
your repository:

```yaml
name: Test and Publish Coder Template

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  test-and-publish:
    runs-on: ubuntu-latest
    env:
      TEMPLATE_NAME: "my-template"
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: latest

      - name: Set up Coder CLI
        uses: coder/setup-action@v1
        with:
          access_url: "https://coder.example.com"
          coder_session_token: ${{ secrets.CODER_SESSION_TOKEN }}

      - name: Validate Terraform template
        run: terraform validate

      - name: Get short commit SHA to use as template version name
        id: name
        run: echo "version_name=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"

      - name: Get latest commit title to use as template version description
        id: message
        run:
          echo "pr_title=$(git log --format=%s -n 1 ${{ github.sha }})" >>
          $GITHUB_OUTPUT

      - name: Push template to Coder
        run: |
          coder templates push $TEMPLATE_NAME --activate=false --name ${{ steps.name.outputs.version_name }} --message "${{ steps.message.outputs.pr_title }}" --yes

      - name: Create a test workspace and run some example commands
        run: |
          coder create -t $TEMPLATE_NAME --template-version ${{ steps.name.outputs.version_name }} test-${{ steps.name.outputs.version_name }} --yes
          # run some example commands
          coder ssh test-${{ steps.name.outputs.version_name }} -- make build

      - name: Delete the test workspace
        if: always()
        run: coder delete test-${{ steps.name.outputs.version_name }} --yes

      - name: Promote template version
        if: success()
        run: |
          coder template version promote --template=$TEMPLATE_NAME --template-version=${{ steps.name.outputs.version_name }} --yes
```

---

# Use Apache as a Reverse Proxy

Source: https://coder.com/docs/tutorials/reverse-proxy-apache

# How to use Apache as a reverse-proxy with LetsEncrypt

## Requirements

1. Start a Coder deployment and be sure to set the following
   [configuration values](../admin/setup/index.md):

   ```env
   CODER_HTTP_ADDRESS=127.0.0.1:3000
   CODER_ACCESS_URL=https://coder.example.com
   CODER_WILDCARD_ACCESS_URL=*coder.example.com
   ```

   Throughout the guide, be sure to replace `coder.example.com` with the domain
   you intend to use with Coder.

2. Configure your DNS provider to point your coder.example.com and
   \*.coder.example.com to your server's public IP address.

   > For example, to use `coder.example.com` as your subdomain, configure
   > `coder.example.com` and `*.coder.example.com` to point to your server's
   > public ip. This can be done by adding A records in your DNS provider's
   > dashboard.

3. Install Apache (assuming you're on Debian/Ubuntu):

   ```shell
   sudo apt install apache2
   ```

4. Enable the following Apache modules:

   ```shell
   sudo a2enmod proxy
   sudo a2enmod proxy_http
   sudo a2enmod ssl
   sudo a2enmod rewrite
   ```

5. Stop Apache service and disable default site:

   ```shell
   sudo a2dissite 000-default.conf
   sudo systemctl stop apache2
   ```

## Install and configure LetsEncrypt Certbot

1. Install LetsEncrypt Certbot: Refer to the
   [CertBot documentation](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal&tab=wildcard).
   Be sure to pick the wildcard tab and select your DNS provider for
   instructions to install the necessary DNS plugin.

## Create DNS provider credentials

This example assumes you're using CloudFlare as your DNS provider. For other
providers, refer to the
[CertBot documentation](https://eff-certbot.readthedocs.io/en/stable/using.html#dns-plugins).

1. Create an API token for the DNS provider you're using: e.g.
   [CloudFlare](https://developers.cloudflare.com/fundamentals/api/get-started/create-token)
   with the following permissions:

   - Zone - DNS - Edit

2. Create a file in `.secrets/certbot/cloudflare.ini` with the following
   content:

   ```ini
   dns_cloudflare_api_token = YOUR_API_TOKEN
   ```

   ```shell
   mkdir -p ~/.secrets/certbot
   touch ~/.secrets/certbot/cloudflare.ini
   nano ~/.secrets/certbot/cloudflare.ini
   ```

3. Set the correct permissions:

   ```shell
   sudo chmod 600 ~/.secrets/certbot/cloudflare.ini
   ```

## Create the certificate

1. Create the wildcard certificate:

   ```shell
   sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -d coder.example.com -d *.coder.example.com
   ```

## Configure Apache

This example assumes Coder is running locally on `127.0.0.1:3000` and that
you're using `coder.example.com` as your subdomain.

1. Create Apache configuration for Coder:

   ```shell
   sudo nano /etc/apache2/sites-available/coder.conf
   ```

2. Add the following content:

   ```apache
    # Redirect HTTP to HTTPS
    <VirtualHost *:80>
        ServerName coder.example.com
        ServerAlias *.coder.example.com
        Redirect permanent / https://coder.example.com/
    </VirtualHost>

    <VirtualHost *:443>
        ServerName coder.example.com
        ServerAlias *.coder.example.com
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        ProxyPass / http://127.0.0.1:3000/ upgrade=any # required for websockets
        ProxyPassReverse / http://127.0.0.1:3000/
        ProxyRequests Off
        ProxyPreserveHost On

        RewriteEngine On
        # Websockets are required for workspace connectivity
        RewriteCond %{HTTP:Connection} Upgrade [NC]
        RewriteCond %{HTTP:Upgrade} websocket [NC]
        RewriteRule /(.*) ws://127.0.0.1:3000/$1 [P,L]

        SSLCertificateFile /etc/letsencrypt/live/coder.example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/coder.example.com/privkey.pem
    </VirtualHost>
   ```

   > Don't forget to change: `coder.example.com` by your (sub)domain

3. Enable the site:

   ```shell
   sudo a2ensite coder.conf
   ```

4. Restart Apache:

   ```shell
   sudo systemctl restart apache2
   ```

## Refresh certificates automatically

1. Create a new file in `/etc/cron.weekly`:

   ```shell
   sudo touch /etc/cron.weekly/certbot
   ```

2. Make it executable:

   ```shell
   sudo chmod +x /etc/cron.weekly/certbot
   ```

3. And add this code:

   ```shell
   #!/bin/sh
   sudo certbot renew -q
   ```

And that's it, you should now be able to access Coder at your sub(domain) e.g.
`https://coder.example.com`.

---

# Use Caddy as a Reverse Proxy

Source: https://coder.com/docs/tutorials/reverse-proxy-caddy

# Caddy

This is an example configuration of how to use Coder with
[caddy](https://caddyserver.com/docs). To use Caddy to generate TLS
certificates, you'll need a domain name that resolves to your Caddy server.

## Getting started

### With `docker compose`

1. [Install Docker](https://docs.docker.com/engine/install/) and
   [Docker Compose](https://docs.docker.com/compose/install/)

2. Create a `compose.yaml` file and add the following:

   ```yaml
   services:
   coder:
       image: ghcr.io/coder/coder:${CODER_VERSION:-latest}
       environment:
           CODER_PG_CONNECTION_URL: "postgresql://${POSTGRES_USER:-username}:${POSTGRES_PASSWORD:-password}@database/${POSTGRES_DB:-coder}?sslmode=disable"
           CODER_HTTP_ADDRESS: "0.0.0.0:7080"
           # You'll need to set CODER_ACCESS_URL to an IP or domain
           # that workspaces can reach. This cannot be localhost
           # or 127.0.0.1 for non-Docker templates!
           CODER_ACCESS_URL: "${CODER_ACCESS_URL}"
           # Optional) Enable wildcard apps/dashboard port forwarding
           CODER_WILDCARD_ACCESS_URL: "${CODER_WILDCARD_ACCESS_URL}"
           # If the coder user does not have write permissions on
           # the docker socket, you can uncomment the following
           # lines and set the group ID to one that has write
           # permissions on the docker socket.
           #group_add:
           #  - "998" # docker group on host
       volumes:
           - /var/run/docker.sock:/var/run/docker.sock
       depends_on:
           database:
           condition: service_healthy

   database:
       image: "postgres:17"
       ports:
           - "5432:5432"
       environment:
           POSTGRES_USER: ${POSTGRES_USER:-username} # The PostgreSQL user (useful to connect to the database)
           POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password} # The PostgreSQL password (useful to connect to the database)
           POSTGRES_DB: ${POSTGRES_DB:-coder} # The PostgreSQL default database (automatically created at first launch)
       volumes:
           - coder_data:/var/lib/postgresql/data # Use "docker volume rm coder_coder_data" to reset Coder
       healthcheck:
           test:
           [
               "CMD-SHELL",
               "pg_isready -U ${POSTGRES_USER:-username} -d ${POSTGRES_DB:-coder}",
           ]
           interval: 5s
           timeout: 5s
           retries: 5

   caddy:
       image: caddy:2.6.2
       ports:
           - "80:80"
           - "443:443"
           - "443:443/udp"
       volumes:
           - $PWD/Caddyfile:/etc/caddy/Caddyfile
           - caddy_data:/data
           - caddy_config:/config

   volumes:
       coder_data:
       caddy_data:
       caddy_config:
   ```

3. Create a `Caddyfile` and add the following:

   ```caddyfile
   {
       on_demand_tls {
           ask http://example.com
       }
   }

   coder.example.com, *.coder.example.com {
     reverse_proxy coder:7080
     tls {
           on_demand
         issuer acme {
            email email@example.com
         }
         }
   }
   ```

   Here;

   - `coder:7080` is the address of the Coder container on the Docker network.
   - `coder.example.com` is the domain name you're using for Coder.
   - `*.coder.example.com` is the domain name for wildcard apps, commonly used
     for [dashboard port forwarding](../admin/networking/port-forwarding.md).
     This is optional and can be removed.
   - `email@example.com`: Email to request certificates from LetsEncrypt/ZeroSSL
     (does not have to be Coder admin email)

4. Start Coder. Set `CODER_ACCESS_URL` and `CODER_WILDCARD_ACCESS_URL` to the
   domain you're using in your Caddyfile.

   ```shell
   export CODER_ACCESS_URL=https://coder.example.com
   export CODER_WILDCARD_ACCESS_URL=*.coder.example.com
   docker compose up -d # Run on startup
   ```

### Standalone

1. If you haven't already, [install Coder](../install/index.md)

2. Install [Caddy Server](https://caddyserver.com/docs/install)

3. Copy our sample `Caddyfile` and change the following values:

   ```caddyfile
   {
       on_demand_tls {
           ask http://example.com
       }
   }

   coder.example.com, *.coder.example.com {
     reverse_proxy coder:7080
   }
   ```

   > If you're installed Caddy as a system package, update the default Caddyfile
   > with `vim /etc/caddy/Caddyfile`

   - `email@example.com`: Email to request certificates from LetsEncrypt/ZeroSSL
     (does not have to be Coder admin email)
   - `coder.example.com`: Domain name you're using for Coder.
   - `*.coder.example.com`: Domain name for wildcard apps, commonly used for
     [dashboard port forwarding](../admin/networking/port-forwarding.md). This
     is optional and can be removed.
   - `localhost:3000`: Address Coder is running on. Modify this if you changed
     `CODER_HTTP_ADDRESS` in the Coder configuration.
   - _DO NOT CHANGE the `ask http://example.com` line! Doing so will result in
     your certs potentially not being generated._

4. [Configure Coder](../admin/setup/index.md) and change the following values:

   - `CODER_ACCESS_URL`: root domain (e.g. `https://coder.example.com`)
   - `CODER_WILDCARD_ACCESS_URL`: wildcard domain (e.g. `*.example.com`).

5. Start the Caddy server:

   If you're [keeping Caddy running](https://caddyserver.com/docs/running) via a
   system service:

   ```shell
   sudo systemctl restart caddy
   ```

   Or run a standalone server:

   ```shell
   caddy run
   ```

6. Optionally, use [ufw](https://wiki.ubuntu.com/UncomplicatedFirewall) or
   another firewall to disable external traffic outside of Caddy.

   ```shell
   # Check status of UncomplicatedFirewall
   sudo ufw status

   # Allow SSH
   sudo ufw allow 22

   # Allow HTTP, HTTPS (Caddy)
   sudo ufw allow 80
   sudo ufw allow 443

   # Deny direct access to Coder server
   sudo ufw deny 3000

   # Enable UncomplicatedFirewall
   sudo ufw enable
   ```

7. Navigate to your Coder URL! A TLS certificate should be auto-generated on
   your first visit.

## Generating wildcard certificates

By default, this configuration uses Caddy's
[on-demand TLS](https://caddyserver.com/docs/caddyfile/options#on-demand-tls) to
generate a certificate for each subdomain (e.g. `app1.coder.example.com`,
`app2.coder.example.com`). When users visit new subdomains, such as accessing
[ports on a workspace](../admin/networking/port-forwarding.md), the request will
take an additional 5-30 seconds since a new certificate is being generated.

For production deployments, we recommend configuring Caddy to generate a
wildcard certificate, which requires an explicit DNS challenge and additional
Caddy modules.

1. Install a custom Caddy build that includes the
   [caddy-dns](https://github.com/caddy-dns) module for your DNS provider (e.g.
   CloudFlare, Route53).

   - Docker:
     [Build an custom Caddy image](https://github.com/docker-library/docs/tree/master/caddy#adding-custom-caddy-modules)
     with the module for your DNS provider. Be sure to reference the new image
     in the `compose.yaml`.

   - Standalone:
     [Download a custom Caddy build](https://caddyserver.com/download) with the
     module for your DNS provider. If you're using Debian/Ubuntu, you
     [can configure the Caddy package](https://caddyserver.com/docs/build#package-support-files-for-custom-builds-for-debianubunturaspbian)
     to use the new build.

2. Edit your `Caddyfile` and add the necessary credentials/API tokens to solve
   the DNS challenge for wildcard certificates.

   For example, for AWS Route53:

   ```diff
   tls {
   -  on_demand
   -  issuer acme {
   -      email email@example.com
   -  }

   +  dns route53 {
   +     max_retries 10
   +     aws_profile "real-profile"
   +     access_key_id "AKI..."
   +     secret_access_key "wJa..."
   +     token "TOKEN..."
   +     region "us-east-1"
   +  }
   }
   ```

   > Configuration reference from
   > [caddy-dns/route53](https://github.com/caddy-dns/route53).

   And for CloudFlare:

   Generate a
   [token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token)
   with the following permissions:

   - Zone:Zone:Edit

   ```diff
   tls {
   -  on_demand
   -  issuer acme {
   -      email email@example.com
   -  }

   +  dns cloudflare CLOUDFLARE_API_TOKEN
   }
   ```

   > Configuration reference from
   > [caddy-dns/cloudflare](https://github.com/caddy-dns/cloudflare).

---

# Use NGINX as a Reverse Proxy

Source: https://coder.com/docs/tutorials/reverse-proxy-nginx

# How to use NGINX as a reverse-proxy with LetsEncrypt

## Requirements

1. Start a Coder deployment and be sure to set the following
   [configuration values](../admin/setup/index.md):

   ```env
   CODER_HTTP_ADDRESS=127.0.0.1:3000
   CODER_ACCESS_URL=https://coder.example.com
   CODER_WILDCARD_ACCESS_URL=*.coder.example.com
   ```

   Throughout the guide, be sure to replace `coder.example.com` with the domain
   you intend to use with Coder.

2. Configure your DNS provider to point your coder.example.com and
   \*.coder.example.com to your server's public IP address.

   > For example, to use `coder.example.com` as your subdomain, configure
   > `coder.example.com` and `*.coder.example.com` to point to your server's
   > public ip. This can be done by adding A records in your DNS provider's
   > dashboard.

3. Install NGINX (assuming you're on Debian/Ubuntu):

   ```shell
   sudo apt install nginx
   ```

4. Stop NGINX service:

   ```shell
   sudo systemctl stop nginx
   ```

## Adding Coder deployment subdomain

This example assumes Coder is running locally on `127.0.0.1:3000` and that
you're using `coder.example.com` as your subdomain.

1. Create NGINX configuration for this app:

   ```shell
   sudo touch /etc/nginx/sites-available/coder.example.com
   ```

2. Activate this file:

   ```shell
   sudo ln -s /etc/nginx/sites-available/coder.example.com /etc/nginx/sites-enabled/coder.example.com
   ```

## Install and configure LetsEncrypt Certbot

1. Install LetsEncrypt Certbot: Refer to the
   [CertBot documentation](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal&tab=wildcard).
   Be sure to pick the wildcard tab and select your DNS provider for
   instructions to install the necessary DNS plugin.

## Create DNS provider credentials

This example assumes you're using CloudFlare as your DNS provider. For other
providers, refer to the
[CertBot documentation](https://eff-certbot.readthedocs.io/en/stable/using.html#dns-plugins).

1. Create an API token for the DNS provider you're using: e.g.
   [CloudFlare](https://developers.cloudflare.com/fundamentals/api/get-started/create-token)
   with the following permissions:

   - Zone - DNS - Edit

2. Create a file in `.secrets/certbot/cloudflare.ini` with the following
   content:

   ```ini
   dns_cloudflare_api_token = YOUR_API_TOKEN
   ```

   ```shell
   mkdir -p ~/.secrets/certbot
   touch ~/.secrets/certbot/cloudflare.ini
   nano ~/.secrets/certbot/cloudflare.ini
   ```

3. Set the correct permissions:

   ```shell
   sudo chmod 600 ~/.secrets/certbot/cloudflare.ini
   ```

## Create the certificate

1. Create the wildcard certificate:

   ```shell
   sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -d coder.example.com -d *.coder.example.com
   ```

## Configure nginx

1. Edit the file with:

   ```shell
   sudo nano /etc/nginx/sites-available/coder.example.com
   ```

2. Add the following content:

   ```nginx
   server {
       server_name coder.example.com *.coder.example.com;

       # HTTP configuration
       listen 80;
       listen [::]:80;

       # HTTP to HTTPS
       if ($scheme != "https") {
           return 301 https://$host$request_uri;
       }

       # HTTPS configuration
       listen [::]:443 ssl ipv6only=on;
       listen 443 ssl;
       ssl_certificate /etc/letsencrypt/live/coder.example.com/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/coder.example.com/privkey.pem;

       location / {
           proxy_pass  http://127.0.0.1:3000; # Change this to your coder deployment port default is 3000
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection upgrade;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
           add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
       }
   }
   ```

   > Don't forget to change: `coder.example.com` by your (sub)domain

3. Test the configuration:

   ```shell
   sudo nginx -t
   ```

## Refresh certificates automatically

1. Create a new file in `/etc/cron.weekly`:

   ```shell
   sudo touch /etc/cron.weekly/certbot
   ```

2. Make it executable:

   ```shell
   sudo chmod +x /etc/cron.weekly/certbot
   ```

3. And add this code:

   ```shell
   #!/bin/sh
   sudo certbot renew -q
   ```

## Restart NGINX

```shell
sudo systemctl restart nginx
```

And that's it, you should now be able to access Coder at your sub(domain) e.g.
`https://coder.example.com`.

---

# Pre-install JetBrains IDEs in Workspaces

Source: https://coder.com/docs/admin/templates/extending-templates/jetbrains-preinstall

# Pre-install JetBrains IDEs in your template

For a faster first time connection with JetBrains IDEs, pre-install the IDEs backend in your template.

> [!NOTE]
> This guide only talks about installing the IDEs backend. For a complete guide on setting up JetBrains Gateway with client IDEs, refer to the [JetBrains Gateway air-gapped guide](./jetbrains-airgapped.md).

## Install the Client Downloader

Install the JetBrains Client Downloader binary:

```shell
wget -O jetbrains-clients-downloader-linux-x86_64.tar.gz \
  'https://data.services.jetbrains.com/products/download?code=JCD&platform=linux_x86-64' && \
tar -xzvf jetbrains-clients-downloader-linux-x86_64.tar.gz
rm jetbrains-clients-downloader-linux-x86_64.tar.gz
```

## Install Gateway backend

```shell
mkdir ~/JetBrains
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64 --download-backends ~/JetBrains
```

For example, to install the build `243.26053.27` of IntelliJ IDEA:

```shell
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter IU --build-filter 243.26053.27 --platforms-filter linux-x64 --download-backends ~/JetBrains
tar -xzvf ~/JetBrains/backends/IU/*.tar.gz -C ~/JetBrains/backends/IU
rm -rf ~/JetBrains/backends/IU/*.tar.gz
```

## Register the Gateway backend

Add the following command to your template's `startup_script`:

```shell
~/JetBrains/*/bin/remote-dev-server.sh registerBackendLocationForGateway
```

## Configure JetBrains Gateway Module

If you are using our [jetbrains-gateway](https://registry.coder.com/modules/coder/jetbrains-gateway) module, you can configure it by adding the following snippet to your template:

```tf
module "jetbrains_gateway" {
  count          = data.coder_workspace.me.start_count
  source         = "registry.coder.com/modules/jetbrains-gateway/coder"
  version        = "1.0.29"
  agent_id       = coder_agent.main.id
  folder         = "/home/coder/example"
  jetbrains_ides = ["IU"]
  default        = "IU"
  latest         = false
  jetbrains_ide_versions = {
    "IU" = {
      build_number = "251.25410.129"
      version      = "2025.1"
    }
  }
}

resource "coder_agent" "main" {
    ...
    startup_script = <<-EOF
    ~/JetBrains/*/bin/remote-dev-server.sh registerBackendLocationForGateway
    EOF
}
```

## Dockerfile example

If you are using Docker based workspaces, you can add the command to your Dockerfile:

```dockerfile
FROM codercom/enterprise-base:ubuntu

# JetBrains IDE installation (configurable)
ARG IDE_CODE=IU
ARG IDE_VERSION=2025.1

# Fetch and install IDE dynamically
RUN mkdir -p ~/JetBrains \
    && IDE_URL=$(curl -s "https://data.services.jetbrains.com/products/releases?code=${IDE_CODE}&majorVersion=${IDE_VERSION}&latest=true" | jq -r ".${IDE_CODE}[0].downloads.linux.link") \
    && IDE_NAME=$(curl -s "https://data.services.jetbrains.com/products/releases?code=${IDE_CODE}&majorVersion=${IDE_VERSION}&latest=true" | jq -r ".${IDE_CODE}[0].name") \
    && echo "Installing ${IDE_NAME}..." \
    && wget -q ${IDE_URL} -P /tmp \
    && tar -xzf /tmp/$(basename ${IDE_URL}) -C ~/JetBrains \
    && rm -f /tmp/$(basename ${IDE_URL}) \
    && echo "${IDE_NAME} installed successfully"
```

## Next steps

- [Pre-install the Client IDEs](./jetbrains-airgapped.md#1-deploy-the-server-and-install-the-client-downloader)

---

# Use JetBrains IDEs in Air-Gapped Deployments

Source: https://coder.com/docs/admin/templates/extending-templates/jetbrains-airgapped

# JetBrains IDEs in an air-gapped environment

In networks that restrict access to the internet, you will need to leverage the
JetBrains Client Installer to download and save the IDE clients locally. Please
see the
[JetBrains documentation for more information](https://www.jetbrains.com/help/idea/fully-offline-mode.html).

This page is an example that the Coder team used as a proof-of-concept (POC) of the JetBrains Gateway Offline Mode solution.

We used Ubuntu on a virtual machine to test the steps.
If you have a suggestion or encounter an issue, please
[file a GitHub issue](https://github.com/coder/coder/issues/new?title=request%28docs%29%3A+jetbrains-airgapped+-+request+title+here%0D%0A&labels=["community","docs"]&body=doc%3A+%5Bjetbrains-airgapped%5D%28https%3A%2F%2Fcoder.com%2Fdocs%2Fuser-guides%2Fworkspace-access%2Fjetbrains%2Fjetbrains-airgapped%29%0D%0A%0D%0Aplease+enter+your+request+here%0D%0A).

## 1. Deploy the server and install the Client Downloader

Install the JetBrains Client Downloader binary. Note that the server must be a Linux-based distribution:

```shell
wget -O jetbrains-clients-downloader-linux-x86_64.tar.gz \
  'https://data.services.jetbrains.com/products/download?code=JCD&platform=linux_x86-64' && \
tar -xzvf jetbrains-clients-downloader-linux-x86_64.tar.gz
```

## 2. Install backends and clients

JetBrains Gateway requires both a backend to be installed on the remote host
(your Coder workspace) and a client to be installed on your local machine. You
can host both on the server in this example.

See here for the full
[JetBrains product list and builds](https://data.services.jetbrains.com/products).
Below is the full list of supported `--platforms-filter` values:

```console
windows-x64, windows-aarch64, linux-x64, linux-aarch64, osx-x64, osx-aarch64
```

To install both backends and clients, you will need to run two commands.

### Backends

```shell
mkdir ~/backends
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64,windows-x64,osx-x64 --download-backends ~/backends
```

### Clients

This is the same command as above, with the `--download-backends` flag removed.

```shell
mkdir ~/clients
./jetbrains-clients-downloader-linux-x86_64-*/bin/jetbrains-clients-downloader --products-filter <product-code> --build-filter <build-number> --platforms-filter linux-x64,windows-x64,osx-x64 ~/clients
```

We now have both clients and backends installed.

## 3. Install a web server

You will need to run a web server in order to serve requests to the backend and
client files. We installed `nginx` and setup an FQDN and routed all requests to
`/`. See below:

```console
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                root /home/ubuntu;
        }
}
```

Then, configure your DNS entry to point to the IP address of the server. For the
purposes of the POC, we did not configure TLS, although that is a supported
option.

## 4. Add Client Files

You will need to add the following files on your local machine in order for
Gateway to pull the backend and client from the server.

```shell
$ cat productsInfoUrl # a path to products.json that was generated by the backend's downloader (it could be http://, https://, or file://)

https://internal.site/backends/<PRODUCT_CODE>/products.json

$ cat clientDownloadUrl # a path for clients that you got from the clients' downloader (it could be http://, https://, or file://)

https://internal.site/clients/

$ cat jreDownloadUrl # a path for JBR that you got from the clients' downloader (it could be http://, https://, or file://)

https://internal.site/jre/

$ cat pgpPublicKeyUrl # a URL to the KEYS file that was downloaded with the clients builds.

https://internal.site/KEYS
```

The location of these files will depend upon your local operating system:

<div class="tabs">

### macOS

```console
# User-specific settings
/Users/UserName/Library/Application Support/JetBrains/RemoteDev
# System-wide settings
/Library/Application Support/JetBrains/RemoteDev/
```

### Linux

```console
# User-specific settings
$HOME/.config/JetBrains/RemoteDev
# System-wide settings
/etc/xdg/JetBrains/RemoteDev/
```

### Windows

```console
# User-specific settings
HKEY_CURRENT_USER registry
# System-wide settings
HKEY_LOCAL_MACHINE registry
```

Additionally, create a string for each setting with its appropriate value in
`SOFTWARE\JetBrains\RemoteDev`:

![JetBrains offline - Windows](../../../images/gateway/jetbrains-offline-windows.png)

</div>

## 5. Setup SSH connection with JetBrains Gateway

With the server now configured, you can now configure your local machine to use
Gateway. Here is the documentation to
[setup SSH config via the Coder CLI](../../../user-guides/workspace-access/index.md#configure-ssh).
On the Gateway side, follow our guide here until step 16.

Instead of downloading from jetbrains.com, we will point Gateway to our server
endpoint. Select `Installation options...` and select `Use download link`. Note
that the URL must explicitly reference the archive file:

![Offline Gateway](../../../images/gateway/offline-gateway.png)

Click `Download IDE and Connect`. Gateway should now download the backend and
clients from the server into your remote workspace and local machine,
respectively.

## Next steps

- [Pre-install the JetBrains IDEs backend in your workspace](./jetbrains-preinstall.md)

---

# FAQs

Source: https://coder.com/docs/tutorials/faqs

# FAQs

Frequently asked questions on Coder OSS and licensed deployments. These FAQs
come from our community and customers, feel free to
[contribute to this page](https://github.com/coder/coder/edit/main/docs/tutorials/faqs.md).

For other community resources, see our
[GitHub discussions](https://github.com/coder/coder/discussions), or join our
[Discord server](https://discord.gg/coder).

## How do I add a Premium trial license?

Visit <https://coder.com/trial> or contact
[sales@coder.com](mailto:sales@coder.com?subject=License) to get a trial key.

<details>

<summary>You can add a license through the UI or CLI</summary>

<!-- copied from docs/admin/licensing/index.md -->

<div class="tabs">

### Coder UI

1. With an `Owner` account, go to **Admin settings** > **Deployment**.

1. Select **Licenses** from the sidebar, then **Add a license**:

   ![Add a license from the licenses screen](../images/admin/licenses/licenses-nolicense.png)

1. On the **Add a license** screen, drag your `.jwt` license file into the
   **Upload Your License** section, or paste your license in the
   **Paste Your License** text box, then select **Upload License**:

   ![Add a license screen](../images/admin/licenses/add-license-ui.png)

### Coder CLI

1. Ensure you have the [Coder CLI](../install/cli.md) installed.
1. Save your license key to disk and make note of the path.
1. Open a terminal.
1. Log in to your Coder deployment:

   ```shell
   coder login <access url>
   ```

1. Run `coder licenses add`:

   - For a `.jwt` license file:

     ```shell
     coder licenses add -f <path to your license key>
     ```

   - For a text string:

     ```sh
     coder licenses add -l 1f5...765
     ```

</div>

</details>

Visit the [licensing documentation](../admin/licensing/index.md) for more
information about licenses.

## I'm experiencing networking issues, so want to disable Tailscale, STUN, Direct connections and force use of websocket

The primary developer use case is a local IDE connecting over SSH to a Coder
workspace.

Coder's networking stack has intelligence to attempt a peer-to-peer or
[Direct connection](../admin/networking/index.md#direct-connections) between the
local IDE and the workspace. However, this requires some additional protocols
like UDP and being able to reach a STUN server to echo the IP addresses of the
local IDE machine and workspace, for sharing using a Wireguard Coordination
Server. By default, Coder assumes Internet and attempts to reach Google's STUN
servers to perform this IP echo.

Operators experimenting with Coder may run into networking issues if UDP (which
STUN requires) or the STUN servers are unavailable, potentially resulting in
lengthy local IDE and SSH connection times as the Coder control plane attempts
to establish these direct connections.

Setting the following flags as shown disables this logic to simplify
troubleshooting.

| Flag                                                                                          | Value       | Meaning                               |
|-----------------------------------------------------------------------------------------------|-------------|---------------------------------------|
| [`CODER_BLOCK_DIRECT`](../reference/cli/server.md#--block-direct-connections)                 | `true`      | Blocks direct connections             |
| [`CODER_DERP_SERVER_STUN_ADDRESSES`](../reference/cli/server.md#--derp-server-stun-addresses) | `"disable"` | Disables STUN                         |
| [`CODER_DERP_FORCE_WEBSOCKETS`](../reference/cli/server.md#--derp-force-websockets)           | `true`      | Forces websockets over Tailscale DERP |

## How do I configure NGINX as the reverse proxy in front of Coder?

[This tutorial](./reverse-proxy-nginx.md) in our docs explains in detail how to
configure NGINX with Coder so that our Tailscale Wireguard networking functions
properly.

## How do I hide some of the default icons in a workspace like VS Code Desktop, Terminal, SSH, Ports?

The visibility of Coder apps is configurable in the template. To change the
default (shows all), add this block inside the
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent)
of a template and configure as needed:

```tf
  display_apps {
    vscode = false
    vscode_insiders = false
    ssh_helper = false
    port_forwarding_helper = false
    web_terminal = true
  }
```

This example will hide all built-in
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
icons except the web terminal.

## I want to allow code-server to be accessible by other users in my deployment

We don't recommend that you share a web IDE, but if you need to, the following
deployment environment variable settings are required.

Set deployment (Kubernetes) to allow path app sharing:

```yaml
# allow authenticated users to access path-based workspace apps
- name: CODER_DANGEROUS_ALLOW_PATH_APP_SHARING
  value: "true"
# allow Coder owner roles to access path-based workspace apps
- name: CODER_DANGEROUS_ALLOW_PATH_APP_SITE_OWNER_ACCESS
  value: "true"
```

In the template, set
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
[`share`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#share)
option to `authenticated` and when a workspace is built with this template, the
pretty globe shows up next to path-based `code-server`:

```tf
resource "coder_app" "code-server" {
  ...
  share        = "authenticated"
  ...
}
```

## I installed Coder and created a workspace but the icons do not load

An important concept to understand is that Coder creates workspaces which have
an agent that must be able to reach the `coder server`.

If the [`CODER_ACCESS_URL`](../admin/setup/index.md#access-url) is not
accessible from a workspace, the workspace may build, but the agent cannot reach
Coder, and thus the missing icons. e.g., Terminal, IDEs, Apps.

By default, `coder server` automatically creates an Internet-accessible
reverse proxy so that workspaces you create can reach the server.

If you are doing a standalone install, e.g., on a MacBook and want to build
workspaces in Docker Desktop, everything is self-contained and workspaces
(containers in Docker Desktop) can reach the Coder server.

```sh
coder server --access-url http://localhost:3000 --address 0.0.0.0:3000
```

Even `coder server` which creates a reverse proxy, will let you use
<http://localhost> to access Coder from a browser.

## I updated a template, and an existing workspace based on that template fails to start

When updating a template, be aware of potential issues with input variables. For
example, if a template prompts users to choose options like a
[code-server](https://github.com/coder/code-server)
[VS Code](https://code.visualstudio.com/) IDE release, a
[container image](https://hub.docker.com/u/codercom), or a
[VS Code extension](https://marketplace.visualstudio.com/vscode), removing any
of these values can lead to existing workspaces failing to start. This issue
occurs because the Terraform state will not be in sync with the new template.

However, a lesser-known CLI sub-command,
[`coder update`](../reference/cli/update.md), can resolve this issue. This
command re-prompts users to re-enter the input variables, potentially saving the
workspace from a failed status.

```sh
coder update --always-prompt <workspace name>
```

## I'm running coder on a VM with systemd but latest release installed isn't showing up

Take, for example, a Coder deployment on a VM with a 2 shared vCPU systemd
service. In this scenario, it's necessary to reload the daemon and then restart
the Coder service. This prevents the `systemd` daemon from trying to reference
the previous Coder release service since the unit file has changed.

The following commands can be used to update Coder and refresh the service:

```sh
curl -fsSL https://coder.com/install.sh | sh
sudo systemctl daemon-reload
sudo systemctl restart coder.service
```

## I'm using the built-in Postgres database and forgot admin email I set up

1. Run the `coder server` command below to retrieve the `psql` connection URL
   which includes the database user and password.
2. `psql` into Postgres, and do a select query on the `users` table.
3. Restart the `coder server`, pull up the Coder UI and log in (you will still
   need your password)

```sh
coder server postgres-builtin-url
psql "postgres://coder@localhost:53737/coder?sslmode=disable&password=I2S...pTk"
```

## How to find out Coder's latest Terraform provider version?

[Coder is on the HashiCorp's Terraform registry](https://registry.terraform.io/providers/coder/coder/latest).
Check this frequently to make sure you are on the latest version.

Sometimes, the version may change and `resource` configurations will either
become deprecated or new ones will be added when you get warnings or errors
creating and pushing templates.

## How can I set up TLS for my deployment and not create a signed certificate?

Caddy is an easy-to-configure reverse proxy that also automatically creates
certificates from Let's Encrypt.
[Install docs here](https://caddyserver.com/docs/quick-starts/reverse-proxy) You
can start Caddy as a `systemd` service.

The Caddyfile configuration will appear like this where `127.0.0.1:3000` is your
`CODER_ACCESS_URL`:

```text
coder.example.com {

  reverse_proxy 127.0.0.1:3000

  tls {

    issuer acme {
      email user@example.com
    }

  }
}
```

## I'm using Caddy as my reverse proxy in front of Coder. How do I set up a wildcard domain for port forwarding?

Caddy requires your DNS provider's credentials to create wildcard certificates.
This involves building the Caddy binary
[from source](https://github.com/caddyserver/caddy) with the DNS provider plugin
added. e.g.,
[Google Cloud DNS provider here](https://github.com/caddy-dns/googleclouddns)

To compile Caddy, the host running Coder requires Go. Once installed, replace
the existing Caddy binary in `usr/bin` and restart the Caddy service.

The updated Caddyfile configuration will look like this:

```text
*.coder.example.com, coder.example.com {

  reverse_proxy 127.0.0.1:3000

  tls {
    issuer acme {
      email user@example.com
      dns googleclouddns {
        gcp_project my-gcp-project
      }
    }
  }

}
```

## Can I use local or remote Terraform Modules in Coder templates?

One way is to reference a Terraform module from a GitHub repo to avoid
duplication and then just extend it or pass template-specific
parameters/resources:

```tf
# template1/main.tf
module "central-coder-module" {
  source = "github.com/org/central-coder-module"
  myparam = "custom-for-template1"
}

resource "ebs_volume" "custom_template1_only_resource" {
}
```

```tf
# template2/main.tf
module "central-coder-module" {
  source = "github.com/org/central-coder-module"
  myparam = "custom-for-template2"
  myparam2 = "bar"
}

resource "aws_instance" "custom_template2_only_resource" {
}
```

Another way using local modules is to symlink the module directory inside the
template directory and then `tar` the template.

```sh
ln -s modules template_1/modules
tar -cvh -C ./template_1 | coder templates <push|create> -d - <name>
```

References:

- [Public GitHub Issue 6117](https://github.com/coder/coder/issues/6117)
- [Public GitHub Issue 5677](https://github.com/coder/coder/issues/5677)
- [Coder docs: Templates/Change Management](../admin/templates/managing-templates/change-management.md)

## Can I run Coder in an air-gapped or offline mode? (no Internet)?

Yes, Coder can be deployed in
[air-gapped or offline mode](../install/airgap.md).

Our product bundles with the Terraform binary so assume access to terraform.io
during installation. The docs outline rebuilding the Coder container with
Terraform built-in as well as any required Terraform providers.

Direct networking from local SSH to a Coder workspace needs a STUN server. Coder
defaults to Google's STUN servers, so you can either create your STUN server in
your network or disable and force all traffic through the control plane's DERP
proxy.

## Create a randomized computer_name for an Azure VM

Azure VMs have a 15 character limit for the `computer_name` which can lead to
duplicate name errors.

This code produces a hashed value that will be difficult to replicate.

```tf
locals {
  concatenated_string = "${data.coder_workspace.me.name}+${data.coder_workspace_owner.me.name}"
  hashed_string = md5(local.concatenated_string)
  truncated_hash = substr(local.hashed_string, 0, 16)
}
```

## Do you have example JetBrains Gateway templates?

In August 2023, JetBrains certified the Coder plugin signifying enhanced
stability and reliability.

The Coder plugin will appear in the Gateway UI when opened.

Selecting the most suitable template depends on how the deployment manages
JetBrains IDE versions. If downloading from
[jetbrains.com](https://www.jetbrains.com/remote-development/gateway/) is
acceptable, see the example templates below which specifies the product code,
IDE version and build number in the
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#share)
resource. This will present an icon in the workspace dashboard which when
clicked, will look for a locally installed Gateway, and open it. Alternatively,
the IDE can be baked into the container image and manually open Gateway (or
IntelliJ which has Gateway built-in), using a session token to Coder and then
open the IDE.

## What options do I have for adding VS Code extensions into code-server, VS Code Desktop or Microsoft's Code Server?

Coder has an open-source project called
[`code-marketplace`](https://github.com/coder/code-marketplace) which is a
private VS Code extension marketplace. There is even integration with JFrog
Artifactory.

- [Blog post](https://coder.com/blog/running-a-private-vs-code-extension-marketplace)
- [OSS project](https://github.com/coder/code-marketplace)

You can also use Microsoft's code-server - which is like Coder's, but it
can connect to Microsoft's extension marketplace so Copilot and chat can be
retrieved there.

Another option is to use VS Code Desktop (local) and that connects to
Microsoft's marketplace.

## I want to run Docker for my workspaces but not install Docker Desktop

[Colima](https://github.com/abiosoft/colima) is a Docker Desktop alternative.

This example is meant for a users who want to try out Coder on a macOS device.

Install Colima and docker with:

```sh
brew install colima
brew install docker
```

Start Colima:

```sh
colima start
```

Start Colima with specific compute options:

```sh
colima start --cpu 4 --memory 8
```

Starting Colima on a M3 MacBook Pro:

```sh
colima start --arch x86_64  --cpu 4 --memory 8 --disk 10
```

Colima will show the path to the docker socket so we have a
[community template](https://github.com/sharkymark/v2-templates/tree/main/src/templates/docker/docker-code-server)
that prompts the Coder admin to enter the Docker socket as a Terraform variable.

## How to make a `coder_app` optional?

An example use case is the user should decide if they want a browser-based IDE
like code-server when creating the workspace.

1. Add a `coder_parameter` with type `bool` to ask the user if they want the
   code-server IDE

    ```tf
    data "coder_parameter" "code_server" {
        name        = "Do you want code-server in your workspace?"
        description = "Use VS Code in a browser."
        type        = "bool"
        default     = false
        mutable     = true
        icon        = "/icon/code.svg"
        order       = 6
    }
    ```

2. Add conditional logic to the `startup_script` to install and start
   code-server depending on the value of the added `coder_parameter`

    ```sh
    # install and start code-server, VS Code in a browser

    if [ ${data.coder_parameter.code_server.value} = true ]; then
    echo "🧑🏼‍💻 Downloading and installing the latest code-server IDE..."
    curl -fsSL https://code-server.dev/install.sh | sh
    code-server --auth none --port 13337 >/dev/null 2>&1 &
    fi
    ```

3. Add a Terraform meta-argument
   [`count`](https://developer.hashicorp.com/terraform/language/meta-arguments/count)
   in the `coder_app` resource so it will only create the resource if the
   `coder_parameter` is `true`

    ```tf
    # code-server
    resource "coder_app" "code-server" {
    count         = data.coder_parameter.code_server.value ? 1 : 0
    agent_id      = coder_agent.coder.id
    slug          = "code-server"
    display_name  = "code-server"
    icon          = "/icon/code.svg"
    url           = "http://localhost:13337?folder=/home/coder"
    subdomain = false
    share     = "owner"

    healthcheck {
        url       = "http://localhost:13337/healthz"
        interval  = 3
        threshold = 10
    }
    }
    ```

## Why am I getting this "remote host doesn't meet VS Code Server's prerequisites" error when opening up VSCode remote in a Linux environment?

![VS Code Server prerequisite](https://github.com/coder/coder/assets/10648092/150c5996-18b1-4fae-afd0-be2b386a3239)

It is because, more than likely, the supported OS of either the container image
or VM/VPS doesn't have the proper C libraries to run the VS Code Server. For
instance, Alpine is not supported at all. If so, you need to find a container
image or supported OS for the VS Code Server. For more information on OS
prerequisites for Linux, please look at the VSCode docs.
<https://code.visualstudio.com/docs/remote/linux#_local-linux-prerequisites>

## How can I resolve disconnects when connected to Coder via JetBrains Gateway?

If your JetBrains IDE is disconnected for a long period of time due to a network
change (for example turning off a VPN), you may find that the IDE will not
reconnect once the network is re-established (for example turning a VPN back
on). When this happens a persistent message will appear similar to the below:

```console
No internet connection. Changes in the document might be lost. Trying to reconnect…
```

To resolve this, add this entry to your SSH config file on your local machine:

```console
Host coder-jetbrains--*
  ServerAliveInterval 5
```

This will make SSH check that it can contact the server every five seconds. If
it fails to do so `ServerAliveCountMax` times (3 by default for a total of 15
seconds) then it will close the connection which forces JetBrains to recreate
the hung session. You can tweak `ServerAliveInterval` and `ServerAliveCountMax`
to increase or decrease the total timeout.

Note that the JetBrains Gateway configuration blocks for each host in your SSH
config file will be overwritten by the JetBrains Gateway client when it
re-authenticates to your Coder deployment so you must add the above config as a
separate block and not add it to any existing ones.

## How can I restrict inbound/outbound file transfers from Coder workspaces?

In certain environments, it is essential to keep confidential files within
workspaces and prevent users from uploading or downloading resources using tools
like `scp` or `rsync`.

To achieve this, template admins can use the environment variable
`CODER_AGENT_BLOCK_FILE_TRANSFER` to enable additional SSH command controls.
This variable allows the system to check if the executed application is on the
block list, which includes `scp`, `rsync`, `ftp`, and `nc`.

```tf
resource "docker_container" "workspace" {
  ...
  env = [
    "CODER_AGENT_TOKEN=${coder_agent.main.token}",
    "CODER_AGENT_BLOCK_FILE_TRANSFER=true",
    ...
  ]
}
```

### Important Notice

This control operates at the `ssh-exec` level or during `sftp` sessions. While
it can help prevent automated file transfers using the specified tools, users
can still SSH into the workspace and manually initiate file transfers. The
primary purpose of this feature is to warn and discourage users from downloading
confidential resources to their local machines.

For more advanced security needs, consider adopting an endpoint security
solution.

## How do I change the access URL for my Coder server?

You may want to change the default domain that's used to access coder, i.e. `yourcompany.coder.com` and find yourself unfamiliar with the process.

To change the access URL associated with your server, you can edit any of the following variables:

- CLI using the `--access-url` flag
- YAML using the `accessURL` option
- or ENV using the `CODER_ACCESS_URL` environmental variable.

For example, if you're using an environment file to configure your server, you'll want to edit the file located at `/etc/coder.d/coder.env` and edit the following:

`CODER_ACCESS_URL=https://yourcompany.coder.com` to your new desired URL.

Then save your changes, and reload daemon-ctl using the following command:

`systemctl daemon-reload`

and restart the service using:

`systemctl restart coder`

After coder restarts, your changes should be applied and should reflect in the admin settings.

---

# Best practices

Source: https://coder.com/docs/tutorials/best-practices

# Best practices

Guides to help you make the most of your Coder experience.

<children></children>

---

# Organizations - best practices

Source: https://coder.com/docs/tutorials/best-practices/organizations

# Organizations - best practices

---

Coder [Organizations](../../admin/users/organizations.md) allow administrators
finer control over groups, templates, workspaces, and provisioners within their
Coder deployment.

Organizations allow multiple platform teams to offer templates and
infrastructure to their users instead of having them entirely managed in a
centralized fashion.

Each organization can have its own unique admin and users can belong to multiple
organizations, but every organization must have separate templates,
provisioners, groups, and workspaces.

On this best practice page, we cover some of the ways you can use Organizations
to make it easier to manage your groups smoothly.

## How Coder organizations work

Organizations are the hierarchical parent for templates, groups, and
provisioners. Every new organization must have separate templates, provisioners,
and groups.

![Organizations architecture](../../images/best-practice/organizations-architecture.png)

Users can belong to multiple organizations while templates and provisioners
cannot.

## When to use organizations

Organizations increase the maintenance overhead of a Coder deployment, so we
recommend that you only use them when necessary.

Use organizations when a separate group of users needs to manage their own
templates and underlying infrastructure. If a group of users already has a
separate, functional platform team willing to write templates or manage
clusters, organizations may be a good fit.

### Organization use case examples

Here are a few examples for a fictional organization called MegaCo. It is
deployed with Coder and has 1000 users in production. Today, MegaCo has a single
(default) organization and a central platform team but is evaluating whether to
use organizations for several use cases.

| **Use Case**                                                                         | **Description**                                                                                                                                                                                                                                                                                                                                                                 | **Good fit for organizations?**                                                                        |
|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|
| Mergers and acquisitions                                                             | Raptix, a 180-person startup recently acquired by MegaCo, has an independent cloud account, platform team, and Terraform modules and pipelines for deploying their code. They want to use Coder.                                                                                                                                                                                | ✅ Organizations                                                                                        |
| Independent cloud-native teams that manage their namespaces, images, and/or clusters | MegaCo has six teams responsible for their own dev, staging, and production Kubernetes clusters and frequently deploy & test their work with `kubectl` and `helm`.</br></br>They wish to hook up Coder to their cluster so they can write and manage IDE templates for connecting to the cluster with their IDE                                                                 | ✅ Organizations                                                                                        |
| Java monolith                                                                        | MegaCo has identified that anyone developing the Java monolith is best served with a VM instead of a container/cloud-native environment.</br></br>However, the Java team is supported by MegaCo's central platform team.                                                                                                                                                        | ❌ Use instead:</br>A separate template and/or groups                                                   |
| Off-shore contractors                                                                | MegaCo employs off-shore contractors but has not onboarded them onto Coder due to privacy concerns, data sovereignty rules, and latency considerations.</br></br>They considered a minimal, localized second deployment of Coder, but decided against it due to maintenance overhead.                                                                                           | ✅ Organizations + Workspace Proxies                                                                    |
| Dev teams                                                                            | Dev teams often need to bring their requirements for dev environments, such as specific repositories and tools                                                                                                                                                                                                                                                                  | ❌ Use instead:</br>Parameters, dev containers, and/or groups                                           |
| ML Platform Team & ML Developers                                                     | MegaCo's data platform team maintains a homegrown "MLBox" product for data environments with a GPU, Jupyter, etc.</br></br>This team is interested in migrating to Coder for improved cost-saving and auditing of environments, but they need to hook up their own cluster and cloud accounts. They also want their templates only to be accessible to a specific set of users. | ✅ Organizations                                                                                        |
| Supporting developers in various regions                                             | MegaCo's central platform team supports developers connecting from the East Coast, the West Coast, and Australia. These developers are working on the same projects but need low-latency access to their environments.                                                                                                                                                          | ❌ Use instead:</br>Provisioners and workspace proxies to support multiple regions on a single template |

## How to migrate to organizations

Since templates and workspaces cannot be moved nor can they belong to multiple
organizations, we recommend that you deprecate your template
[through the API](../../reference/api/templates.md#update-template-metadata-by-id)
or [through the Coder CLI](../../reference/cli/templates_edit.md#--deprecated).
When a template is deprecated, the admin prevents new workspaces from being
created and developers are notified with a deprecation message which can link to
an external wiki page on migration instructions.

Users can use a file transfer tool such as
[rsync](https://linux.die.net/man/1/rsync) to migrate their files from one
workspace to another.

## Provisioner Isolation and Zero Trust

In the organizations model, provisioners run in a separate
cluster/infrastructure and have an isolated key to authenticate back with Coder.
The provisioners have access to separate cloud resources that the control plane
cannot access. Instead, the control plane sends simple "provisioner jobs" to the
provisioner and the provisioner is responsible for executing the Terraform.

There are planned improvements to the troubleshooting provisioners process.
Follow this GitHub issue for more details:

- [coder/coder#15192](https://github.com/coder/coder/issues/15192)

## Identity Provider (SSO) Sync

While the Coder UI or API can be used to assign specific users to organizations,
this is discouraged. Instead, we recommend syncing the state from your identity
provider such as Okta. A single claim from the identity provider (like
`memberOf`) can be used to sync site-wide roles, organizations, groups, and
organization roles.

Regex filters and mapping can be configured to ensure the proper resources are
allocated in Coder. Learn more about [IDP sync](../../admin/users/idp-sync.md).

## Custom Roles

Custom roles are organization-scoped and can be used to limit access controls
within an organization. Custom roles can be applied to the default organization.

Some examples of custom roles that can be created:

### Provisioner Admin

- The user can deploy provisioners but not manage templates. This may be useful
  if automation is used to create and update templates in the organization.

### Template Editor

- Inverse of provisioner admin: User can manage templates but not deploy
  provisioners. This may be useful if the provisioner and template are deployed
  via automation and users are allowed to edit them.

### Template Pusher

- A system account that can push new templates from a git repo but cannot manage
  users or delete templates.

We’re interested in identifying new use cases for custom roles. Please
[create a GitHub issue](https://github.com/coder/internal/issues/new?title=request%28orgs%29%3A+request+title+here&labels=["customer-feedback"]&body=please+enter+your+request+here)
with your suggestion or request.

## Managing Organizations at Scale

Using ClickOps to onboard new organizations, set quotas, and SSO sync can be
cumbersome, especially if you want to "seed" organizations with provisioners and
starter templates.

We suggest using the coderd Terraform provider to manage organizations at scale.
Documentation and examples for the Organization and Group Sync resources is available
at https://registry.terraform.io/providers/coder/coderd/latest/docs. Feature requests
for additional functionality can be created at https://github.com/coder/terraform-provider-coderd/issues.

---

# Scale Coder

Source: https://coder.com/docs/tutorials/best-practices/scale-coder

# Scale Coder

This best practice guide helps you prepare a Coder deployment that you can
scale up to a high-scale deployment as use grows, and keep it operating smoothly with a
high number of active users and workspaces.

## Observability

Observability is one of the most important aspects to a scalable Coder deployment.
When you have visibility into performance and usage metrics, you can make informed
decisions about what changes you should make.

[Monitor your Coder deployment](../../admin/monitoring/index.md) with log output
and metrics to identify potential bottlenecks before they negatively affect the
end-user experience and measure the effects of modifications you make to your
deployment.

- Log output
  - Capture log output from from Coder Server instances and external provisioner daemons
  and store them in a searchable log store like Loki, CloudWatch logs, or other tools.
  - Retain logs for a minimum of thirty days, ideally ninety days.
  This allows you investigate when anomalous behaviors began.

- Metrics
  - Capture infrastructure metrics like CPU, memory, open files, and network I/O for all
  Coder Server, external provisioner daemon, workspace proxy, and PostgreSQL instances.
  - Capture Coder Server and External Provisioner daemons metrics
  [via Prometheus](#how-to-capture-coder-server-metrics-with-prometheus).

Retain metric time series for at least six months. This allows you to see
performance trends relative to user growth.

For a more comprehensive overview, integrate metrics with an observability
dashboard like [Grafana](../../admin/monitoring/index.md).

### Observability key metrics

Configure alerting based on these metrics to ensure you surface problems before
they affect the end-user experience.

- CPU and Memory Utilization
  - Monitor the utilization as a fraction of the available resources on the instance.

     Utilization will vary with use throughout the course of a day, week, and longer timelines.
     Monitor trends and pay special attention to the daily and weekly peak utilization.
     Use long-term trends to plan infrastructure upgrades.

- Tail latency of Coder Server API requests
  - High tail latency can indicate Coder Server or the PostgreSQL database is underprovisioned
  for the load.
  - Use the `coderd_api_request_latencies_seconds` metric.

- Tail latency of database queries
  - High tail latency can indicate the PostgreSQL database is low in resources.
  - Use the `coderd_db_query_latencies_seconds` metric.

### How to capture Coder server metrics with Prometheus

Edit your Helm `values.yaml` to capture metrics from Coder Server and external provisioner daemons with
[Prometheus](../../admin/integrations/prometheus.md):

1. Enable Prometheus metrics:

   ```yaml
   CODER_PROMETHEUS_ENABLE=true
   ```

1. Enable database metrics:

   ```yaml
   CODER_PROMETHEUS_COLLECT_DB_METRICS=true
   ```

1. For a high scale deployment, configure agent stats to avoid large cardinality or disable them:

   - Configure agent stats:

     ```yaml
     CODER_PROMETHEUS_AGGREGATE_AGENT_STATS_BY=agent_name
     ```

   - Disable agent stats:

     ```yaml
     CODER_PROMETHEUS_COLLECT_AGENT_STATS=false
     ```

## Coder Server

### Locality

If increased availability of the Coder API is a concern, deploy at least three
instances of Coder Server. Spread the instances across nodes with anti-affinity rules in
Kubernetes or in different availability zones of the same geographic region.

Do not deploy in different geographic regions.

Coder Servers need to be able to communicate with one another directly with low
latency, under 10ms. Note that this is for the availability of the Coder API.
Workspaces are not fault tolerant unless they are explicitly built that way at
the template level.

Deploy Coder Server instances as geographically close to PostgreSQL as possible.
Low-latency communication (under 10ms) with Postgres is essential for Coder
Server's performance.

### Scaling

Coder Server can be scaled both vertically for bigger instances and horizontally
for more instances.

Aim to keep the number of Coder Server instances relatively small, preferably
under ten instances, and opt for vertical scale over horizontal scale after
meeting availability requirements.

Coder's
[validated architectures](../../admin/infrastructure/validated-architectures/index.md)
give specific sizing recommendations for various user scales. These are a useful
starting point, but very few deployments will remain stable at a predetermined
user level over the long term. We recommend monitoring and adjusting resources as needed.

We don't recommend that you autoscale the Coder Servers. Instead, scale the
deployment for peak weekly usage.

Although Coder Server persists no internal state, it operates as a proxy for end
users to their workspaces in two capacities:

1. As an HTTP proxy when they access workspace applications in their browser via
   the Coder Dashboard.

1. As a DERP proxy when establishing tunneled connections with CLI tools like
   `coder ssh`, `coder port-forward`, and others, and with desktop IDEs.

Stopping a Coder Server instance will (momentarily) disconnect any users
currently connecting through that instance. Adding a new instance is not
disruptive, but you should remove instances and perform upgrades during a
maintenance window to minimize disruption.

## Provisioner daemons

### Locality

We recommend that you run one or more
[provisioner daemon deployments external to Coder Server](../../admin/provisioners/index.md)
and disable provisioner daemons within your Coder Server.
This allows you to scale them independently of the Coder Server:

```yaml
CODER_PROVISIONER_DAEMONS=0
```

We recommend deploying provisioner daemons within the same cluster as the
workspaces they will provision or are hosted in.

- This gives them a low-latency connection to the APIs they will use to
  provision workspaces and can speed builds.

- It allows provisioner daemons to use in-cluster mechanisms (for example
  Kubernetes service account tokens, AWS IAM Roles, and others) to authenticate with
  the infrastructure APIs.

- If you deploy workspaces in multiple clusters, run multiple provisioner daemon
  deployments and use template tags to select the correct set of provisioner
  daemons.

- Provisioner daemons need to be able to connect to Coder Server, but this does not need
  to be a low-latency connection.

Provisioner daemons make no direct connections to the PostgreSQL database, so
there's no need for locality to the Postgres database.

### Scaling

Each provisioner daemon instance can handle a single workspace build job at a
time. Therefore, the maximum number of simultaneous builds your Coder deployment
can handle is equal to the number of provisioner daemon instances within a tagged
deployment.

If users experience unacceptably long queues for workspace builds to start,
consider increasing the number of provisioner daemon instances in the affected
cluster.

You might need to automatically scale the number of provisioner daemon instances
throughout the day to meet demand.

If you stop instances with `SIGHUP`, they will complete their current build job
and exit. `SIGINT` will cancel the current job, which will result in a failed build.
Ensure your autoscaler waits long enough for your build jobs to complete before
it kills the provisioner daemon process.

If you deploy in Kubernetes, we recommend a single provisioner daemon per pod.
On a virtual machine (VM), you can deploy multiple provisioner daemons, ensuring
each has a unique `CODER_CACHE_DIRECTORY` value.

Coder's
[validated architectures](../../admin/infrastructure/validated-architectures/index.md)
give specific sizing recommendations for various user scales. Since the
complexity of builds varies significantly depending on the workspace template,
consider this a starting point. Monitor queue times and build times and adjust
the number and size of your provisioner daemon instances.

## PostgreSQL

PostgreSQL is the primary persistence layer for all of Coder's deployment data.
We also use `LISTEN` and `NOTIFY` to coordinate between different instances of
Coder Server.

### Locality

Coder Server instances must have low-latency connections (under 10ms) to
PostgreSQL. If you use multiple PostgreSQL replicas in a clustered config, these
must also be low-latency with respect to one another.

### Scaling

Prefer scaling PostgreSQL vertically rather than horizontally for best
performance. Coder's
[validated architectures](../../admin/infrastructure/validated-architectures/index.md)
give specific sizing recommendations for various user scales.

### Connection pool tuning

Coder Server maintains a pool of connections to PostgreSQL. You can tune the
pool size with the following settings:

> [!NOTE]
> When adjusting these settings, please ensure that your PostgreSQL Server has `max_connections`
> set appropriately to accommodate all Coder Server replicas multiplied by the
> maximum number of open connections. We recommend configuring an additional 20%
> of connections to account for churn and other clients.
>
> Also note that increasing `max_connections` will result in potentially higher
> CPU and RAM usage, so you'll need to monitor accordingly.

- `--postgres-conn-max-open` (env: `CODER_PG_CONN_MAX_OPEN`): Maximum number of open
  connections. Default: 10.
- `--postgres-conn-max-idle` (env: `CODER_PG_CONN_MAX_IDLE`): Maximum number of idle
  connections kept in the pool. Default: "auto", which uses max open / 3.

When a connection is returned to the pool and the idle pool is already full, the
connection is closed immediately. This can cause connection establishment
overhead (churn) when load fluctuates. Monitor these metrics to understand your
connection pool behavior:

- **Capacity**: `go_sql_max_open_connections - go_sql_in_use_connections` shows
  how many connections are available for new requests. If this is 0, Coder
  Server performance will start to degrade. This just provides a point-in-time view
  of the connections, however.

  For a more systematic view, consider running
  `sum by (pod) (increase(go_sql_wait_duration_seconds_total[1m]))` to see how long
  each Coder replica spent waiting on the connection pool (i.e. no free connections);
  `sum by (pod) (increase(go_sql_wait_count_total[$__interval]))` shows how many
  connections were waited for.

  If either of these values seem unacceptably high, try tuning the above settings.
- **Churn**: `sum(rate(go_sql_max_idle_closed_total[$__rate_interval]))` shows
  how many connections are being closed because the idle pool is full.

If you see high churn, consider increasing `--pg-conn-max-idle` to keep more
connections ready for reuse. If you see capacity consistently near zero,
consider increasing `--pg-conn-max-open`.

## Workspace proxies

Workspace proxies proxy HTTP traffic from end users to workspaces for Coder apps
defined in the templates, and HTTP ports opened by the workspace. By default
they also include a DERP Proxy.

### Locality

We recommend each geographic cluster of workspaces have an associated deployment
of workspace proxies. This ensures that users always have a near-optimal proxy
path.

### Scaling

Workspace proxy load is determined by the amount of traffic they proxy.

Monitor CPU, memory, and network I/O utilization to decide when to resize
the number of proxy instances.

Scale for peak demand and scale down or upgrade during a maintenance window.

We do not recommend autoscaling the workspace proxies because many applications
use long-lived connections such as websockets, which would be disrupted by
stopping the proxy.

## Workspaces

Workspaces represent the vast majority of resources in most Coder deployments.
Because they are defined by templates, there is no one-size-fits-all advice for
scaling workspaces.

### Hard and soft cluster limits

All Infrastructure as a Service (IaaS) clusters have limits to what can be
simultaneously provisioned. These could be hard limits, based on the physical
size of the cluster, especially in the case of a private cloud, or soft limits,
based on configured limits in your public cloud account.

It is important to be aware of these limits and monitor Coder workspace resource
utilization against the limits, so that a new influx of users don't encounter
failed builds. Monitoring these is outside the scope of Coder, but we recommend
that you set up dashboards and alerts for each kind of limited resource.

As you approach soft limits, you can request limit increases to keep growing.

As you approach hard limits, consider deploying to additional cluster(s).

### Workspaces per node

Many development workloads are "spiky" in their CPU and memory requirements, for
example, they peak during build/test and then lower while editing code.
This leads to an opportunity to efficiently use compute resources by packing multiple
workspaces onto a single node. This can lead to better experience (more CPU and
memory available during brief bursts) and lower cost.

There are a number of things you should consider before you decide how many
workspaces you should allow per node:

- "Noisy neighbor" issues: Users share the node's CPU and memory resources and might
be susceptible to a user or process consuming shared resources.

- If the shared nodes are a provisioned resource, for example, Kubernetes nodes
  running on VMs in a public cloud, then it can sometimes be a challenge to
  effectively autoscale down.

  - For example, if half the workspaces are stopped overnight, and there are ten
    workspaces per node, it's unlikely that all ten workspaces on the node are
    among the stopped ones.

  - You can mitigate this by lowering the number of workspaces per node, or
    using autostop policies to stop more workspaces during off-peak hours.

- If you do overprovision workspaces onto nodes, keep them in a separate node
  pool and schedule Coder control plane (Coder Server, PostgreSQL, workspace
  proxies) components on a different node pool to avoid resource spikes
  affecting them.

Coder customers have had success with both:

- One workspace per AWS VM
- Lots of workspaces on Kubernetes nodes for efficiency

### Cost control

- Use quotas to discourage users from creating many workspaces they don't need
  simultaneously.

- Label workspace cloud resources by user, team, organization, or your own
  labelling conventions to track usage at different granularities.

- Use autostop requirements to bring off-peak utilization down.

## Networking

Set up your network so that most users can get direct, peer-to-peer connections
to their workspaces. This drastically reduces the load on Coder Server and
workspace proxy instances.

## Next steps

- [Scale Tests and Utilities](../../admin/infrastructure/scale-utility.md)
- [Scale Testing](../../admin/infrastructure/scale-testing.md)

---

# Security - best practices

Source: https://coder.com/docs/tutorials/best-practices/security-best-practices

# Security - best practices

December 16, 2024

---

This best practices guide is separated into parts to help you secure aspects of
your Coder deployment.

Each section briefly introduces each threat model, then suggests steps or
concepts to help implement security improvements such as authentication and
encryption.

As with any security guide, the steps and suggestions outlined in this document
are not meant to be exhaustive and do not offer any guarantee.

## Coder Server

Coder Server is the main control core of a Coder deployment.

If the Coder Server is compromised in a security incident, it can affect every
other part of your deployment. Even a successful read-only attack against the
Coder Server could result in a complete compromise of the Coder deployment if
credentials are stolen.

### User authentication

Configure [OIDC authentication](../../admin/users/oidc-auth/index.md) against your
organization’s Identity Provider (IdP), such as Okta, to allow single-sign on.

1. Enable and require two-factor authentication in your identity provider.
1. Enable [IdP Sync](../../admin/users/idp-sync.md) to manage users’ roles and
   groups in Coder.
1. Use SCIM to automatically suspend users when they leave the organization.

This allows you to manage user credentials according to your company’s central
requirements, such as password complexity, 2FA, PassKeys, and others.

Using IdP sync and SCIM means that the central Identity Provider is the source
of truth, so that when users change roles or leave, their permissions in Coder
are automatically up to date.

### Encryption in transit

Place Coder behind a TLS-capable reverse-proxy/load balancer and enable
[Strict Transport Security](../../reference/cli/server.md#--strict-transport-security)
so that connections from end users are always encrypted.

Enable [TLS](../../reference/cli/server.md#--tls-address) on Coder Server and
encrypt traffic from the reverse-proxy/load balancer to Coder Server, so that
even if an attacker gains access to your network, they will not be able to snoop
on Coder Server traffic.

### Encryption at rest

Coder Server persists no state locally. No action is required.

### Server logs and audit logs

Capture the logging output of all Coder Server instances and persist them.

Retain all logs for a minimum of thirty days, ideally ninety days. Filter audit
logs (which have `msg: audit_log`) and retain them for a minimum of two years
(ideally five years) in a secure system that resists tampering.

If a security incident with Coder does occur, audit logs are invaluable in
determining the nature and scope of the impact.

### Disable path-based apps

For production deployments, we recommend that you disable path-based apps after you've configured a wildcard access URL.

Path-based apps share the same origin as the Coder API, which can be convenient for trialing Coder,
but can expose the deployment to cross-site-scripting (XSS) attacks in production.
A malicious workspace could reuse Coder cookies to call the API or interact with other workspaces owned by the same user.

1. [Enable sub-domain apps with a wildcard DNS record](../../admin/setup/index.md#wildcard-access-url) (like `*.coder.example.com`)

1. Disable path-based apps:

   ```shell
   coderd server --disable-path-apps
   # or
   export CODER_DISABLE_PATH_APPS=true
   ```

By default, Coder mitigates the impact of having path-based apps enabled, but we still recommend disabling it to prevent
malicious workspaces accessing other workspaces owned by the same user or performing requests against the Coder API.

If you do keep path-based apps enabled:

- Path-based apps cannot be shared with other users unless you start the Coder server with `--dangerous-allow-path-app-sharing`.
- Users with the site `owner` role cannot use their admin privileges to access path-based apps for workspaces unless the
  server is started with `--dangerous-allow-path-app-site-owner-access`.

## PostgreSQL

PostgreSQL is the persistent datastore underlying the entire Coder deployment.
If the database is compromised, it may leave every other part of your deployment
vulnerable.

Coder session tokens and API keys are salted and hashed, so a read-only
compromise of the database is unlikely to allow an attacker to log into Coder.
However, the database contains the Terraform state for all workspaces, OIDC
tokens, and agent tokens, so it is possible that a read-only attack could enable
lateral movement to other systems.

A successful attack that modifies database state could be escalated to a full
takeover of an owner account in Coder which could lead to a complete compromise
of the Coder deployment.

### Authentication

1. Generate a strong, random password for accessing PostgreSQL and store it
   securely.

1. Use environment variables to pass the PostgreSQL URL to Coder.

1. If on Kubernetes, use a Kubernetes secret to set the environment variable.

### Encryption in transit

Enable TLS on PostgreSQL and set `sslmode=verify-full` in your
[postgres URL](../../reference/cli/server.md#--postgres-url) on Coder Server.
This configures Coder Server to only establish TLS connections to PostgreSQL and
check that the PostgreSQL server’s certificate is valid and matches the expected
hostname.

### Encryption at rest

Run PostgreSQL on servers with full disk encryption enabled and configured.

Coder supports
[encrypting some particularly sensitive data](../../admin/security/database-encryption.md)
including OIDC tokens using an encryption key managed independently of the
database, so even a user with full administrative privileges on the PostgreSQL
server(s) cannot read the data without the separate key.

If you use this feature:

1. Generate a random encryption key and store it in a central secrets management
   system like Vault.

1. Inject the secret using an environment variable.

   - If you're using Kubernetes, use a Kubernetes secret rather than including
     the secret directly in the podspec.

1. Follow your organization's policies about key rotation on a fixed schedule.

   - If you suspect the key has been leaked or compromised,
     [rotate the key immediately](../../admin/security/database-encryption.md#rotating-keys).

## Provisioner daemons

Provisioner daemons are deployed with credentials that give them power to make
requests to cluster/cloud APIs.

If one of those credentials is compromised, the potential severity of the
compromise depends on the permissions granted to the credentials, but will
almost certainly include code execution inside the cluster/cloud since the whole
purpose of Coder is to deploy workspaces in the cluster/cloud that can run
developer code.

In addition, provisioner daemons are given access to parameters entered by end
users, which could include sensitive data like credentials for additional
systems.

### External provisioner daemons

When Coder workspaces are deployed into multiple clusters/clouds, or workspaces
are in a different cluster/cloud than the Coder Server, use external provisioner
daemons.

Running provisioner daemons within the same cluster/cloud as the workspaces they
provision:

- Allows you to use infrastructure-provided credentials (see **Authentication**
  below) which are typically easier to manage and have shorter lifetimes than
  credentials issued outside the cloud/cluster.
- Means that you don’t have to open any ingress ports on the clusters/clouds
  that host workspaces.
  - The external provisioner daemons dial out to Coder Server.
  - Provisioner daemons run in the cluster, so you don’t need to expose
    cluster/cloud APIs externally.
- Each cloud/cluster is isolated, so a compromise of a provisioner daemon is
  limited to a single cluster.

### Authentication

1. Use a [scoped key](../../admin/provisioners/index.md#scoped-key-recommended) to
   authenticate the provisioner daemons with Coder. These keys can only be used
   to authenticate provisioner daemons (not other APIs on the Coder Server).

1. Store the keys securely and use environment variables to pass them to the
   provisioner daemon.

1. If on Kubernetes, use a Kubernetes secret to set the environment variable.

1. Tag provisioners with identifiers for the specific cluster/cloud.

   This allows your templates to target a specific cluster/cloud such as for
   geographic proximity to the end user, or for specific features like GPUs or
   managed services.

1. Scope your keys to organizations and the specific cluster/cloud using the
   same tags when creating the keys.

   This ensures that a compromised key will not allow an attacker to gain access
   to jobs for other clusters or organizations.

Provisioner daemons should have access only to cluster/cloud API credentials for
the specific cluster/cloud they are for. This ensures that compromise of one
Provisioner Daemon does not compromise all clusters/clouds.

Deploy the provisioner daemon to the cloud and leverage infrastructure-provided
credentials, if available:

- [Service account tokens on Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
- [IAM roles for EC2 on AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)
- [Attached service accounts on Google Cloud](https://cloud.google.com/iam/docs/attach-service-accounts)

### Encryption in transit

Enable TLS on Coder Server and ensure you use an `https://` URL to access the
Coder Server.

See the **Encryption in transit** subheading of the
[Templates](#workspace-templates) section for more about encrypting
cluster/cloud API calls.

### Encryption at rest

Run provisioner daemons only on systems with full disk encryption enabled.

- Provisioner daemons temporarily persist terraform template files and resource
  state to disk. Either of these could contain sensitive information, including
  credentials.

  This temporary state is on disk only while actively building workspaces, but
  an attacker who compromises physical disks could successfully read this
  information if not encrypted.

- Provisioner daemons store cached copies of Terraform provider binaries. These
  are generally not sensitive in terms of confidentiality, but it is important
  to maintain their integrity. An attacker that can modify these binaries could
  inject malicious code.

## Workspace proxies

Workspace proxies authenticate end users and then proxy network traffic to
workspaces.

Coder takes care to ensure the user credentials processed by workspace proxies
are scoped to application access and do not grant full access to the Coder API
on behalf of the user. Still, a fully compromised workspace proxy would be in a
privileged position to phish unrestricted user credentials.

Workspace proxies have unrestricted access to establish encrypted tunnels to
workspaces and can access any port on any running workspace.

### Authentication

1. Securely store the workspace proxy token generated by
   [`coder wsproxy create`](../../admin/networking/workspace-proxies.md#step-1-create-the-proxy).

1. Inject the token to the workspace proxy process via an environment variable,
   rather than via an argument.

1. If on Kubernetes, use a Kubernetes secret to set the environment variable.

### Encryption in transit

Enable TLS on Coder Server and ensure you use an `https://` URL to access the
Coder Server.

Communication to the proxied workspace applications is always encrypted with
Wireguard. No action is required.

### Encryption at rest

Workspace proxies persist no state locally. No action is required.

## Workspace templates

Coder templates are executed on provisioner daemons and can include arbitrary
code via the
[local-exec provisioner](https://developer.hashicorp.com/terraform/language/resources/provisioners/local-exec).

Furthermore, Coder templates are designed to provision compute resources in one
or more clusters/clouds, and template authors are generally in full control over
code and scripts executed by the Coder agent in those compute resources.

This means that template admins have remote code execution privileges for any
provisioner daemons in their organization and within any cluster/cloud those
provisioner daemons are credentialed to access.

Template admin is a powerful, highly-trusted role that you should not assign
lightly. Instead of directly assigning the role to anyone who might need to edit
a template, use [GitOps](#gitops) to allow users to author and edit templates.

## Secrets

Never include credentials or any other secrets directly in templates, including
in `.tfvars` or other files uploaded with the template.

Instead do one of the following:

- Store secrets in a central secrets manager.

  - Access the secrets at build time via a Terraform provider.

    This can be through
    [Vault](https://registry.terraform.io/providers/hashicorp/vault/latest/docs)
    or
    [AWS Secrets Manager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret).

- Place secrets in `TF_VAR_*` environment variables.

  - Provide the secrets to the relevant Provisioner Daemons and access them via
    Terraform variables with `sensitive = true`.

- Use Coder parameters to accept secrets from end users at build time.

Coder does not attempt to obscure the contents of template files from users
authorized to view and edit templates, so secrets included directly could
inadvertently appear on screen while template authors do their work.

Template versions are persisted indefinitely in the PostgreSQL database, so if
secrets are inadvertently included, they should be revoked as soon as practical.
Pushing a new template version does not expunge them from the database. Contact
support if you need assistance expunging any particularly sensitive data.

### Encryption in transit

Always use encrypted transport to access any infrastructure APIs. Crucially,
this protects confidentiality of the credentials used to access the APIs.

Configuration of this depends on the specific Terraform providers in use and is
beyond the scope of this document.

### Encryption at rest

While your most privileged secrets should never be included in template files,
they may inevitably contain confidential or sensitive data about your operations
and/or infrastructure.

- Ensure that operators who write, review or modify Coder templates are working
  on laptops/workstations with full disk encryption, or do their work inside a
  Coder workspace with full disk encryption.
- Ensure [PostgreSQL](#postgresql) is encrypted at rest.
- Ensure any [source code repositories that store templates](#gitops) are
  encrypted at rest and have appropriate access controls.

### GitOps

GitOps is the practice of using a Git repository as the source of truth for
operational config and reconciling the config in Git with operational systems
each time the `main` (or, archaically, `master`) branch of the repository is
updated.

1. Store Coder templates in a single Git repository, or a single repository per
   Coder organization, and use the
   [Coderd Terraform provider](https://registry.terraform.io/providers/coder/coderd/latest/docs/resources/template)
   to push changes from the main branch to Coder using a CI/CD tool.

   This gives you an easily browsable, auditable history of template changes and
   who made them. Coder audit logs establish who and when changes happen, but
   git repositories are particularly handy for analyzing exactly what changes to
   templates are made.

1. Use a Coder user account exclusively for the purpose of pushing template
   changes and do not give any human users the credentials.

   This ensures any actions taken by the account correspond exactly to CI/CD
   actions from the repository and allows you to avoid granting the template
   admin role widely in your organization.

1. Use
   [GitHub branch protection](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches),
   or the equivalent for your source repository to enforce code review of
   changes to templates.

   Code review increases the chance that someone will catch a potential security
   bug in your template.

These protections also mitigate the risk of a single trusted insider “going
rogue” and acting unilaterally to maliciously modify Coder templates.

## Workspaces

The central purpose of Coder is to give end users access to managed compute in
clusters/clouds designated by Coder’s operators (like platform or developer
experience teams). End users are granted shell access and from there can execute
arbitrary commands.

This means that end users have remote code execution privileges within the
clusters/clouds that host Coder workspaces.

It is important to limit Coder users to trusted insiders and/or take steps to
constrain malicious activity that could be undertaken from a Coder workspace.

Example constraints include:

- Network policy or segmentation
- Runtime protections on the workspace host (e.g. SELinux)
- Limiting privileges of the account or role assigned to the workspace such as a
  service account on Kubernetes, or IAM role on public clouds
- Monitoring and/or auditing for suspicious activity such as cryptomining or
  exfiltration

### Outbound network access

Identify network assets like production systems or highly confidential
datastores and configure the network to limit access from Coder workspaces.

If production systems or confidential data reside in the same cluster/cloud, use
separate node pools and network boundaries.

If extraordinary access is required, follow
[Zero Trust](https://en.wikipedia.org/wiki/Zero_trust_security_model)
principles:

- Authenticate the user and the workspace using strong cryptography
- Apply strict authorization controls
- Audit access in a tamper resistant secure store

Consider the network assets end users will need to do their job and the level of
trust the company has with them. In-house full-time employees have different
access than temporary contractors or third-party service providers. Restrict
access as appropriate.

A non-exclusive list of network assets to consider:

- Access to the public Internet
  - If end users will access the workspace over the public Internet, you must
    allow outbound access to establish the encrypted tunnels.
- Access to internal corporate networks
  - If end users will access the workspace over the corporate network, you must
    allow outbound access to establish the encrypted tunnels.
- Access to staging or production systems
- Access to confidential data (e.g. payment processing data, health records,
  personally identifiable information)
- Access to other clusters/clouds

### Inbound network access

Coder manages inbound network access to your workspaces via a set of Wireguard
encrypted tunnels. These tunnels are established by sending outbound packets, so
on stateful firewalls, disable inbound connections to workspaces to ensure
inbound connections are handled exclusively by the encrypted tunnels.

#### DERP

[DERP](https://tailscale.com/kb/1232/derp-servers) is a relay protocol developed
by Tailscale.

Coder Server and Workspace Proxies include a DERP service by default. Tailcale
also runs a set of public DERP servers, globally distributed.

All DERP messages are end-to-end encrypted, so the DERP service only learns the
(public) IP addresses of the participants.

If you consider these addresses or the fact that pairs of them communicate over
DERP to be sensitive, stick to the Coder-provided DERP services which run on
your own infrastructure. If not, feel free to configure Tailscale DERP servers
for global coverage.

#### STUN

[STUN](https://en.wikipedia.org/wiki/STUN) is an IETF standard protocol that
allows network endpoints behind NAT to learn their public address and port
mappings. It is an essential component of Coder’s networking to enable encrypted
tunnels to be established without a relay for best performance.

Coder does not ship with a STUN service because it needs to be run directly
connected to the network, not behind a reverse proxy or load balancer as Coder
usually is.

STUN messages are not encrypted, but do not transmit any tunneled data, they
simply query the public address and ports. As such, a STUN service learns the
public address and port information such as the address and port on the NAT
device of Coder workspaces and the end user's device if STUN is configured.

Unlike DERP, it doesn’t definitively learn about communicating pairs of IPs.

If you consider the public IP and port information to be sensitive, do not use
public STUN servers.

You may choose not to configure any STUN servers, in which case most workspace
traffic will need to be relayed via DERP. You may choose to deploy your own STUN
servers, either on the public Internet, or on your corporate network and
[configure Coder to use it](../../reference/cli/server.md#--derp-server-stun-addresses).

If you do not consider the addresses and ports to be sensitive, we recommend
using the default set of STUN servers operated by Google.

#### Workspace apps

Coder workspace apps are a way to allow users to access web applications running
in the workspace via the Coder Server or Workspace Proxy.

1. [Disable workspace apps on sub-paths](../../reference/cli/server.md#--disable-path-apps)
   of the main Coder domain name.

1. [Use a separate, wildcard domain name](../../admin/setup/index.md#wildcard-access-url)
   for forwarding.

   Because of the default
   [same-origin policy](https://en.wikipedia.org/wiki/Same-origin_policy) in
   browsers, serving web apps on the main Coder domain would allow those apps to
   send API requests to the Coder Server, authenticated as the logged-in user
   without their explicit consent.

#### Port sharing

Coder supports the option to allow users to designate specific network ports on
their workspace as shared, which allows others to access those ports via the
Coder Server.

Consider restricting the maximum sharing level for workspaces, located in the
template settings for the corresponding template.

### Encryption at rest

Deploy Coder workspaces using full disk encryption for all volumes.

This mitigates attempts to recover sensitive data in the workspace by attackers
who gain physical access to the disk(s).

---

# Speed up your workspaces

Source: https://coder.com/docs/tutorials/best-practices/speed-up-templates

# Speed up your Coder templates and workspaces

October 31, 2024

---

If it takes your workspace a long time to start, find out why and make some
changes to your Coder templates to help speed things up.

## Monitoring

You can monitor [Coder logs](../../admin/monitoring/logs.md) through the
system-native tools on your deployment platform, or stream logs to tools like
Splunk, Datadog, Grafana Loki, and others.

### Workspace build timeline

Use the **Build timeline** to monitor the time it takes to start specific
workspaces. Identify long scripts, resources, and other things you can
potentially optimize within the template.

![Screenshot of a workspace and its build timeline](../../images/best-practice/build-timeline.png)

You can also retrieve this detail programmatically from the API:

```shell
curl -X GET https://coder.example.com/api/v2/workspacebuilds/{workspacebuild}/timings \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

Visit the
[API documentation](../../reference/api/builds.md#get-workspace-build-timings-by-id)
for more information.

### Coder Observability Chart

Use the [Observability Helm chart](https://github.com/coder/observability) for a
pre-built set of dashboards to monitor your Coder deployments over time. It
includes pre-configured instances of Grafana, Prometheus, Loki, and Alertmanager
to ingest and display key observability data.

We recommend that all administrators deploying on Kubernetes or on an existing
Prometheus or Grafana stack set the observability bundle up with the control
plane from the start. For installation instructions, visit the
[observability repository](https://github.com/coder/observability?tab=readme-ov-file#installation),
or our [Kubernetes installation guide](../../install/kubernetes.md).

### Enable Prometheus metrics for Coder

Coder exposes a variety of
[application metrics](../../admin/integrations/prometheus.md#available-metrics),
such as `coderd_provisionerd_job_timings_seconds` and
`coderd_agentstats_startup_script_seconds`, which measure how long the
workspaces take to provision and how long the startup scripts take.

To make use of these metrics, you will need to
[enable Prometheus metrics](../../admin/integrations/prometheus.md#enable-prometheus-metrics)
exposition.

If you are not using the [Observability Chart](#coder-observability-chart), you
will need to install Prometheus and configure it to scrape the metrics from your
Coder installation.

## Provisioners

`coder server` by default provides three built-in provisioner daemons
(controlled by the
[`CODER_PROVISIONER_DAEMONS`](../../reference/cli/server.md#--provisioner-daemons)
config option). Each provisioner daemon can handle one single job (such as
start, stop, or delete) at a time and can be resource intensive. When all
provisioners are busy, workspaces enter a "pending" state until a provisioner
becomes available.

### Increase provisioner daemons

Provisioners are queue-based to reduce unpredictable load to the Coder server.
If you require a higher bandwidth of provisioner jobs, you can do so by
increasing the
[`CODER_PROVISIONER_DAEMONS`](../../reference/cli/server.md#--provisioner-daemons)
config option.

You risk overloading Coder if you use too many built-in provisioners, so we
recommend a maximum of five built-in provisioners per `coderd` replica. For more
than five provisioners, we recommend that you move to
[External Provisioners](../../admin/provisioners/index.md) and also consider
[High Availability](../../admin/networking/high-availability.md) to run multiple
`coderd` replicas.

Visit the
[CLI documentation](../../reference/cli/server.md#--provisioner-daemons) for
more information about increasing provisioner daemons, configuring external
provisioners, and other options.

### Adjust provisioner CPU/memory

We recommend that you deploy Coder to its own respective Kubernetes cluster,
separate from production applications. Keep in mind that Coder runs development
workloads, so the cluster should be deployed as such, without production-level
configurations.

Adjust the CPU and memory values as shown in
[Helm provisioner values.yaml](https://github.com/coder/coder/blob/main/helm/provisioner/values.yaml#L134-L141):

```yaml
…
  resources:
    limits:
      cpu: "0.25"
      memory: "1Gi"
    requests:
      cpu: "0.25"
      memory: "1Gi"
…
```

Visit the
[validated architecture documentation](../../admin/infrastructure/validated-architectures/index.md#workspace-nodes)
for more information.

## Set up Terraform provider caching

### Template lock file

On each workspace build, Terraform will examine the providers used by the
template and attempt to download the latest version of each provider unless it
is constrained to a specific version. Terraform exposes a mechanism to build a
static list of provider versions, which improves cacheability.

Without caching, Terraform will download each provider on each build, and this
can create unnecessary network and disk I/O.

`terraform init` generates a `.terraform.lock.hcl` which instructs Coder
provisioners to cache specific versions of your providers.

To use `terraform init` to build the static provider version list:

1. Pull your template to your local device:

   ```shell
   coder templates pull <template>
   ```

1. Run `terraform init` inside the template directory to build the lock file:

   ```shell
   terraform init
   ```

1. Push the templates back to your Coder deployment:

   ```shell
   coder templates push <template>
   ```

This bundles up your template and the lock file and uploads it to Coder. The
next time the template is used, Terraform will attempt to cache the specific
provider versions.

### Cache directory

Coder will instruct Terraform to cache its downloaded providers in the
configured [`CODER_CACHE_DIRECTORY`](../../reference/cli/server.md#--cache-dir)
directory.

Ensure that this directory is set to a location on disk which will persist
across restarts of Coder or
[external provisioners](../../admin/provisioners/index.md), if you're using them.

---

# Reference

Source: https://coder.com/docs/reference

# Reference

## Automation

All actions possible through the Coder dashboard can also be automated. There
are several ways to extend/automate Coder:

- [coderd Terraform Provider](https://registry.terraform.io/providers/coder/coderd/latest)
- [CLI](../reference/cli/index.md)
- [REST API](../reference/api/index.md)
- [Coder SDK](https://pkg.go.dev/github.com/coder/coder/v2/codersdk)
- [Agent API](../reference/agent-api/index.md)

## Quickstart

Generate a token on your Coder deployment by visiting:

```shell
https://coder.example.com/settings/tokens
```

List your workspaces

```shell
# CLI
coder ls \
  --url https://coder.example.com \
  --token <your-token> \
  --output json

# REST API (with curl)
curl https://coder.example.com/api/v2/workspaces?q=owner:me \
  -H "Coder-Session-Token: <your-token>"
```

## Documentation

We publish an [API reference](../reference/api/index.md) in our documentation.
You can also enable a
[Swagger endpoint](../reference/cli/server.md#--swagger-enable) on your Coder
deployment.

## Use cases

We strive to keep the following use cases up to date, but please note that
changes to API queries and routes can occur. For the most recent queries and
payloads, we recommend checking the relevant documentation.

### Users & Groups

- [Manage Users via Terraform](https://registry.terraform.io/providers/coder/coderd/latest/docs/resources/user)
- [Manage Groups via Terraform](https://registry.terraform.io/providers/coder/coderd/latest/docs/resources/group)

### Templates

- [Manage templates via Terraform or CLI](../admin/templates/managing-templates/change-management.md):
  Store all templates in git and update them in CI/CD pipelines.

### Workspace agents

Workspace agents have a special token that can send logs, metrics, and workspace
activity.

- [Custom workspace logs](../reference/api/agents.md#patch-workspace-agent-logs):
  Expose messages prior to the Coder init script running (e.g. pulling image, VM
  starting, restoring snapshot).
  [coder-logstream-kube](https://github.com/coder/coder-logstream-kube) uses
  this to show Kubernetes events, such as image pulls or ResourceQuota
  restrictions.

  ```shell
  curl -X PATCH https://coder.example.com/api/v2/workspaceagents/me/logs \
  -H "Coder-Session-Token: $CODER_AGENT_TOKEN" \
  -d "{
  \"logs\": [
    {
      \"created_at\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\",
      \"level\": \"info\",
      \"output\": \"Restoring workspace from snapshot: 05%...\"
    }
  ]
  }"
  ```

- [Manually send workspace activity](../reference/api/workspaces.md#extend-workspace-deadline-by-id):
  Keep a workspace "active," even if there is not an open connection (e.g. for a
  long-running machine learning job).

  ```shell
  #!/bin/bash
  # Send workspace activity as long as the job is still running

  while true
  do
  if pgrep -f "my_training_script.py" > /dev/null
  then
    curl -X PUT "https://coder.example.com/api/v2/workspaces/$WORKSPACE_ID/extend" \
    -H "Coder-Session-Token: $CODER_AGENT_TOKEN" \
    -d '{
      "deadline": "2019-08-24T14:15:22Z"
    }'

    # Sleep for 30 minutes (1800 seconds) if the job is running
    sleep 1800
  else
    # Sleep for 1 minute (60 seconds) if the job is not running
    sleep 60
  fi
  done
  ```

---

# REST API

Source: https://coder.com/docs/reference/api

# API

Get started with the Coder API:

## Quickstart

Generate a token on your Coder deployment by visiting:

````shell
https://coder.example.com/settings/tokens
````

List your workspaces

````shell
# CLI
curl https://coder.example.com/api/v2/workspaces?q=owner:me \
-H "Coder-Session-Token: <your-token>"
````

## Use cases

See some common [use cases](../../reference/index.md#use-cases) for the REST API.

## Sections

<children>
  This page is rendered on https://coder.com/docs/reference/api. Refer to the other documents in the `api/` directory.
</children>

---

# General

Source: https://coder.com/docs/reference/api/general

# General

## API root handler

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/ \
  -H 'Accept: application/json'
```

`GET /api/v2/`

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

## Build info

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/buildinfo \
  -H 'Accept: application/json'
```

`GET /api/v2/buildinfo`

### Example responses

> 200 Response

```json
{
  "agent_api_version": "string",
  "dashboard_url": "string",
  "deployment_id": "string",
  "external_url": "string",
  "provisioner_api_version": "string",
  "telemetry": true,
  "upgrade_message": "string",
  "version": "string",
  "webpush_public_key": "string",
  "workspace_proxy": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.BuildInfoResponse](schemas.md#codersdkbuildinforesponse) |

## Report CSP violations

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/csp/reports \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/csp/reports`

> Body parameter

```json
{
  "csp-report": {}
}
```

### Parameters

| Name   | In   | Type                                                 | Required | Description      |
|--------|------|------------------------------------------------------|----------|------------------|
| `body` | body | [coderd.cspViolation](schemas.md#coderdcspviolation) | true     | Violation report |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get deployment config

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/deployment/config \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/deployment/config`

### Example responses

> 200 Response

```json
{
  "config": {
    "access_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "additional_csp_policy": [
      "string"
    ],
    "address": {
      "host": "string",
      "port": "string"
    },
    "agent_fallback_troubleshooting_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "agent_stat_refresh_interval": 0,
    "ai": {
      "aibridge_proxy": {
        "allowed_private_cidrs": [
          "string"
        ],
        "cert_file": "string",
        "domain_allowlist": [
          "string"
        ],
        "enabled": true,
        "key_file": "string",
        "listen_addr": "string",
        "tls_cert_file": "string",
        "tls_key_file": "string",
        "upstream_proxy": "string",
        "upstream_proxy_ca": "string"
      },
      "bridge": {
        "allow_byok": true,
        "anthropic": {
          "base_url": "string",
          "key": "string"
        },
        "bedrock": {
          "access_key": "string",
          "access_key_secret": "string",
          "base_url": "string",
          "model": "string",
          "region": "string",
          "small_fast_model": "string"
        },
        "circuit_breaker_enabled": true,
        "circuit_breaker_failure_threshold": 0,
        "circuit_breaker_interval": 0,
        "circuit_breaker_max_requests": 0,
        "circuit_breaker_timeout": 0,
        "enabled": true,
        "inject_coder_mcp_tools": true,
        "max_concurrency": 0,
        "openai": {
          "base_url": "string",
          "key": "string"
        },
        "providers": [
          {
            "base_url": "string",
            "bedrock_model": "string",
            "bedrock_region": "string",
            "bedrock_small_fast_model": "string",
            "dump_dir": "string",
            "name": "string",
            "type": "string"
          }
        ],
        "rate_limit": 0,
        "retention": 0,
        "send_actor_headers": true,
        "structured_logging": true
      },
      "chat": {
        "acquire_batch_size": 0,
        "debug_logging_enabled": true
      }
    },
    "allow_workspace_renames": true,
    "autobuild_poll_interval": 0,
    "browser_only": true,
    "cache_directory": "string",
    "cli_upgrade_message": "string",
    "config": "string",
    "config_ssh": {
      "deploymentName": "string",
      "sshconfigOptions": [
        "string"
      ]
    },
    "dangerous": {
      "allow_all_cors": true,
      "allow_path_app_sharing": true,
      "allow_path_app_site_owner_access": true
    },
    "derp": {
      "config": {
        "block_direct": true,
        "force_websockets": true,
        "path": "string",
        "url": "string"
      },
      "server": {
        "enable": true,
        "region_code": "string",
        "region_id": 0,
        "region_name": "string",
        "relay_url": {
          "forceQuery": true,
          "fragment": "string",
          "host": "string",
          "omitHost": true,
          "opaque": "string",
          "path": "string",
          "rawFragment": "string",
          "rawPath": "string",
          "rawQuery": "string",
          "scheme": "string",
          "user": {}
        },
        "stun_addresses": [
          "string"
        ]
      }
    },
    "disable_owner_workspace_exec": true,
    "disable_password_auth": true,
    "disable_path_apps": true,
    "disable_workspace_sharing": true,
    "docs_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "enable_authz_recording": true,
    "enable_terraform_debug_mode": true,
    "ephemeral_deployment": true,
    "experiments": [
      "string"
    ],
    "external_auth": {
      "value": [
        {
          "api_base_url": "string",
          "app_install_url": "string",
          "app_installations_url": "string",
          "auth_url": "string",
          "client_id": "string",
          "code_challenge_methods_supported": [
            "string"
          ],
          "device_code_url": "string",
          "device_flow": true,
          "display_icon": "string",
          "display_name": "string",
          "id": "string",
          "mcp_tool_allow_regex": "string",
          "mcp_tool_deny_regex": "string",
          "mcp_url": "string",
          "no_refresh": true,
          "regex": "string",
          "revoke_url": "string",
          "scopes": [
            "string"
          ],
          "token_url": "string",
          "type": "string",
          "validate_url": "string"
        }
      ]
    },
    "external_auth_github_default_provider_enable": true,
    "external_token_encryption_keys": [
      "string"
    ],
    "healthcheck": {
      "refresh": 0,
      "threshold_database": 0
    },
    "hide_ai_tasks": true,
    "http_address": "string",
    "http_cookies": {
      "host_prefix": true,
      "same_site": "string",
      "secure_auth_cookie": true
    },
    "job_hang_detector_interval": 0,
    "logging": {
      "human": "string",
      "json": "string",
      "log_filter": [
        "string"
      ],
      "stackdriver": "string"
    },
    "metrics_cache_refresh_interval": 0,
    "notifications": {
      "dispatch_timeout": 0,
      "email": {
        "auth": {
          "identity": "string",
          "password": "string",
          "password_file": "string",
          "username": "string"
        },
        "force_tls": true,
        "from": "string",
        "hello": "string",
        "smarthost": "string",
        "tls": {
          "ca_file": "string",
          "cert_file": "string",
          "insecure_skip_verify": true,
          "key_file": "string",
          "server_name": "string",
          "start_tls": true
        }
      },
      "fetch_interval": 0,
      "inbox": {
        "enabled": true
      },
      "lease_count": 0,
      "lease_period": 0,
      "max_send_attempts": 0,
      "method": "string",
      "retry_interval": 0,
      "sync_buffer_size": 0,
      "sync_interval": 0,
      "webhook": {
        "endpoint": {
          "forceQuery": true,
          "fragment": "string",
          "host": "string",
          "omitHost": true,
          "opaque": "string",
          "path": "string",
          "rawFragment": "string",
          "rawPath": "string",
          "rawQuery": "string",
          "scheme": "string",
          "user": {}
        }
      }
    },
    "oauth2": {
      "github": {
        "allow_everyone": true,
        "allow_signups": true,
        "allowed_orgs": [
          "string"
        ],
        "allowed_teams": [
          "string"
        ],
        "client_id": "string",
        "client_secret": "string",
        "default_provider_enable": true,
        "device_flow": true,
        "enterprise_base_url": "string"
      }
    },
    "oidc": {
      "allow_signups": true,
      "auth_url_params": {},
      "client_cert_file": "string",
      "client_id": "string",
      "client_key_file": "string",
      "client_secret": "string",
      "email_domain": [
        "string"
      ],
      "email_field": "string",
      "group_allow_list": [
        "string"
      ],
      "group_auto_create": true,
      "group_mapping": {},
      "group_regex_filter": {},
      "groups_field": "string",
      "icon_url": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      },
      "ignore_email_verified": true,
      "ignore_user_info": true,
      "issuer_url": "string",
      "name_field": "string",
      "organization_assign_default": true,
      "organization_field": "string",
      "organization_mapping": {},
      "redirect_url": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      },
      "scopes": [
        "string"
      ],
      "sign_in_text": "string",
      "signups_disabled_text": "string",
      "skip_issuer_checks": true,
      "source_user_info_from_access_token": true,
      "user_role_field": "string",
      "user_role_mapping": {},
      "user_roles_default": [
        "string"
      ],
      "username_field": "string"
    },
    "pg_auth": "string",
    "pg_conn_max_idle": "string",
    "pg_conn_max_open": 0,
    "pg_connection_url": "string",
    "pprof": {
      "address": {
        "host": "string",
        "port": "string"
      },
      "enable": true
    },
    "prometheus": {
      "address": {
        "host": "string",
        "port": "string"
      },
      "aggregate_agent_stats_by": [
        "string"
      ],
      "collect_agent_stats": true,
      "collect_db_metrics": true,
      "enable": true
    },
    "provisioner": {
      "daemon_poll_interval": 0,
      "daemon_poll_jitter": 0,
      "daemon_psk": "string",
      "daemon_types": [
        "string"
      ],
      "daemons": 0,
      "force_cancel_interval": 0
    },
    "proxy_health_status_interval": 0,
    "proxy_trusted_headers": [
      "string"
    ],
    "proxy_trusted_origins": [
      "string"
    ],
    "rate_limit": {
      "api": 0,
      "disable_all": true
    },
    "redirect_to_access_url": true,
    "retention": {
      "api_keys": 0,
      "audit_logs": 0,
      "connection_logs": 0,
      "workspace_agent_logs": 0
    },
    "scim_api_key": "string",
    "session_lifetime": {
      "default_duration": 0,
      "default_token_lifetime": 0,
      "disable_expiry_refresh": true,
      "max_admin_token_lifetime": 0,
      "max_token_lifetime": 0,
      "refresh_default_duration": 0
    },
    "ssh_keygen_algorithm": "string",
    "stats_collection": {
      "usage_stats": {
        "enable": true
      }
    },
    "strict_transport_security": 0,
    "strict_transport_security_options": [
      "string"
    ],
    "support": {
      "links": {
        "value": [
          {
            "icon": "bug",
            "location": "navbar",
            "name": "string",
            "target": "string"
          }
        ]
      }
    },
    "swagger": {
      "enable": true
    },
    "telemetry": {
      "enable": true,
      "trace": true,
      "url": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      }
    },
    "terms_of_service_url": "string",
    "tls": {
      "address": {
        "host": "string",
        "port": "string"
      },
      "allow_insecure_ciphers": true,
      "cert_file": [
        "string"
      ],
      "client_auth": "string",
      "client_ca_file": "string",
      "client_cert_file": "string",
      "client_key_file": "string",
      "enable": true,
      "key_file": [
        "string"
      ],
      "min_version": "string",
      "redirect_http": true,
      "supported_ciphers": [
        "string"
      ]
    },
    "trace": {
      "capture_logs": true,
      "data_dog": true,
      "enable": true,
      "honeycomb_api_key": "string"
    },
    "update_check": true,
    "user_quiet_hours_schedule": {
      "allow_user_custom": true,
      "default_schedule": "string"
    },
    "verbose": true,
    "web_terminal_renderer": "string",
    "wgtunnel_host": "string",
    "wildcard_access_url": "string",
    "workspace_hostname_suffix": "string",
    "workspace_prebuilds": {
      "failure_hard_limit": 0,
      "reconciliation_backoff_interval": 0,
      "reconciliation_backoff_lookback": 0,
      "reconciliation_interval": 0
    },
    "write_config": true
  },
  "options": [
    {
      "annotations": {
        "property1": "string",
        "property2": "string"
      },
      "default": "string",
      "description": "string",
      "env": "string",
      "flag": "string",
      "flag_shorthand": "string",
      "group": {
        "description": "string",
        "name": "string",
        "parent": {
          "description": "string",
          "name": "string",
          "parent": {},
          "yaml": "string"
        },
        "yaml": "string"
      },
      "hidden": true,
      "name": "string",
      "required": true,
      "use_instead": [
        {}
      ],
      "value": null,
      "value_source": "",
      "yaml": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.DeploymentConfig](schemas.md#codersdkdeploymentconfig) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## SSH Config

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/deployment/ssh \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/deployment/ssh`

### Example responses

> 200 Response

```json
{
  "hostname_prefix": "string",
  "hostname_suffix": "string",
  "ssh_config_options": {
    "property1": "string",
    "property2": "string"
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.SSHConfigResponse](schemas.md#codersdksshconfigresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get deployment stats

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/deployment/stats \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/deployment/stats`

### Example responses

> 200 Response

```json
{
  "aggregated_from": "2019-08-24T14:15:22Z",
  "collected_at": "2019-08-24T14:15:22Z",
  "next_update_at": "2019-08-24T14:15:22Z",
  "session_count": {
    "jetbrains": 0,
    "reconnecting_pty": 0,
    "ssh": 0,
    "vscode": 0
  },
  "workspaces": {
    "building": 0,
    "connection_latency_ms": {
      "p50": 0,
      "p95": 0
    },
    "failed": 0,
    "pending": 0,
    "running": 0,
    "rx_bytes": 0,
    "stopped": 0,
    "tx_bytes": 0
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.DeploymentStats](schemas.md#codersdkdeploymentstats) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get enabled experiments

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/experiments \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/experiments`

### Example responses

> 200 Response

```json
[
  "example"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                        |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Experiment](schemas.md#codersdkexperiment) |

<h3 id="get-enabled-experiments-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type  | Required | Restrictions | Description |
|----------------|-------|----------|--------------|-------------|
| `[array item]` | array | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get safe experiments

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/experiments/available \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/experiments/available`

### Example responses

> 200 Response

```json
[
  "example"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                        |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Experiment](schemas.md#codersdkexperiment) |

<h3 id="get-safe-experiments-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type  | Required | Restrictions | Description |
|----------------|-------|----------|--------------|-------------|
| `[array item]` | array | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update check

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/updatecheck \
  -H 'Accept: application/json'
```

`GET /api/v2/updatecheck`

### Example responses

> 200 Response

```json
{
  "current": true,
  "url": "string",
  "version": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                 |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UpdateCheckResponse](schemas.md#codersdkupdatecheckresponse) |

## Get token config

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/tokens/tokenconfig \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/keys/tokens/tokenconfig`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "max_token_lifetime": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                 |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TokenConfig](schemas.md#codersdktokenconfig) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# AI Bridge

Source: https://coder.com/docs/reference/api/aibridge

# AI Bridge

## List AI Bridge clients

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/aibridge/clients \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/aibridge/clients`

### Example responses

> 200 Response

```json
[
  "string"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema          |
|--------|---------------------------------------------------------|-------------|-----------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of string |

<h3 id="list-ai-bridge-clients-responseschema">Response Schema</h3>

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List AI Bridge interceptions

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/aibridge/interceptions \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/aibridge/interceptions`

### Parameters

| Name       | In    | Type    | Required | Description                                                                                                            |
|------------|-------|---------|----------|------------------------------------------------------------------------------------------------------------------------|
| `q`        | query | string  | false    | Search query in the format `key:value`. Available keys are: initiator, provider, model, started_after, started_before. |
| `limit`    | query | integer | false    | Page limit                                                                                                             |
| `after_id` | query | string  | false    | Cursor pagination after ID (cannot be used with offset)                                                                |
| `offset`   | query | integer | false    | Offset pagination (cannot be used with after_id)                                                                       |

### Example responses

> 200 Response

```json
{
  "count": 0,
  "results": [
    {
      "api_key_id": "string",
      "client": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator": {
        "avatar_url": "http://example.com",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string",
        "username": "string"
      },
      "metadata": {
        "property1": null,
        "property2": null
      },
      "model": "string",
      "provider": "string",
      "provider_name": "string",
      "started_at": "2019-08-24T14:15:22Z",
      "token_usages": [
        {
          "cache_read_input_tokens": 0,
          "cache_write_input_tokens": 0,
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "input_tokens": 0,
          "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
          "metadata": {
            "property1": null,
            "property2": null
          },
          "output_tokens": 0,
          "provider_response_id": "string"
        }
      ],
      "tool_usages": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "injected": true,
          "input": "string",
          "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
          "invocation_error": "string",
          "metadata": {
            "property1": null,
            "property2": null
          },
          "provider_response_id": "string",
          "server_url": "string",
          "tool": "string"
        }
      ],
      "user_prompts": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
          "metadata": {
            "property1": null,
            "property2": null
          },
          "prompt": "string",
          "provider_response_id": "string"
        }
      ]
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AIBridgeListInterceptionsResponse](schemas.md#codersdkaibridgelistinterceptionsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List AI Bridge models

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/aibridge/models \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/aibridge/models`

### Example responses

> 200 Response

```json
[
  "string"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema          |
|--------|---------------------------------------------------------|-------------|-----------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of string |

<h3 id="list-ai-bridge-models-responseschema">Response Schema</h3>

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List AI Bridge sessions

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/aibridge/sessions \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/aibridge/sessions`

### Parameters

| Name               | In    | Type    | Required | Description                                                                                                                                |
|--------------------|-------|---------|----------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `q`                | query | string  | false    | Search query in the format `key:value`. Available keys are: initiator, provider, model, client, session_id, started_after, started_before. |
| `limit`            | query | integer | false    | Page limit                                                                                                                                 |
| `after_session_id` | query | string  | false    | Cursor pagination after session ID (cannot be used with offset)                                                                            |
| `offset`           | query | integer | false    | Offset pagination (cannot be used with after_session_id)                                                                                   |

### Example responses

> 200 Response

```json
{
  "count": 0,
  "sessions": [
    {
      "client": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "id": "string",
      "initiator": {
        "avatar_url": "http://example.com",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string",
        "username": "string"
      },
      "last_active_at": "2019-08-24T14:15:22Z",
      "last_prompt": "string",
      "metadata": {
        "property1": null,
        "property2": null
      },
      "models": [
        "string"
      ],
      "providers": [
        "string"
      ],
      "started_at": "2019-08-24T14:15:22Z",
      "threads": 0,
      "token_usage_summary": {
        "cache_read_input_tokens": 0,
        "cache_write_input_tokens": 0,
        "input_tokens": 0,
        "output_tokens": 0
      }
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AIBridgeListSessionsResponse](schemas.md#codersdkaibridgelistsessionsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get AI Bridge session threads

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/aibridge/sessions/{session_id} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/aibridge/sessions/{session_id}`

### Parameters

| Name         | In    | Type    | Required | Description                                         |
|--------------|-------|---------|----------|-----------------------------------------------------|
| `session_id` | path  | string  | true     | Session ID (client_session_id or interception UUID) |
| `after_id`   | query | string  | false    | Thread pagination cursor (forward/older)            |
| `before_id`  | query | string  | false    | Thread pagination cursor (backward/newer)           |
| `limit`      | query | integer | false    | Number of threads per page (default 50)             |

### Example responses

> 200 Response

```json
{
  "client": "string",
  "ended_at": "2019-08-24T14:15:22Z",
  "id": "string",
  "initiator": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "metadata": {
    "property1": null,
    "property2": null
  },
  "models": [
    "string"
  ],
  "page_ended_at": "2019-08-24T14:15:22Z",
  "page_started_at": "2019-08-24T14:15:22Z",
  "providers": [
    "string"
  ],
  "started_at": "2019-08-24T14:15:22Z",
  "threads": [
    {
      "agentic_actions": [
        {
          "model": "string",
          "thinking": [
            {
              "text": "string"
            }
          ],
          "token_usage": {
            "cache_read_input_tokens": 0,
            "cache_write_input_tokens": 0,
            "input_tokens": 0,
            "metadata": {
              "property1": null,
              "property2": null
            },
            "output_tokens": 0
          },
          "tool_calls": [
            {
              "created_at": "2019-08-24T14:15:22Z",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "injected": true,
              "input": "string",
              "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
              "metadata": {
                "property1": null,
                "property2": null
              },
              "provider_response_id": "string",
              "server_url": "string",
              "tool": "string"
            }
          ]
        }
      ],
      "credential_hint": "string",
      "credential_kind": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "model": "string",
      "prompt": "string",
      "provider": "string",
      "started_at": "2019-08-24T14:15:22Z",
      "token_usage": {
        "cache_read_input_tokens": 0,
        "cache_write_input_tokens": 0,
        "input_tokens": 0,
        "metadata": {
          "property1": null,
          "property2": null
        },
        "output_tokens": 0
      }
    }
  ],
  "token_usage_summary": {
    "cache_read_input_tokens": 0,
    "cache_write_input_tokens": 0,
    "input_tokens": 0,
    "metadata": {
      "property1": null,
      "property2": null
    },
    "output_tokens": 0
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AIBridgeSessionThreadsResponse](schemas.md#codersdkaibridgesessionthreadsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Agents

Source: https://coder.com/docs/reference/api/agents

# Agents

## Get DERP map updates

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/derp-map \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/derp-map`

### Responses

| Status | Meaning                                                                  | Description         | Schema |
|--------|--------------------------------------------------------------------------|---------------------|--------|
| 101    | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## User-scoped tailnet RPC connection

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/tailnet \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/tailnet`

### Responses

| Status | Meaning                                                                  | Description         | Schema |
|--------|--------------------------------------------------------------------------|---------------------|--------|
| 101    | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Authenticate agent on AWS instance

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaceagents/aws-instance-identity \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaceagents/aws-instance-identity`

> Body parameter

```json
{
  "agent_name": "string",
  "document": "string",
  "signature": "string"
}
```

### Parameters

| Name   | In   | Type                                                                             | Required | Description                                                                                                           |
|--------|------|----------------------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------|
| `body` | body | [agentsdk.AWSInstanceIdentityToken](schemas.md#agentsdkawsinstanceidentitytoken) | true     | Instance identity token. The optional agent_name field disambiguates when multiple agents share the same instance ID. |

### Example responses

> 200 Response

```json
{
  "session_token": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [agentsdk.AuthenticateResponse](schemas.md#agentsdkauthenticateresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Authenticate agent on Azure instance

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaceagents/azure-instance-identity \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaceagents/azure-instance-identity`

> Body parameter

```json
{
  "agent_name": "string",
  "encoding": "string",
  "signature": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                 | Required | Description                                                                                                           |
|--------|------|--------------------------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------|
| `body` | body | [agentsdk.AzureInstanceIdentityToken](schemas.md#agentsdkazureinstanceidentitytoken) | true     | Instance identity token. The optional agent_name field disambiguates when multiple agents share the same instance ID. |

### Example responses

> 200 Response

```json
{
  "session_token": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [agentsdk.AuthenticateResponse](schemas.md#agentsdkauthenticateresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Authenticate agent on Google Cloud instance

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaceagents/google-instance-identity \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaceagents/google-instance-identity`

> Body parameter

```json
{
  "agent_name": "string",
  "json_web_token": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                   | Required | Description                                                                                                           |
|--------|------|----------------------------------------------------------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------|
| `body` | body | [agentsdk.GoogleInstanceIdentityToken](schemas.md#agentsdkgoogleinstanceidentitytoken) | true     | Instance identity token. The optional agent_name field disambiguates when multiple agents share the same instance ID. |

### Example responses

> 200 Response

```json
{
  "session_token": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [agentsdk.AuthenticateResponse](schemas.md#agentsdkauthenticateresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Patch workspace agent app status

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/workspaceagents/me/app-status \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/workspaceagents/me/app-status`

> Body parameter

```json
{
  "app_slug": "string",
  "icon": "string",
  "message": "string",
  "needs_user_attention": true,
  "state": "working",
  "uri": "string"
}
```

### Parameters

| Name   | In   | Type                                                         | Required | Description |
|--------|------|--------------------------------------------------------------|----------|-------------|
| `body` | body | [agentsdk.PatchAppStatus](schemas.md#agentsdkpatchappstatus) | true     | app status  |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace agent external auth

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/external-auth?match=string&id=string \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/me/external-auth`

### Parameters

| Name     | In    | Type    | Required | Description                       |
|----------|-------|---------|----------|-----------------------------------|
| `match`  | query | string  | true     | Match                             |
| `id`     | query | string  | true     | Provider ID                       |
| `listen` | query | boolean | false    | Wait for a new token to be issued |

### Example responses

> 200 Response

```json
{
  "access_token": "string",
  "password": "string",
  "token_extra": {},
  "type": "string",
  "url": "string",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [agentsdk.ExternalAuthResponse](schemas.md#agentsdkexternalauthresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Removed: Get workspace agent git auth

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/gitauth?match=string&id=string \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/me/gitauth`

### Parameters

| Name     | In    | Type    | Required | Description                       |
|----------|-------|---------|----------|-----------------------------------|
| `match`  | query | string  | true     | Match                             |
| `id`     | query | string  | true     | Provider ID                       |
| `listen` | query | boolean | false    | Wait for a new token to be issued |

### Example responses

> 200 Response

```json
{
  "access_token": "string",
  "password": "string",
  "token_extra": {},
  "type": "string",
  "url": "string",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [agentsdk.ExternalAuthResponse](schemas.md#agentsdkexternalauthresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace agent Git SSH key

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/gitsshkey \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/me/gitsshkey`

### Example responses

> 200 Response

```json
{
  "private_key": "string",
  "public_key": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [agentsdk.GitSSHKey](schemas.md#agentsdkgitsshkey) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Post workspace agent log source

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/log-source \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaceagents/me/log-source`

> Body parameter

```json
{
  "display_name": "string",
  "icon": "string",
  "id": "string"
}
```

### Parameters

| Name   | In   | Type                                                                     | Required | Description        |
|--------|------|--------------------------------------------------------------------------|----------|--------------------|
| `body` | body | [agentsdk.PostLogSourceRequest](schemas.md#agentsdkpostlogsourcerequest) | true     | Log source request |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                         |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgentLogSource](schemas.md#codersdkworkspaceagentlogsource) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Patch workspace agent logs

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/workspaceagents/me/logs \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/workspaceagents/me/logs`

> Body parameter

```json
{
  "log_source_id": "string",
  "logs": [
    {
      "created_at": "string",
      "level": "trace",
      "output": "string"
    }
  ]
}
```

### Parameters

| Name   | In   | Type                                               | Required | Description |
|--------|------|----------------------------------------------------|----------|-------------|
| `body` | body | [agentsdk.PatchLogs](schemas.md#agentsdkpatchlogs) | true     | logs        |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace agent reinitialization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/me/reinit \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/me/reinit`

### Parameters

| Name   | In    | Type    | Required | Description                     |
|--------|-------|---------|----------|---------------------------------|
| `wait` | query | boolean | false    | Opt in to durable reinit checks |

### Example responses

> 200 Response

```json
{
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "reason": "prebuild_claimed",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Responses

| Status | Meaning                                                       | Description | Schema                                                                     |
|--------|---------------------------------------------------------------|-------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)       | OK          | [agentsdk.ReinitializationEvent](schemas.md#agentsdkreinitializationevent) |
| 409    | [Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) | Conflict    | [codersdk.Response](schemas.md#codersdkresponse)                           |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace agent by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |

### Example responses

> 200 Response

```json
{
  "api_version": "string",
  "apps": [
    {
      "command": "string",
      "display_name": "string",
      "external": true,
      "group": "string",
      "health": "disabled",
      "healthcheck": {
        "interval": 0,
        "threshold": 0,
        "url": "string"
      },
      "hidden": true,
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "open_in": "slim-window",
      "sharing_level": "owner",
      "slug": "string",
      "statuses": [
        {
          "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
          "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
          "created_at": "2019-08-24T14:15:22Z",
          "icon": "string",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "message": "string",
          "needs_user_attention": true,
          "state": "working",
          "uri": "string",
          "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
        }
      ],
      "subdomain": true,
      "subdomain_name": "string",
      "tooltip": "string",
      "url": "string"
    }
  ],
  "architecture": "string",
  "connection_timeout_seconds": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "directory": "string",
  "disconnected_at": "2019-08-24T14:15:22Z",
  "display_apps": [
    "vscode"
  ],
  "environment_variables": {
    "property1": "string",
    "property2": "string"
  },
  "expanded_directory": "string",
  "first_connected_at": "2019-08-24T14:15:22Z",
  "health": {
    "healthy": false,
    "reason": "agent has lost connection"
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "instance_id": "string",
  "last_connected_at": "2019-08-24T14:15:22Z",
  "latency": {
    "property1": {
      "latency_ms": 0,
      "preferred": true
    },
    "property2": {
      "latency_ms": 0,
      "preferred": true
    }
  },
  "lifecycle_state": "created",
  "log_sources": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "display_name": "string",
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
    }
  ],
  "logs_length": 0,
  "logs_overflowed": true,
  "name": "string",
  "operating_system": "string",
  "parent_id": {
    "uuid": "string",
    "valid": true
  },
  "ready_at": "2019-08-24T14:15:22Z",
  "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  "scripts": [
    {
      "cron": "string",
      "display_name": "string",
      "exit_code": 0,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "log_path": "string",
      "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
      "run_on_start": true,
      "run_on_stop": true,
      "script": "string",
      "start_blocks_login": true,
      "status": "ok",
      "timeout": 0
    }
  ],
  "started_at": "2019-08-24T14:15:22Z",
  "startup_script_behavior": "blocking",
  "status": "connecting",
  "subsystems": [
    "envbox"
  ],
  "troubleshooting_url": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "version": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgent](schemas.md#codersdkworkspaceagent) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get connection info for workspace agent

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/connection \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/connection`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |

### Example responses

> 200 Response

```json
{
  "derp_force_websockets": true,
  "derp_map": {
    "homeParams": {
      "regionScore": {
        "property1": 0,
        "property2": 0
      }
    },
    "omitDefaultRegions": true,
    "regions": {
      "property1": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      },
      "property2": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      }
    }
  },
  "disable_direct_connections": true,
  "hostname_suffix": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                         |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [workspacesdk.AgentConnectionInfo](schemas.md#workspacesdkagentconnectioninfo) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get running containers for workspace agent

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/containers?label=string \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/containers`

### Parameters

| Name             | In    | Type              | Required | Description        |
|------------------|-------|-------------------|----------|--------------------|
| `workspaceagent` | path  | string(uuid)      | true     | Workspace agent ID |
| `label`          | query | string(key=value) | true     | Labels             |

### Example responses

> 200 Response

```json
{
  "containers": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "string",
      "image": "string",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "name": "string",
      "ports": [
        {
          "host_ip": "string",
          "host_port": 0,
          "network": "string",
          "port": 0
        }
      ],
      "running": true,
      "status": "string",
      "volumes": {
        "property1": "string",
        "property2": "string"
      }
    }
  ],
  "devcontainers": [
    {
      "agent": {
        "directory": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string"
      },
      "config_path": "string",
      "container": {
        "created_at": "2019-08-24T14:15:22Z",
        "id": "string",
        "image": "string",
        "labels": {
          "property1": "string",
          "property2": "string"
        },
        "name": "string",
        "ports": [
          {
            "host_ip": "string",
            "host_port": 0,
            "network": "string",
            "port": 0
          }
        ],
        "running": true,
        "status": "string",
        "volumes": {
          "property1": "string",
          "property2": "string"
        }
      },
      "dirty": true,
      "error": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "status": "running",
      "subagent_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_folder": "string"
    }
  ],
  "warnings": [
    "string"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgentListContainersResponse](schemas.md#codersdkworkspaceagentlistcontainersresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete devcontainer for workspace agent

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/containers/devcontainers/{devcontainer} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/workspaceagents/{workspaceagent}/containers/devcontainers/{devcontainer}`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |
| `devcontainer`   | path | string       | true     | Devcontainer ID    |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Recreate devcontainer for workspace agent

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/containers/devcontainers/{devcontainer}/recreate \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaceagents/{workspaceagent}/containers/devcontainers/{devcontainer}/recreate`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |
| `devcontainer`   | path | string       | true     | Devcontainer ID    |

### Example responses

> 202 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                       | Description | Schema                                           |
|--------|---------------------------------------------------------------|-------------|--------------------------------------------------|
| 202    | [Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) | Accepted    | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Watch workspace agent for container updates

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/containers/watch \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/containers/watch`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |

### Example responses

> 200 Response

```json
{
  "containers": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "string",
      "image": "string",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "name": "string",
      "ports": [
        {
          "host_ip": "string",
          "host_port": 0,
          "network": "string",
          "port": 0
        }
      ],
      "running": true,
      "status": "string",
      "volumes": {
        "property1": "string",
        "property2": "string"
      }
    }
  ],
  "devcontainers": [
    {
      "agent": {
        "directory": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string"
      },
      "config_path": "string",
      "container": {
        "created_at": "2019-08-24T14:15:22Z",
        "id": "string",
        "image": "string",
        "labels": {
          "property1": "string",
          "property2": "string"
        },
        "name": "string",
        "ports": [
          {
            "host_ip": "string",
            "host_port": 0,
            "network": "string",
            "port": 0
          }
        ],
        "running": true,
        "status": "string",
        "volumes": {
          "property1": "string",
          "property2": "string"
        }
      },
      "dirty": true,
      "error": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "status": "running",
      "subagent_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_folder": "string"
    }
  ],
  "warnings": [
    "string"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgentListContainersResponse](schemas.md#codersdkworkspaceagentlistcontainersresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Coordinate workspace agent

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/coordinate \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/coordinate`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |

### Responses

| Status | Meaning                                                                  | Description         | Schema |
|--------|--------------------------------------------------------------------------|---------------------|--------|
| 101    | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get listening ports for workspace agent

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/listening-ports \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/listening-ports`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |

### Example responses

> 200 Response

```json
{
  "ports": [
    {
      "network": "string",
      "port": 0,
      "process_name": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgentListeningPortsResponse](schemas.md#codersdkworkspaceagentlisteningportsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get logs by workspace agent

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/logs \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/logs`

### Parameters

| Name             | In    | Type         | Required | Description                                                                                                                                 |
|------------------|-------|--------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `workspaceagent` | path  | string(uuid) | true     | Workspace agent ID                                                                                                                          |
| `before`         | query | integer      | false    | Before log id                                                                                                                               |
| `after`          | query | integer      | false    | After log id                                                                                                                                |
| `follow`         | query | boolean      | false    | Follow log stream                                                                                                                           |
| `no_compression` | query | boolean      | false    | Disable compression for WebSocket connection                                                                                                |
| `format`         | query | string       | false    | Log output format. Accepted: 'json' (default), 'text' (plain text with RFC3339 timestamps and ANSI colors). Not supported with follow=true. |

#### Enumerated Values

| Parameter | Value(s)       |
|-----------|----------------|
| `format`  | `json`, `text` |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "id": 0,
    "level": "trace",
    "output": "string",
    "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.WorkspaceAgentLog](schemas.md#codersdkworkspaceagentlog) |

<h3 id="get-logs-by-workspace-agent-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type                                             | Required | Restrictions | Description |
|----------------|--------------------------------------------------|----------|--------------|-------------|
| `[array item]` | array                                            | false    |              |             |
| `» created_at` | string(date-time)                                | false    |              |             |
| `» id`         | integer                                          | false    |              |             |
| `» level`      | [codersdk.LogLevel](schemas.md#codersdkloglevel) | false    |              |             |
| `» output`     | string                                           | false    |              |             |
| `» source_id`  | string(uuid)                                     | false    |              |             |

#### Enumerated Values

| Property | Value(s)                                  |
|----------|-------------------------------------------|
| `level`  | `debug`, `error`, `info`, `trace`, `warn` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Open PTY to workspace agent

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/pty \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/pty`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspaceagent` | path | string(uuid) | true     | Workspace agent ID |

### Responses

| Status | Meaning                                                                  | Description         | Schema |
|--------|--------------------------------------------------------------------------|---------------------|--------|
| 101    | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Removed: Get logs by workspace agent

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent}/startup-logs \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceagents/{workspaceagent}/startup-logs`

### Parameters

| Name             | In    | Type         | Required | Description                                  |
|------------------|-------|--------------|----------|----------------------------------------------|
| `workspaceagent` | path  | string(uuid) | true     | Workspace agent ID                           |
| `before`         | query | integer      | false    | Before log id                                |
| `after`          | query | integer      | false    | After log id                                 |
| `follow`         | query | boolean      | false    | Follow log stream                            |
| `no_compression` | query | boolean      | false    | Disable compression for WebSocket connection |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "id": 0,
    "level": "trace",
    "output": "string",
    "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.WorkspaceAgentLog](schemas.md#codersdkworkspaceagentlog) |

<h3 id="removed:-get-logs-by-workspace-agent-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type                                             | Required | Restrictions | Description |
|----------------|--------------------------------------------------|----------|--------------|-------------|
| `[array item]` | array                                            | false    |              |             |
| `» created_at` | string(date-time)                                | false    |              |             |
| `» id`         | integer                                          | false    |              |             |
| `» level`      | [codersdk.LogLevel](schemas.md#codersdkloglevel) | false    |              |             |
| `» output`     | string                                           | false    |              |             |
| `» source_id`  | string(uuid)                                     | false    |              |             |

#### Enumerated Values

| Property | Value(s)                                  |
|----------|-------------------------------------------|
| `level`  | `debug`, `error`, `info`, `trace`, `warn` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Applications

Source: https://coder.com/docs/reference/api/applications

# Applications

## Redirect to URI with encrypted API key

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/applications/auth-redirect \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/applications/auth-redirect`

### Parameters

| Name           | In    | Type   | Required | Description          |
|----------------|-------|--------|----------|----------------------|
| `redirect_uri` | query | string | false    | Redirect destination |

### Responses

| Status | Meaning                                                                 | Description        | Schema |
|--------|-------------------------------------------------------------------------|--------------------|--------|
| 307    | [Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) | Temporary Redirect |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get applications host

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/applications/host \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/applications/host`

### Example responses

> 200 Response

```json
{
  "host": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AppHostResponse](schemas.md#codersdkapphostresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Audit

Source: https://coder.com/docs/reference/api/audit

# Audit

## Get audit logs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/audit?limit=0 \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/audit`

### Parameters

| Name     | In    | Type    | Required | Description  |
|----------|-------|---------|----------|--------------|
| `q`      | query | string  | false    | Search query |
| `limit`  | query | integer | true     | Page limit   |
| `offset` | query | integer | false    | Page offset  |

### Example responses

> 200 Response

```json
{
  "audit_logs": [
    {
      "action": "create",
      "additional_fields": {},
      "description": "string",
      "diff": {
        "property1": {
          "new": null,
          "old": null,
          "secret": true
        },
        "property2": {
          "new": null,
          "old": null,
          "secret": true
        }
      },
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "ip": "string",
      "is_deleted": true,
      "organization": {
        "display_name": "string",
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "request_id": "266ea41d-adf5-480b-af50-15b940c2b846",
      "resource_icon": "string",
      "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
      "resource_link": "string",
      "resource_target": "string",
      "resource_type": "template",
      "status_code": 0,
      "time": "2019-08-24T14:15:22Z",
      "user": {
        "avatar_url": "http://example.com",
        "created_at": "2019-08-24T14:15:22Z",
        "email": "user@example.com",
        "has_ai_seat": true,
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "is_service_account": true,
        "last_seen_at": "2019-08-24T14:15:22Z",
        "login_type": "",
        "name": "string",
        "organization_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "roles": [
          {
            "display_name": "string",
            "name": "string",
            "organization_id": "string"
          }
        ],
        "status": "active",
        "theme_preference": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "username": "string"
      },
      "user_agent": "string"
    }
  ],
  "count": 0,
  "count_cap": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AuditLogResponse](schemas.md#codersdkauditlogresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Authentication

Source: https://coder.com/docs/reference/api/authentication

# Authentication

Long-lived tokens can be generated to perform actions on behalf of your user account:

```shell
coder tokens create
```

You can use tokens with the Coder's REST API using the `Coder-Session-Token` HTTP header.

```console
curl 'http://coder-server:8080/api/v2/workspaces' \
  -H 'Coder-Session-Token: *****'
```

---

# Authorization

Source: https://coder.com/docs/reference/api/authorization

# Authorization

## List API key scopes

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/auth/scopes \
  -H 'Accept: application/json'
```

`GET /api/v2/auth/scopes`

### Example responses

> 200 Response

```json
{
  "external": [
    "all"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ExternalAPIKeyScopes](schemas.md#codersdkexternalapikeyscopes) |

## Check authorization

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/authcheck \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/authcheck`

> Body parameter

```json
{
  "checks": {
    "property1": {
      "action": "create",
      "object": {
        "any_org": true,
        "organization_id": "string",
        "owner_id": "string",
        "resource_id": "string",
        "resource_type": "*"
      }
    },
    "property2": {
      "action": "create",
      "object": {
        "any_org": true,
        "organization_id": "string",
        "owner_id": "string",
        "resource_id": "string",
        "resource_type": "*"
      }
    }
  }
}
```

### Parameters

| Name   | In   | Type                                                                     | Required | Description           |
|--------|------|--------------------------------------------------------------------------|----------|-----------------------|
| `body` | body | [codersdk.AuthorizationRequest](schemas.md#codersdkauthorizationrequest) | true     | Authorization request |

### Example responses

> 200 Response

```json
{
  "property1": true,
  "property2": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                     |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AuthorizationResponse](schemas.md#codersdkauthorizationresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Log in user

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/login \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'
```

`POST /api/v2/users/login`

> Body parameter

```json
{
  "email": "user@example.com",
  "password": "string"
}
```

### Parameters

| Name   | In   | Type                                                                             | Required | Description   |
|--------|------|----------------------------------------------------------------------------------|----------|---------------|
| `body` | body | [codersdk.LoginWithPasswordRequest](schemas.md#codersdkloginwithpasswordrequest) | true     | Login request |

### Example responses

> 201 Response

```json
{
  "session_token": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                             |
|--------|--------------------------------------------------------------|-------------|------------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.LoginWithPasswordResponse](schemas.md#codersdkloginwithpasswordresponse) |

## Change password with a one-time passcode

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/otp/change-password \
  -H 'Content-Type: application/json'
```

`POST /api/v2/users/otp/change-password`

> Body parameter

```json
{
  "email": "user@example.com",
  "one_time_passcode": "string",
  "password": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                                             | Required | Description             |
|--------|------|------------------------------------------------------------------------------------------------------------------|----------|-------------------------|
| `body` | body | [codersdk.ChangePasswordWithOneTimePasscodeRequest](schemas.md#codersdkchangepasswordwithonetimepasscoderequest) | true     | Change password request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

## Request one-time passcode

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/otp/request \
  -H 'Content-Type: application/json'
```

`POST /api/v2/users/otp/request`

> Body parameter

```json
{
  "email": "user@example.com"
}
```

### Parameters

| Name   | In   | Type                                                                                       | Required | Description               |
|--------|------|--------------------------------------------------------------------------------------------|----------|---------------------------|
| `body` | body | [codersdk.RequestOneTimePasscodeRequest](schemas.md#codersdkrequestonetimepasscoderequest) | true     | One-time passcode request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

## Validate user password

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/validate-password \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/validate-password`

> Body parameter

```json
{
  "password": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                   | Required | Description                    |
|--------|------|----------------------------------------------------------------------------------------|----------|--------------------------------|
| `body` | body | [codersdk.ValidateUserPasswordRequest](schemas.md#codersdkvalidateuserpasswordrequest) | true     | Validate user password request |

### Example responses

> 200 Response

```json
{
  "details": "string",
  "valid": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ValidateUserPasswordResponse](schemas.md#codersdkvalidateuserpasswordresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Convert user from password to oauth authentication

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/{user}/convert-login \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/{user}/convert-login`

> Body parameter

```json
{
  "password": "string",
  "to_type": ""
}
```

### Parameters

| Name   | In   | Type                                                                   | Required | Description          |
|--------|------|------------------------------------------------------------------------|----------|----------------------|
| `user` | path | string                                                                 | true     | User ID, name, or me |
| `body` | body | [codersdk.ConvertLoginRequest](schemas.md#codersdkconvertloginrequest) | true     | Convert request      |

### Example responses

> 201 Response

```json
{
  "expires_at": "2019-08-24T14:15:22Z",
  "state_string": "string",
  "to_type": "",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                         |
|--------|--------------------------------------------------------------|-------------|--------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.OAuthConversionResponse](schemas.md#codersdkoauthconversionresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Builds

Source: https://coder.com/docs/reference/api/builds

# Builds

## Get workspace build by user, workspace name, and build number

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacename}/builds/{buildnumber} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/workspace/{workspacename}/builds/{buildnumber}`

### Parameters

| Name            | In   | Type           | Required | Description          |
|-----------------|------|----------------|----------|----------------------|
| `user`          | path | string         | true     | User ID, name, or me |
| `workspacename` | path | string         | true     | Workspace name       |
| `buildnumber`   | path | string(number) | true     | Build number         |

### Example responses

> 200 Response

```json
{
  "build_number": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "daily_cost": 0,
  "deadline": "2019-08-24T14:15:22Z",
  "has_ai_task": true,
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "initiator_name": "string",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "max_deadline": "2019-08-24T14:15:22Z",
  "reason": "initiator",
  "resources": [
    {
      "agents": [
        {
          "api_version": "string",
          "apps": [
            {
              "command": "string",
              "display_name": "string",
              "external": true,
              "group": "string",
              "health": "disabled",
              "healthcheck": {
                "interval": 0,
                "threshold": 0,
                "url": "string"
              },
              "hidden": true,
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "open_in": "slim-window",
              "sharing_level": "owner",
              "slug": "string",
              "statuses": [
                {
                  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                  "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                  "created_at": "2019-08-24T14:15:22Z",
                  "icon": "string",
                  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                  "message": "string",
                  "needs_user_attention": true,
                  "state": "working",
                  "uri": "string",
                  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                }
              ],
              "subdomain": true,
              "subdomain_name": "string",
              "tooltip": "string",
              "url": "string"
            }
          ],
          "architecture": "string",
          "connection_timeout_seconds": 0,
          "created_at": "2019-08-24T14:15:22Z",
          "directory": "string",
          "disconnected_at": "2019-08-24T14:15:22Z",
          "display_apps": [
            "vscode"
          ],
          "environment_variables": {
            "property1": "string",
            "property2": "string"
          },
          "expanded_directory": "string",
          "first_connected_at": "2019-08-24T14:15:22Z",
          "health": {
            "healthy": false,
            "reason": "agent has lost connection"
          },
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "instance_id": "string",
          "last_connected_at": "2019-08-24T14:15:22Z",
          "latency": {
            "property1": {
              "latency_ms": 0,
              "preferred": true
            },
            "property2": {
              "latency_ms": 0,
              "preferred": true
            }
          },
          "lifecycle_state": "created",
          "log_sources": [
            {
              "created_at": "2019-08-24T14:15:22Z",
              "display_name": "string",
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
            }
          ],
          "logs_length": 0,
          "logs_overflowed": true,
          "name": "string",
          "operating_system": "string",
          "parent_id": {
            "uuid": "string",
            "valid": true
          },
          "ready_at": "2019-08-24T14:15:22Z",
          "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
          "scripts": [
            {
              "cron": "string",
              "display_name": "string",
              "exit_code": 0,
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "log_path": "string",
              "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
              "run_on_start": true,
              "run_on_stop": true,
              "script": "string",
              "start_blocks_login": true,
              "status": "ok",
              "timeout": 0
            }
          ],
          "started_at": "2019-08-24T14:15:22Z",
          "startup_script_behavior": "blocking",
          "status": "connecting",
          "subsystems": [
            "envbox"
          ],
          "troubleshooting_url": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "version": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "daily_cost": 0,
      "hide": true,
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "metadata": [
        {
          "key": "string",
          "sensitive": true,
          "value": "string"
        }
      ],
      "name": "string",
      "type": "string",
      "workspace_transition": "start"
    }
  ],
  "status": "pending",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_name": "string",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "transition": "start",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
  "workspace_name": "string",
  "workspace_owner_avatar_url": "string",
  "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
  "workspace_owner_name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace build

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspacebuilds/{workspacebuild}`

### Parameters

| Name             | In   | Type   | Required | Description        |
|------------------|------|--------|----------|--------------------|
| `workspacebuild` | path | string | true     | Workspace build ID |

### Example responses

> 200 Response

```json
{
  "build_number": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "daily_cost": 0,
  "deadline": "2019-08-24T14:15:22Z",
  "has_ai_task": true,
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "initiator_name": "string",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "max_deadline": "2019-08-24T14:15:22Z",
  "reason": "initiator",
  "resources": [
    {
      "agents": [
        {
          "api_version": "string",
          "apps": [
            {
              "command": "string",
              "display_name": "string",
              "external": true,
              "group": "string",
              "health": "disabled",
              "healthcheck": {
                "interval": 0,
                "threshold": 0,
                "url": "string"
              },
              "hidden": true,
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "open_in": "slim-window",
              "sharing_level": "owner",
              "slug": "string",
              "statuses": [
                {
                  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                  "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                  "created_at": "2019-08-24T14:15:22Z",
                  "icon": "string",
                  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                  "message": "string",
                  "needs_user_attention": true,
                  "state": "working",
                  "uri": "string",
                  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                }
              ],
              "subdomain": true,
              "subdomain_name": "string",
              "tooltip": "string",
              "url": "string"
            }
          ],
          "architecture": "string",
          "connection_timeout_seconds": 0,
          "created_at": "2019-08-24T14:15:22Z",
          "directory": "string",
          "disconnected_at": "2019-08-24T14:15:22Z",
          "display_apps": [
            "vscode"
          ],
          "environment_variables": {
            "property1": "string",
            "property2": "string"
          },
          "expanded_directory": "string",
          "first_connected_at": "2019-08-24T14:15:22Z",
          "health": {
            "healthy": false,
            "reason": "agent has lost connection"
          },
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "instance_id": "string",
          "last_connected_at": "2019-08-24T14:15:22Z",
          "latency": {
            "property1": {
              "latency_ms": 0,
              "preferred": true
            },
            "property2": {
              "latency_ms": 0,
              "preferred": true
            }
          },
          "lifecycle_state": "created",
          "log_sources": [
            {
              "created_at": "2019-08-24T14:15:22Z",
              "display_name": "string",
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
            }
          ],
          "logs_length": 0,
          "logs_overflowed": true,
          "name": "string",
          "operating_system": "string",
          "parent_id": {
            "uuid": "string",
            "valid": true
          },
          "ready_at": "2019-08-24T14:15:22Z",
          "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
          "scripts": [
            {
              "cron": "string",
              "display_name": "string",
              "exit_code": 0,
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "log_path": "string",
              "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
              "run_on_start": true,
              "run_on_stop": true,
              "script": "string",
              "start_blocks_login": true,
              "status": "ok",
              "timeout": 0
            }
          ],
          "started_at": "2019-08-24T14:15:22Z",
          "startup_script_behavior": "blocking",
          "status": "connecting",
          "subsystems": [
            "envbox"
          ],
          "troubleshooting_url": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "version": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "daily_cost": 0,
      "hide": true,
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "metadata": [
        {
          "key": "string",
          "sensitive": true,
          "value": "string"
        }
      ],
      "name": "string",
      "type": "string",
      "workspace_transition": "start"
    }
  ],
  "status": "pending",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_name": "string",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "transition": "start",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
  "workspace_name": "string",
  "workspace_owner_avatar_url": "string",
  "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
  "workspace_owner_name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Cancel workspace build

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/cancel \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/workspacebuilds/{workspacebuild}/cancel`

### Parameters

| Name             | In    | Type   | Required | Description                                                                                                                                                                              |
|------------------|-------|--------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `workspacebuild` | path  | string | true     | Workspace build ID                                                                                                                                                                       |
| `expect_status`  | query | string | false    | Expected status of the job. If expect_status is supplied, the request will be rejected with 412 Precondition Failed if the job doesn't match the state when performing the cancellation. |

#### Enumerated Values

| Parameter       | Value(s)             |
|-----------------|----------------------|
| `expect_status` | `pending`, `running` |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace build logs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/logs \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspacebuilds/{workspacebuild}/logs`

### Parameters

| Name             | In    | Type    | Required | Description                                                                                                                                 |
|------------------|-------|---------|----------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `workspacebuild` | path  | string  | true     | Workspace build ID                                                                                                                          |
| `before`         | query | integer | false    | Before log id                                                                                                                               |
| `after`          | query | integer | false    | After log id                                                                                                                                |
| `follow`         | query | boolean | false    | Follow log stream                                                                                                                           |
| `format`         | query | string  | false    | Log output format. Accepted: 'json' (default), 'text' (plain text with RFC3339 timestamps and ANSI colors). Not supported with follow=true. |

#### Enumerated Values

| Parameter | Value(s)       |
|-----------|----------------|
| `format`  | `json`, `text` |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "id": 0,
    "log_level": "trace",
    "log_source": "provisioner_daemon",
    "output": "string",
    "stage": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) |

<h3 id="get-workspace-build-logs-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type                                               | Required | Restrictions | Description |
|----------------|----------------------------------------------------|----------|--------------|-------------|
| `[array item]` | array                                              | false    |              |             |
| `» created_at` | string(date-time)                                  | false    |              |             |
| `» id`         | integer                                            | false    |              |             |
| `» log_level`  | [codersdk.LogLevel](schemas.md#codersdkloglevel)   | false    |              |             |
| `» log_source` | [codersdk.LogSource](schemas.md#codersdklogsource) | false    |              |             |
| `» output`     | string                                             | false    |              |             |
| `» stage`      | string                                             | false    |              |             |

#### Enumerated Values

| Property     | Value(s)                                  |
|--------------|-------------------------------------------|
| `log_level`  | `debug`, `error`, `info`, `trace`, `warn` |
| `log_source` | `provisioner`, `provisioner_daemon`       |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get build parameters for workspace build

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/parameters \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspacebuilds/{workspacebuild}/parameters`

### Parameters

| Name             | In   | Type   | Required | Description        |
|------------------|------|--------|----------|--------------------|
| `workspacebuild` | path | string | true     | Workspace build ID |

### Example responses

> 200 Response

```json
[
  {
    "name": "string",
    "value": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                  |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.WorkspaceBuildParameter](schemas.md#codersdkworkspacebuildparameter) |

<h3 id="get-build-parameters-for-workspace-build-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `[array item]` | array  | false    |              |             |
| `» name`       | string | false    |              |             |
| `» value`      | string | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Removed: Get workspace resources for workspace build

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/resources \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspacebuilds/{workspacebuild}/resources`

### Parameters

| Name             | In   | Type   | Required | Description        |
|------------------|------|--------|----------|--------------------|
| `workspacebuild` | path | string | true     | Workspace build ID |

### Example responses

> 200 Response

```json
[
  {
    "agents": [
      {
        "api_version": "string",
        "apps": [
          {
            "command": "string",
            "display_name": "string",
            "external": true,
            "group": "string",
            "health": "disabled",
            "healthcheck": {
              "interval": 0,
              "threshold": 0,
              "url": "string"
            },
            "hidden": true,
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "open_in": "slim-window",
            "sharing_level": "owner",
            "slug": "string",
            "statuses": [
              {
                "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                "created_at": "2019-08-24T14:15:22Z",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "message": "string",
                "needs_user_attention": true,
                "state": "working",
                "uri": "string",
                "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
              }
            ],
            "subdomain": true,
            "subdomain_name": "string",
            "tooltip": "string",
            "url": "string"
          }
        ],
        "architecture": "string",
        "connection_timeout_seconds": 0,
        "created_at": "2019-08-24T14:15:22Z",
        "directory": "string",
        "disconnected_at": "2019-08-24T14:15:22Z",
        "display_apps": [
          "vscode"
        ],
        "environment_variables": {
          "property1": "string",
          "property2": "string"
        },
        "expanded_directory": "string",
        "first_connected_at": "2019-08-24T14:15:22Z",
        "health": {
          "healthy": false,
          "reason": "agent has lost connection"
        },
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "instance_id": "string",
        "last_connected_at": "2019-08-24T14:15:22Z",
        "latency": {
          "property1": {
            "latency_ms": 0,
            "preferred": true
          },
          "property2": {
            "latency_ms": 0,
            "preferred": true
          }
        },
        "lifecycle_state": "created",
        "log_sources": [
          {
            "created_at": "2019-08-24T14:15:22Z",
            "display_name": "string",
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
          }
        ],
        "logs_length": 0,
        "logs_overflowed": true,
        "name": "string",
        "operating_system": "string",
        "parent_id": {
          "uuid": "string",
          "valid": true
        },
        "ready_at": "2019-08-24T14:15:22Z",
        "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
        "scripts": [
          {
            "cron": "string",
            "display_name": "string",
            "exit_code": 0,
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "log_path": "string",
            "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
            "run_on_start": true,
            "run_on_stop": true,
            "script": "string",
            "start_blocks_login": true,
            "status": "ok",
            "timeout": 0
          }
        ],
        "started_at": "2019-08-24T14:15:22Z",
        "startup_script_behavior": "blocking",
        "status": "connecting",
        "subsystems": [
          "envbox"
        ],
        "troubleshooting_url": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "version": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "hide": true,
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
    "metadata": [
      {
        "key": "string",
        "sensitive": true,
        "value": "string"
      }
    ],
    "name": "string",
    "type": "string",
    "workspace_transition": "start"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) |

<h3 id="removed:-get-workspace-resources-for-workspace-build-responseschema">Response Schema</h3>

Status Code **200**

| Name                            | Type                                                                                                   | Required | Restrictions | Description                                                                                                                                                                                                                                    |
|---------------------------------|--------------------------------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                  | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `» agents`                      | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» api_version`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» apps`                       | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» command`                   | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              | Display name is a friendly name for the app.                                                                                                                                                                                                   |
| `»»» external`                  | boolean                                                                                                | false    |              | External specifies whether the URL should be opened externally on the client or not.                                                                                                                                                           |
| `»»» group`                     | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» health`                    | [codersdk.WorkspaceAppHealth](schemas.md#codersdkworkspaceapphealth)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» healthcheck`               | [codersdk.Healthcheck](schemas.md#codersdkhealthcheck)                                                 | false    |              | Healthcheck specifies the configuration for checking app health.                                                                                                                                                                               |
| `»»»» interval`                 | integer                                                                                                | false    |              | Interval specifies the seconds between each health check.                                                                                                                                                                                      |
| `»»»» threshold`                | integer                                                                                                | false    |              | Threshold specifies the number of consecutive failed health checks before returning "unhealthy".                                                                                                                                               |
| `»»»» url`                      | string                                                                                                 | false    |              | URL specifies the endpoint to check for the app health.                                                                                                                                                                                        |
| `»»» hidden`                    | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» icon`                      | string                                                                                                 | false    |              | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard.                                                                                                                                               |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» open_in`                   | [codersdk.WorkspaceAppOpenIn](schemas.md#codersdkworkspaceappopenin)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» sharing_level`             | [codersdk.WorkspaceAppSharingLevel](schemas.md#codersdkworkspaceappsharinglevel)                       | false    |              |                                                                                                                                                                                                                                                |
| `»»» slug`                      | string                                                                                                 | false    |              | Slug is a unique identifier within the agent.                                                                                                                                                                                                  |
| `»»» statuses`                  | array                                                                                                  | false    |              | Statuses is a list of statuses for the app.                                                                                                                                                                                                    |
| `»»»» agent_id`                 | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» app_id`                   | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» created_at`               | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»»» icon`                     | string                                                                                                 | false    |              | Deprecated: This field is unused and will be removed in a future version. Icon is an external URL to an icon that will be rendered in the UI.                                                                                                  |
| `»»»» id`                       | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» message`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» needs_user_attention`     | boolean                                                                                                | false    |              | Deprecated: This field is unused and will be removed in a future version. NeedsUserAttention specifies whether the status needs user attention.                                                                                                |
| `»»»» state`                    | [codersdk.WorkspaceAppStatusState](schemas.md#codersdkworkspaceappstatusstate)                         | false    |              |                                                                                                                                                                                                                                                |
| `»»»» uri`                      | string                                                                                                 | false    |              | Uri is the URI of the resource that the status is for. e.g. https://github.com/org/repo/pull/123 e.g. file:///path/to/file                                                                                                                     |
| `»»»» workspace_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» subdomain`                 | boolean                                                                                                | false    |              | Subdomain denotes whether the app should be accessed via a path on the `coder server` or via a hostname-based dev URL. If this is set to true and there is no app wildcard configured on the server, the app will not be accessible in the UI. |
| `»»» subdomain_name`            | string                                                                                                 | false    |              | Subdomain name is the application domain exposed on the `coder server`.                                                                                                                                                                        |
| `»»» tooltip`                   | string                                                                                                 | false    |              | Tooltip is an optional markdown supported field that is displayed when hovering over workspace apps in the UI.                                                                                                                                 |
| `»»» url`                       | string                                                                                                 | false    |              | URL is the address being proxied to inside the workspace. If external is specified, this will be opened on the client.                                                                                                                         |
| `»» architecture`               | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» connection_timeout_seconds` | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» created_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» directory`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» disconnected_at`            | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» display_apps`               | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» environment_variables`      | object                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» [any property]`            | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» expanded_directory`         | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» first_connected_at`         | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» health`                     | [codersdk.WorkspaceAgentHealth](schemas.md#codersdkworkspaceagenthealth)                               | false    |              | Health reports the health of the agent.                                                                                                                                                                                                        |
| `»»» healthy`                   | boolean                                                                                                | false    |              | Healthy is true if the agent is healthy.                                                                                                                                                                                                       |
| `»»» reason`                    | string                                                                                                 | false    |              | Reason is a human-readable explanation of the agent's health. It is empty if Healthy is true.                                                                                                                                                  |
| `»» id`                         | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» instance_id`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» last_connected_at`          | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» latency`                    | object                                                                                                 | false    |              | Latency is mapped by region name (e.g. "New York City", "Seattle").                                                                                                                                                                            |
| `»»» [any property]`            | [codersdk.DERPRegion](schemas.md#codersdkderpregion)                                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»»» latency_ms`               | number                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» preferred`                | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» lifecycle_state`            | [codersdk.WorkspaceAgentLifecycle](schemas.md#codersdkworkspaceagentlifecycle)                         | false    |              |                                                                                                                                                                                                                                                |
| `»» log_sources`                | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» created_at`                | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» icon`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» workspace_agent_id`        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» logs_length`                | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» logs_overflowed`            | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» name`                       | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» operating_system`           | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» parent_id`                  | [uuid.NullUUID](schemas.md#uuidnulluuid)                                                               | false    |              |                                                                                                                                                                                                                                                |
| `»»» uuid`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» valid`                     | boolean                                                                                                | false    |              | Valid is true if UUID is not NULL                                                                                                                                                                                                              |
| `»» ready_at`                   | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» resource_id`                | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» scripts`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» cron`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» exit_code`                 | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» log_path`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» log_source_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» run_on_start`              | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» run_on_stop`               | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» script`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» start_blocks_login`        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» status`                    | [codersdk.WorkspaceAgentScriptStatus](schemas.md#codersdkworkspaceagentscriptstatus)                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» timeout`                   | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» started_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» startup_script_behavior`    | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false    |              | Startup script behavior is a legacy field that is deprecated in favor of the `coder_script` resource. It's only referenced by old clients. Deprecated: Remove in the future!                                                                   |
| `»» status`                     | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus)                               | false    |              |                                                                                                                                                                                                                                                |
| `»» subsystems`                 | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» troubleshooting_url`        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» updated_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» version`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» created_at`                  | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `» daily_cost`                  | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» hide`                        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» icon`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» id`                          | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» job_id`                      | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» metadata`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» key`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» sensitive`                  | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» value`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» name`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» type`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_transition`        | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)                                 | false    |              |                                                                                                                                                                                                                                                |

#### Enumerated Values

| Property                  | Value(s)                                                                                                                     |
|---------------------------|------------------------------------------------------------------------------------------------------------------------------|
| `health`                  | `disabled`, `healthy`, `initializing`, `unhealthy`                                                                           |
| `open_in`                 | `slim-window`, `tab`                                                                                                         |
| `sharing_level`           | `authenticated`, `organization`, `owner`, `public`                                                                           |
| `state`                   | `complete`, `failure`, `idle`, `working`                                                                                     |
| `lifecycle_state`         | `created`, `off`, `ready`, `shutdown_error`, `shutdown_timeout`, `shutting_down`, `start_error`, `start_timeout`, `starting` |
| `status`                  | `connected`, `connecting`, `disconnected`, `exit_failure`, `ok`, `pipes_left_open`, `timed_out`, `timeout`                   |
| `startup_script_behavior` | `blocking`, `non-blocking`                                                                                                   |
| `workspace_transition`    | `delete`, `start`, `stop`                                                                                                    |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get provisioner state for workspace build

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/state \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspacebuilds/{workspacebuild}/state`

### Parameters

| Name             | In   | Type   | Required | Description        |
|------------------|------|--------|----------|--------------------|
| `workspacebuild` | path | string | true     | Workspace build ID |

### Example responses

> 200 Response

```json
{
  "build_number": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "daily_cost": 0,
  "deadline": "2019-08-24T14:15:22Z",
  "has_ai_task": true,
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "initiator_name": "string",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "max_deadline": "2019-08-24T14:15:22Z",
  "reason": "initiator",
  "resources": [
    {
      "agents": [
        {
          "api_version": "string",
          "apps": [
            {
              "command": "string",
              "display_name": "string",
              "external": true,
              "group": "string",
              "health": "disabled",
              "healthcheck": {
                "interval": 0,
                "threshold": 0,
                "url": "string"
              },
              "hidden": true,
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "open_in": "slim-window",
              "sharing_level": "owner",
              "slug": "string",
              "statuses": [
                {
                  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                  "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                  "created_at": "2019-08-24T14:15:22Z",
                  "icon": "string",
                  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                  "message": "string",
                  "needs_user_attention": true,
                  "state": "working",
                  "uri": "string",
                  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                }
              ],
              "subdomain": true,
              "subdomain_name": "string",
              "tooltip": "string",
              "url": "string"
            }
          ],
          "architecture": "string",
          "connection_timeout_seconds": 0,
          "created_at": "2019-08-24T14:15:22Z",
          "directory": "string",
          "disconnected_at": "2019-08-24T14:15:22Z",
          "display_apps": [
            "vscode"
          ],
          "environment_variables": {
            "property1": "string",
            "property2": "string"
          },
          "expanded_directory": "string",
          "first_connected_at": "2019-08-24T14:15:22Z",
          "health": {
            "healthy": false,
            "reason": "agent has lost connection"
          },
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "instance_id": "string",
          "last_connected_at": "2019-08-24T14:15:22Z",
          "latency": {
            "property1": {
              "latency_ms": 0,
              "preferred": true
            },
            "property2": {
              "latency_ms": 0,
              "preferred": true
            }
          },
          "lifecycle_state": "created",
          "log_sources": [
            {
              "created_at": "2019-08-24T14:15:22Z",
              "display_name": "string",
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
            }
          ],
          "logs_length": 0,
          "logs_overflowed": true,
          "name": "string",
          "operating_system": "string",
          "parent_id": {
            "uuid": "string",
            "valid": true
          },
          "ready_at": "2019-08-24T14:15:22Z",
          "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
          "scripts": [
            {
              "cron": "string",
              "display_name": "string",
              "exit_code": 0,
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "log_path": "string",
              "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
              "run_on_start": true,
              "run_on_stop": true,
              "script": "string",
              "start_blocks_login": true,
              "status": "ok",
              "timeout": 0
            }
          ],
          "started_at": "2019-08-24T14:15:22Z",
          "startup_script_behavior": "blocking",
          "status": "connecting",
          "subsystems": [
            "envbox"
          ],
          "troubleshooting_url": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "version": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "daily_cost": 0,
      "hide": true,
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "metadata": [
        {
          "key": "string",
          "sensitive": true,
          "value": "string"
        }
      ],
      "name": "string",
      "type": "string",
      "workspace_transition": "start"
    }
  ],
  "status": "pending",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_name": "string",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "transition": "start",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
  "workspace_name": "string",
  "workspace_owner_avatar_url": "string",
  "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
  "workspace_owner_name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace build state

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/state \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/workspacebuilds/{workspacebuild}/state`

> Body parameter

```json
{
  "state": [
    0
  ]
}
```

### Parameters

| Name             | In   | Type                                                                                             | Required | Description        |
|------------------|------|--------------------------------------------------------------------------------------------------|----------|--------------------|
| `workspacebuild` | path | string(uuid)                                                                                     | true     | Workspace build ID |
| `body`           | body | [codersdk.UpdateWorkspaceBuildStateRequest](schemas.md#codersdkupdateworkspacebuildstaterequest) | true     | Request body       |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace build timings by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/timings \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspacebuilds/{workspacebuild}/timings`

### Parameters

| Name             | In   | Type         | Required | Description        |
|------------------|------|--------------|----------|--------------------|
| `workspacebuild` | path | string(uuid) | true     | Workspace build ID |

### Example responses

> 200 Response

```json
{
  "agent_connection_timings": [
    {
      "ended_at": "2019-08-24T14:15:22Z",
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z",
      "workspace_agent_id": "string",
      "workspace_agent_name": "string"
    }
  ],
  "agent_script_timings": [
    {
      "display_name": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "exit_code": 0,
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z",
      "status": "string",
      "workspace_agent_id": "string",
      "workspace_agent_name": "string"
    }
  ],
  "provisioner_timings": [
    {
      "action": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "resource": "string",
      "source": "string",
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                     |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceBuildTimings](schemas.md#codersdkworkspacebuildtimings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace builds by workspace ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/builds`

### Parameters

| Name        | In    | Type              | Required | Description     |
|-------------|-------|-------------------|----------|-----------------|
| `workspace` | path  | string(uuid)      | true     | Workspace ID    |
| `after_id`  | query | string(uuid)      | false    | After ID        |
| `limit`     | query | integer           | false    | Page limit      |
| `offset`    | query | integer           | false    | Page offset     |
| `since`     | query | string(date-time) | false    | Since timestamp |

### Example responses

> 200 Response

```json
[
  {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) |

<h3 id="get-workspace-builds-by-workspace-id-responseschema">Response Schema</h3>

Status Code **200**

| Name                             | Type                                                                                                   | Required | Restrictions | Description                                                                                                                                                                                                                                    |
|----------------------------------|--------------------------------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                   | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `» build_number`                 | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» created_at`                   | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `» daily_cost`                   | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» deadline`                     | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `» has_ai_task`                  | boolean                                                                                                | false    |              | Deprecated: This field has been deprecated in favor of Task WorkspaceID.                                                                                                                                                                       |
| `» has_external_agent`           | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» id`                           | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» initiator_id`                 | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» initiator_name`               | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» job`                          | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob)                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» available_workers`           | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» canceled_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» completed_at`                | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» created_at`                  | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» error`                       | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» error_code`                  | [codersdk.JobErrorCode](schemas.md#codersdkjoberrorcode)                                               | false    |              |                                                                                                                                                                                                                                                |
| `»» file_id`                     | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» id`                          | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» initiator_id`                | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» input`                       | [codersdk.ProvisionerJobInput](schemas.md#codersdkprovisionerjobinput)                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» error`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» template_version_id`        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» workspace_build_id`         | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» logs_overflowed`             | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» metadata`                    | [codersdk.ProvisionerJobMetadata](schemas.md#codersdkprovisionerjobmetadata)                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» template_display_name`      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» template_icon`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» template_id`                | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» template_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» template_version_name`      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» workspace_build_transition` | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» workspace_id`               | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» workspace_name`             | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» organization_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» queue_position`              | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» queue_size`                  | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» started_at`                  | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» status`                      | [codersdk.ProvisionerJobStatus](schemas.md#codersdkprovisionerjobstatus)                               | false    |              |                                                                                                                                                                                                                                                |
| `»» tags`                        | object                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» [any property]`             | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» type`                        | [codersdk.ProvisionerJobType](schemas.md#codersdkprovisionerjobtype)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»» worker_id`                   | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» worker_name`                 | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» matched_provisioners`         | [codersdk.MatchedProvisioners](schemas.md#codersdkmatchedprovisioners)                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» available`                   | integer                                                                                                | false    |              | Available is the number of provisioner daemons that are available to take jobs. This may be less than the count if some provisioners are busy or have been stopped.                                                                            |
| `»» count`                       | integer                                                                                                | false    |              | Count is the number of provisioner daemons that matched the given tags. If the count is 0, it means no provisioner daemons matched the requested tags.                                                                                         |
| `»» most_recently_seen`          | string(date-time)                                                                                      | false    |              | Most recently seen is the most recently seen time of the set of matched provisioners. If no provisioners matched, this field will be null.                                                                                                     |
| `» max_deadline`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `» reason`                       | [codersdk.BuildReason](schemas.md#codersdkbuildreason)                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» resources`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» agents`                      | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» api_version`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» apps`                       | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»»» command`                   | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» display_name`              | string                                                                                                 | false    |              | Display name is a friendly name for the app.                                                                                                                                                                                                   |
| `»»»» external`                  | boolean                                                                                                | false    |              | External specifies whether the URL should be opened externally on the client or not.                                                                                                                                                           |
| `»»»» group`                     | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» health`                    | [codersdk.WorkspaceAppHealth](schemas.md#codersdkworkspaceapphealth)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»»» healthcheck`               | [codersdk.Healthcheck](schemas.md#codersdkhealthcheck)                                                 | false    |              | Healthcheck specifies the configuration for checking app health.                                                                                                                                                                               |
| `»»»»» interval`                 | integer                                                                                                | false    |              | Interval specifies the seconds between each health check.                                                                                                                                                                                      |
| `»»»»» threshold`                | integer                                                                                                | false    |              | Threshold specifies the number of consecutive failed health checks before returning "unhealthy".                                                                                                                                               |
| `»»»»» url`                      | string                                                                                                 | false    |              | URL specifies the endpoint to check for the app health.                                                                                                                                                                                        |
| `»»»» hidden`                    | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»»» icon`                      | string                                                                                                 | false    |              | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard.                                                                                                                                               |
| `»»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» open_in`                   | [codersdk.WorkspaceAppOpenIn](schemas.md#codersdkworkspaceappopenin)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»»» sharing_level`             | [codersdk.WorkspaceAppSharingLevel](schemas.md#codersdkworkspaceappsharinglevel)                       | false    |              |                                                                                                                                                                                                                                                |
| `»»»» slug`                      | string                                                                                                 | false    |              | Slug is a unique identifier within the agent.                                                                                                                                                                                                  |
| `»»»» statuses`                  | array                                                                                                  | false    |              | Statuses is a list of statuses for the app.                                                                                                                                                                                                    |
| `»»»»» agent_id`                 | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» app_id`                   | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» created_at`               | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» icon`                     | string                                                                                                 | false    |              | Deprecated: This field is unused and will be removed in a future version. Icon is an external URL to an icon that will be rendered in the UI.                                                                                                  |
| `»»»»» id`                       | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» message`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» needs_user_attention`     | boolean                                                                                                | false    |              | Deprecated: This field is unused and will be removed in a future version. NeedsUserAttention specifies whether the status needs user attention.                                                                                                |
| `»»»»» state`                    | [codersdk.WorkspaceAppStatusState](schemas.md#codersdkworkspaceappstatusstate)                         | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» uri`                      | string                                                                                                 | false    |              | Uri is the URI of the resource that the status is for. e.g. https://github.com/org/repo/pull/123 e.g. file:///path/to/file                                                                                                                     |
| `»»»»» workspace_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» subdomain`                 | boolean                                                                                                | false    |              | Subdomain denotes whether the app should be accessed via a path on the `coder server` or via a hostname-based dev URL. If this is set to true and there is no app wildcard configured on the server, the app will not be accessible in the UI. |
| `»»»» subdomain_name`            | string                                                                                                 | false    |              | Subdomain name is the application domain exposed on the `coder server`.                                                                                                                                                                        |
| `»»»» tooltip`                   | string                                                                                                 | false    |              | Tooltip is an optional markdown supported field that is displayed when hovering over workspace apps in the UI.                                                                                                                                 |
| `»»»» url`                       | string                                                                                                 | false    |              | URL is the address being proxied to inside the workspace. If external is specified, this will be opened on the client.                                                                                                                         |
| `»»» architecture`               | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» connection_timeout_seconds` | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» created_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» directory`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» disconnected_at`            | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_apps`               | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» environment_variables`      | object                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» [any property]`            | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» expanded_directory`         | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» first_connected_at`         | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» health`                     | [codersdk.WorkspaceAgentHealth](schemas.md#codersdkworkspaceagenthealth)                               | false    |              | Health reports the health of the agent.                                                                                                                                                                                                        |
| `»»»» healthy`                   | boolean                                                                                                | false    |              | Healthy is true if the agent is healthy.                                                                                                                                                                                                       |
| `»»»» reason`                    | string                                                                                                 | false    |              | Reason is a human-readable explanation of the agent's health. It is empty if Healthy is true.                                                                                                                                                  |
| `»»» id`                         | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» instance_id`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» last_connected_at`          | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» latency`                    | object                                                                                                 | false    |              | Latency is mapped by region name (e.g. "New York City", "Seattle").                                                                                                                                                                            |
| `»»»» [any property]`            | [codersdk.DERPRegion](schemas.md#codersdkderpregion)                                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» latency_ms`               | number                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»»» preferred`                | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» lifecycle_state`            | [codersdk.WorkspaceAgentLifecycle](schemas.md#codersdkworkspaceagentlifecycle)                         | false    |              |                                                                                                                                                                                                                                                |
| `»»» log_sources`                | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»»» created_at`                | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» icon`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» workspace_agent_id`        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» logs_length`                | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» logs_overflowed`            | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» name`                       | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» operating_system`           | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» parent_id`                  | [uuid.NullUUID](schemas.md#uuidnulluuid)                                                               | false    |              |                                                                                                                                                                                                                                                |
| `»»»» uuid`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» valid`                     | boolean                                                                                                | false    |              | Valid is true if UUID is not NULL                                                                                                                                                                                                              |
| `»»» ready_at`                   | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» resource_id`                | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» scripts`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»»» cron`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» exit_code`                 | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» log_path`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» log_source_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» run_on_start`              | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»»» run_on_stop`               | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»»» script`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» start_blocks_login`        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»»» status`                    | [codersdk.WorkspaceAgentScriptStatus](schemas.md#codersdkworkspaceagentscriptstatus)                   | false    |              |                                                                                                                                                                                                                                                |
| `»»»» timeout`                   | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» started_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» startup_script_behavior`    | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false    |              | Startup script behavior is a legacy field that is deprecated in favor of the `coder_script` resource. It's only referenced by old clients. Deprecated: Remove in the future!                                                                   |
| `»»» status`                     | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus)                               | false    |              |                                                                                                                                                                                                                                                |
| `»»» subsystems`                 | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» troubleshooting_url`        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» updated_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» version`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» created_at`                  | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» daily_cost`                  | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» hide`                        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» icon`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» id`                          | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» job_id`                      | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» metadata`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» key`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» sensitive`                  | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» value`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» name`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» type`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» workspace_transition`        | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)                                 | false    |              |                                                                                                                                                                                                                                                |
| `» status`                       | [codersdk.WorkspaceStatus](schemas.md#codersdkworkspacestatus)                                         | false    |              |                                                                                                                                                                                                                                                |
| `» template_version_id`          | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» template_version_name`        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» template_version_preset_id`   | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» transition`                   | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)                                 | false    |              |                                                                                                                                                                                                                                                |
| `» updated_at`                   | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_id`                 | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_name`               | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_owner_avatar_url`   | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_owner_id`           | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_owner_name`         | string                                                                                                 | false    |              | Workspace owner name is the username of the owner of the workspace.                                                                                                                                                                            |

#### Enumerated Values

| Property                     | Value(s)                                                                                                                                                                                                                                   |
|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `error_code`                 | `INSUFFICIENT_QUOTA`, `REQUIRED_TEMPLATE_VARIABLES`                                                                                                                                                                                        |
| `workspace_build_transition` | `delete`, `start`, `stop`                                                                                                                                                                                                                  |
| `status`                     | `canceled`, `canceling`, `connected`, `connecting`, `deleted`, `deleting`, `disconnected`, `exit_failure`, `failed`, `ok`, `pending`, `pipes_left_open`, `running`, `starting`, `stopped`, `stopping`, `succeeded`, `timed_out`, `timeout` |
| `type`                       | `template_version_dry_run`, `template_version_import`, `workspace_build`                                                                                                                                                                   |
| `reason`                     | `autostart`, `autostop`, `initiator`                                                                                                                                                                                                       |
| `health`                     | `disabled`, `healthy`, `initializing`, `unhealthy`                                                                                                                                                                                         |
| `open_in`                    | `slim-window`, `tab`                                                                                                                                                                                                                       |
| `sharing_level`              | `authenticated`, `organization`, `owner`, `public`                                                                                                                                                                                         |
| `state`                      | `complete`, `failure`, `idle`, `working`                                                                                                                                                                                                   |
| `lifecycle_state`            | `created`, `off`, `ready`, `shutdown_error`, `shutdown_timeout`, `shutting_down`, `start_error`, `start_timeout`, `starting`                                                                                                               |
| `startup_script_behavior`    | `blocking`, `non-blocking`                                                                                                                                                                                                                 |
| `workspace_transition`       | `delete`, `start`, `stop`                                                                                                                                                                                                                  |
| `transition`                 | `delete`, `start`, `stop`                                                                                                                                                                                                                  |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create workspace build

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaces/{workspace}/builds`

> Body parameter

```json
{
  "dry_run": true,
  "log_level": "debug",
  "orphan": true,
  "reason": "dashboard",
  "rich_parameter_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "state": [
    0
  ],
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "transition": "start"
}
```

### Parameters

| Name        | In   | Type                                                                                   | Required | Description                    |
|-------------|------|----------------------------------------------------------------------------------------|----------|--------------------------------|
| `workspace` | path | string(uuid)                                                                           | true     | Workspace ID                   |
| `body`      | body | [codersdk.CreateWorkspaceBuildRequest](schemas.md#codersdkcreateworkspacebuildrequest) | true     | Create workspace build request |

### Example responses

> 200 Response

```json
{
  "build_number": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "daily_cost": 0,
  "deadline": "2019-08-24T14:15:22Z",
  "has_ai_task": true,
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "initiator_name": "string",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "max_deadline": "2019-08-24T14:15:22Z",
  "reason": "initiator",
  "resources": [
    {
      "agents": [
        {
          "api_version": "string",
          "apps": [
            {
              "command": "string",
              "display_name": "string",
              "external": true,
              "group": "string",
              "health": "disabled",
              "healthcheck": {
                "interval": 0,
                "threshold": 0,
                "url": "string"
              },
              "hidden": true,
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "open_in": "slim-window",
              "sharing_level": "owner",
              "slug": "string",
              "statuses": [
                {
                  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                  "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                  "created_at": "2019-08-24T14:15:22Z",
                  "icon": "string",
                  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                  "message": "string",
                  "needs_user_attention": true,
                  "state": "working",
                  "uri": "string",
                  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                }
              ],
              "subdomain": true,
              "subdomain_name": "string",
              "tooltip": "string",
              "url": "string"
            }
          ],
          "architecture": "string",
          "connection_timeout_seconds": 0,
          "created_at": "2019-08-24T14:15:22Z",
          "directory": "string",
          "disconnected_at": "2019-08-24T14:15:22Z",
          "display_apps": [
            "vscode"
          ],
          "environment_variables": {
            "property1": "string",
            "property2": "string"
          },
          "expanded_directory": "string",
          "first_connected_at": "2019-08-24T14:15:22Z",
          "health": {
            "healthy": false,
            "reason": "agent has lost connection"
          },
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "instance_id": "string",
          "last_connected_at": "2019-08-24T14:15:22Z",
          "latency": {
            "property1": {
              "latency_ms": 0,
              "preferred": true
            },
            "property2": {
              "latency_ms": 0,
              "preferred": true
            }
          },
          "lifecycle_state": "created",
          "log_sources": [
            {
              "created_at": "2019-08-24T14:15:22Z",
              "display_name": "string",
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
            }
          ],
          "logs_length": 0,
          "logs_overflowed": true,
          "name": "string",
          "operating_system": "string",
          "parent_id": {
            "uuid": "string",
            "valid": true
          },
          "ready_at": "2019-08-24T14:15:22Z",
          "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
          "scripts": [
            {
              "cron": "string",
              "display_name": "string",
              "exit_code": 0,
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "log_path": "string",
              "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
              "run_on_start": true,
              "run_on_stop": true,
              "script": "string",
              "start_blocks_login": true,
              "status": "ok",
              "timeout": 0
            }
          ],
          "started_at": "2019-08-24T14:15:22Z",
          "startup_script_behavior": "blocking",
          "status": "connecting",
          "subsystems": [
            "envbox"
          ],
          "troubleshooting_url": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "version": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "daily_cost": 0,
      "hide": true,
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "metadata": [
        {
          "key": "string",
          "sensitive": true,
          "value": "string"
        }
      ],
      "name": "string",
      "type": "string",
      "workspace_transition": "start"
    }
  ],
  "status": "pending",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_name": "string",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "transition": "start",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
  "workspace_name": "string",
  "workspace_owner_avatar_url": "string",
  "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
  "workspace_owner_name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceBuild](schemas.md#codersdkworkspacebuild) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Chats

Source: https://coder.com/docs/reference/api/chats

# Chats

## List chats

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats`

Experimental: this endpoint is subject to change.

### Parameters

| Name    | In    | Type   | Required | Description                                                    |
|---------|-------|--------|----------|----------------------------------------------------------------|
| `q`     | query | string | false    | Search query                                                   |
| `label` | query | string | false    | Filter by label as key:value. Repeat for multiple (AND logic). |

### Example responses

> 200 Response

```json
[
  {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "archived": true,
    "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
    "children": [
      {}
    ],
    "client_type": "ui",
    "created_at": "2019-08-24T14:15:22Z",
    "diff_status": {
      "additions": 0,
      "approved": true,
      "author_avatar_url": "string",
      "author_login": "string",
      "base_branch": "string",
      "changed_files": 0,
      "changes_requested": true,
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "commits": 0,
      "deletions": 0,
      "head_branch": "string",
      "pr_number": 0,
      "pull_request_draft": true,
      "pull_request_state": "string",
      "pull_request_title": "string",
      "refreshed_at": "2019-08-24T14:15:22Z",
      "reviewer_count": 0,
      "stale_at": "2019-08-24T14:15:22Z",
      "url": "string"
    },
    "files": [
      {
        "created_at": "2019-08-24T14:15:22Z",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "mime_type": "string",
        "name": "string",
        "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
        "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
      }
    ],
    "has_unread": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "labels": {
      "property1": "string",
      "property2": "string"
    },
    "last_error": {
      "detail": "string",
      "kind": "generic",
      "message": "string",
      "provider": "string",
      "retryable": true,
      "status_code": 0
    },
    "last_injected_context": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
    "last_turn_summary": "string",
    "mcp_server_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
    "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
    "pin_order": 0,
    "plan_mode": "plan",
    "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
    "status": "waiting",
    "title": "string",
    "updated_at": "2019-08-24T14:15:22Z",
    "warnings": [
      "string"
    ],
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                            |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Chat](schemas.md#codersdkchat) |

<h3 id="list-chats-responseschema">Response Schema</h3>

Status Code **200**

| Name                              | Type                                                                   | Required | Restrictions | Description                                                                                                                                                                                                                                                                |
|-----------------------------------|------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                    | array                                                                  | false    |              |                                                                                                                                                                                                                                                                            |
| `» agent_id`                      | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» archived`                      | boolean                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `» build_id`                      | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» children`                      | [codersdk.Chat](schemas.md#codersdkchat)                               | false    |              | Children holds child (subagent) chats nested under this root chat. Always initialized to an empty slice so the JSON field is present as []. Child chats cannot create their own subagents, so nesting depth is capped at 1 and this slice is always empty for child chats. |
| `» client_type`                   | [codersdk.ChatClientType](schemas.md#codersdkchatclienttype)           | false    |              |                                                                                                                                                                                                                                                                            |
| `» created_at`                    | string(date-time)                                                      | false    |              |                                                                                                                                                                                                                                                                            |
| `» diff_status`                   | [codersdk.ChatDiffStatus](schemas.md#codersdkchatdiffstatus)           | false    |              |                                                                                                                                                                                                                                                                            |
| `»» additions`                    | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» approved`                     | boolean                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» author_avatar_url`            | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» author_login`                 | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» base_branch`                  | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» changed_files`                | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» changes_requested`            | boolean                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» chat_id`                      | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `»» commits`                      | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» deletions`                    | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» head_branch`                  | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» pr_number`                    | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» pull_request_draft`           | boolean                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» pull_request_state`           | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» pull_request_title`           | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» refreshed_at`                 | string(date-time)                                                      | false    |              |                                                                                                                                                                                                                                                                            |
| `»» reviewer_count`               | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» stale_at`                     | string(date-time)                                                      | false    |              |                                                                                                                                                                                                                                                                            |
| `»» url`                          | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `» files`                         | array                                                                  | false    |              |                                                                                                                                                                                                                                                                            |
| `»» created_at`                   | string(date-time)                                                      | false    |              |                                                                                                                                                                                                                                                                            |
| `»» id`                           | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `»» mime_type`                    | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» name`                         | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» organization_id`              | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `»» owner_id`                     | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» has_unread`                    | boolean                                                                | false    |              | Has unread is true when assistant messages exist beyond the owner's read cursor, which updates on stream connect and disconnect.                                                                                                                                           |
| `» id`                            | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» labels`                        | object                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» [any property]`               | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `» last_error`                    | [codersdk.ChatError](schemas.md#codersdkchaterror)                     | false    |              |                                                                                                                                                                                                                                                                            |
| `»» detail`                       | string                                                                 | false    |              | Detail is optional provider-specific context shown alongside the normalized error message when available.                                                                                                                                                                  |
| `»» kind`                         | [codersdk.ChatErrorKind](schemas.md#codersdkchaterrorkind)             | false    |              | Kind classifies the error for consistent client rendering.                                                                                                                                                                                                                 |
| `»» message`                      | string                                                                 | false    |              | Message is the normalized, user-facing error message.                                                                                                                                                                                                                      |
| `»» provider`                     | string                                                                 | false    |              | Provider identifies the upstream model provider when known.                                                                                                                                                                                                                |
| `»» retryable`                    | boolean                                                                | false    |              | Retryable reports whether the underlying error is transient.                                                                                                                                                                                                               |
| `»» status_code`                  | integer                                                                | false    |              | Status code is the best-effort upstream HTTP status code.                                                                                                                                                                                                                  |
| `» last_injected_context`         | array                                                                  | false    |              | Last injected context holds the most recently persisted injected context parts (AGENTS.md files and skills). It is updated only when context changes, on first workspace attach or agent change.                                                                           |
| `»» args`                         | array                                                                  | false    |              |                                                                                                                                                                                                                                                                            |
| `»» args_delta`                   | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» content`                      | string                                                                 | false    |              | The code content from the diff that was commented on.                                                                                                                                                                                                                      |
| `»» context_file_agent_id`        | [uuid.NullUUID](schemas.md#uuidnulluuid)                               | false    |              | Context file agent ID is the workspace agent that provided this context file. Used to detect when the agent changes (e.g. workspace rebuilt) so instruction files can be re-persisted with fresh content.                                                                  |
| `»»» uuid`                        | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»»» valid`                       | boolean                                                                | false    |              | Valid is true if UUID is not NULL                                                                                                                                                                                                                                          |
| `»» context_file_content`         | string                                                                 | false    |              | Context file content holds the file content sent to the LLM. Internal only: stripped before API responses to keep payloads small. The backend reads it when building the prompt via partsToMessageParts.                                                                   |
| `»» context_file_directory`       | string                                                                 | false    |              | Context file directory is the working directory of the workspace agent. Internal only: same purpose as ContextFileOS.                                                                                                                                                      |
| `»» context_file_os`              | string                                                                 | false    |              | Context file os is the operating system of the workspace agent. Internal only: used during prompt expansion so the LLM knows the OS even on turns where InsertSystem is not called.                                                                                        |
| `»» context_file_path`            | string                                                                 | false    |              | Context file path is the absolute path of a file loaded into the LLM context (e.g. an AGENTS.md instruction file).                                                                                                                                                         |
| `»» context_file_skill_meta_file` | string                                                                 | false    |              | Context file skill meta file is the basename of the skill meta file (e.g. "SKILL.md") at the time of persistence. Internal only: restored on subsequent turns so the read_skill tool uses the correct filename even when the agent configured a non-default value.         |
| `»» context_file_truncated`       | boolean                                                                | false    |              | Context file truncated indicates the file exceeded the 64KiB instruction file limit and was truncated.                                                                                                                                                                     |
| `»» created_at`                   | string(date-time)                                                      | false    |              | Created at records when this part was produced. Present on tool-call and tool-result parts so the frontend can compute tool execution duration.                                                                                                                            |
| `»» data`                         | array                                                                  | false    |              |                                                                                                                                                                                                                                                                            |
| `»» end_line`                     | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» file_id`                      | [uuid.NullUUID](schemas.md#uuidnulluuid)                               | false    |              |                                                                                                                                                                                                                                                                            |
| `»»» uuid`                        | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»»» valid`                       | boolean                                                                | false    |              | Valid is true if UUID is not NULL                                                                                                                                                                                                                                          |
| `»» file_name`                    | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» is_error`                     | boolean                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» is_media`                     | boolean                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» mcp_server_config_id`         | [uuid.NullUUID](schemas.md#uuidnulluuid)                               | false    |              |                                                                                                                                                                                                                                                                            |
| `»»» uuid`                        | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»»» valid`                       | boolean                                                                | false    |              | Valid is true if UUID is not NULL                                                                                                                                                                                                                                          |
| `»» media_type`                   | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» name`                         | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» provider_executed`            | boolean                                                                | false    |              | Provider executed indicates the tool call was executed by the provider (e.g. Anthropic computer use).                                                                                                                                                                      |
| `»» provider_metadata`            | array                                                                  | false    |              | Provider metadata holds provider-specific response metadata (e.g. Anthropic cache control hints) as raw JSON. Internal only: stripped by db2sdk before API responses.                                                                                                      |
| `»» result`                       | array                                                                  | false    |              |                                                                                                                                                                                                                                                                            |
| `»» result_delta`                 | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» signature`                    | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» skill_description`            | string                                                                 | false    |              | Skill description is the short description from the skill's SKILL.md frontmatter.                                                                                                                                                                                          |
| `»» skill_dir`                    | string                                                                 | false    |              | Skill dir is the absolute path to the skill directory inside the workspace filesystem. Internal only: used by read_skill/read_skill_file tools to locate skill files.                                                                                                      |
| `»» skill_name`                   | string                                                                 | false    |              | Skill name is the kebab-case name of a discovered skill from the workspace's .agents/skills/ directory.                                                                                                                                                                    |
| `»» source_id`                    | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» start_line`                   | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `»» text`                         | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» title`                        | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» tool_call_id`                 | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» tool_name`                    | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `»» type`                         | [codersdk.ChatMessagePartType](schemas.md#codersdkchatmessageparttype) | false    |              |                                                                                                                                                                                                                                                                            |
| `»» url`                          | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `» last_model_config_id`          | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» last_turn_summary`             | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `» mcp_server_ids`                | array                                                                  | false    |              |                                                                                                                                                                                                                                                                            |
| `» organization_id`               | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» owner_id`                      | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» parent_chat_id`                | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» pin_order`                     | integer                                                                | false    |              |                                                                                                                                                                                                                                                                            |
| `» plan_mode`                     | [codersdk.ChatPlanMode](schemas.md#codersdkchatplanmode)               | false    |              |                                                                                                                                                                                                                                                                            |
| `» root_chat_id`                  | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |
| `» status`                        | [codersdk.ChatStatus](schemas.md#codersdkchatstatus)                   | false    |              |                                                                                                                                                                                                                                                                            |
| `» title`                         | string                                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `» updated_at`                    | string(date-time)                                                      | false    |              |                                                                                                                                                                                                                                                                            |
| `» warnings`                      | array                                                                  | false    |              |                                                                                                                                                                                                                                                                            |
| `» workspace_id`                  | string(uuid)                                                           | false    |              |                                                                                                                                                                                                                                                                            |

#### Enumerated Values

| Property      | Value(s)                                                                                                     |
|---------------|--------------------------------------------------------------------------------------------------------------|
| `client_type` | `api`, `ui`                                                                                                  |
| `kind`        | `auth`, `config`, `generic`, `overloaded`, `rate_limit`, `startup_timeout`, `timeout`, `usage_limit`         |
| `type`        | `context-file`, `file`, `file-reference`, `reasoning`, `skill`, `source`, `text`, `tool-call`, `tool-result` |
| `plan_mode`   | `plan`                                                                                                       |
| `status`      | `completed`, `error`, `paused`, `pending`, `requires_action`, `running`, `waiting`                           |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create chat

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/experimental/chats \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/experimental/chats`

Experimental: this endpoint is subject to change.

> Body parameter

```json
{
  "client_type": "ui",
  "content": [
    {
      "content": "string",
      "end_line": 0,
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "file_name": "string",
      "start_line": 0,
      "text": "string",
      "type": "text"
    }
  ],
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "plan_mode": "plan",
  "system_prompt": "string",
  "unsafe_dynamic_tools": [
    {
      "description": "string",
      "input_schema": [
        0
      ],
      "name": "string"
    }
  ],
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Parameters

| Name   | In   | Type                                                               | Required | Description         |
|--------|------|--------------------------------------------------------------------|----------|---------------------|
| `body` | body | [codersdk.CreateChatRequest](schemas.md#codersdkcreatechatrequest) | true     | Create chat request |

### Example responses

> 201 Response

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "archived": true,
  "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
  "children": [
    {
      "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
      "archived": true,
      "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
      "children": [],
      "client_type": "ui",
      "created_at": "2019-08-24T14:15:22Z",
      "diff_status": {
        "additions": 0,
        "approved": true,
        "author_avatar_url": "string",
        "author_login": "string",
        "base_branch": "string",
        "changed_files": 0,
        "changes_requested": true,
        "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
        "commits": 0,
        "deletions": 0,
        "head_branch": "string",
        "pr_number": 0,
        "pull_request_draft": true,
        "pull_request_state": "string",
        "pull_request_title": "string",
        "refreshed_at": "2019-08-24T14:15:22Z",
        "reviewer_count": 0,
        "stale_at": "2019-08-24T14:15:22Z",
        "url": "string"
      },
      "files": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "mime_type": "string",
          "name": "string",
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
        }
      ],
      "has_unread": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "last_error": {
        "detail": "string",
        "kind": "generic",
        "message": "string",
        "provider": "string",
        "retryable": true,
        "status_code": 0
      },
      "last_injected_context": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
      "last_turn_summary": "string",
      "mcp_server_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
      "pin_order": 0,
      "plan_mode": "plan",
      "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
      "status": "waiting",
      "title": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "warnings": [
        "string"
      ],
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ],
  "client_type": "ui",
  "created_at": "2019-08-24T14:15:22Z",
  "diff_status": {
    "additions": 0,
    "approved": true,
    "author_avatar_url": "string",
    "author_login": "string",
    "base_branch": "string",
    "changed_files": 0,
    "changes_requested": true,
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "commits": 0,
    "deletions": 0,
    "head_branch": "string",
    "pr_number": 0,
    "pull_request_draft": true,
    "pull_request_state": "string",
    "pull_request_title": "string",
    "refreshed_at": "2019-08-24T14:15:22Z",
    "reviewer_count": 0,
    "stale_at": "2019-08-24T14:15:22Z",
    "url": "string"
  },
  "files": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "mime_type": "string",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
    }
  ],
  "has_unread": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "last_error": {
    "detail": "string",
    "kind": "generic",
    "message": "string",
    "provider": "string",
    "retryable": true,
    "status_code": 0
  },
  "last_injected_context": [
    {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    }
  ],
  "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
  "last_turn_summary": "string",
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
  "pin_order": 0,
  "plan_mode": "plan",
  "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
  "status": "waiting",
  "title": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "string"
  ],
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                   |
|--------|--------------------------------------------------------------|-------------|------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.Chat](schemas.md#codersdkchat) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Upload chat file

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/experimental/chats/files?organization=497f6eca-6276-4993-bfeb-53cbbbba6f08 \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/experimental/chats/files`

Experimental: this endpoint is subject to change.

### Parameters

| Name           | In    | Type         | Required | Description     |
|----------------|-------|--------------|----------|-----------------|
| `organization` | query | string(uuid) | true     | Organization ID |

### Example responses

> 201 Response

```json
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                       |
|--------|--------------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.UploadChatFileResponse](schemas.md#codersdkuploadchatfileresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get chat file

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/files/{file} \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/files/{file}`

Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `file` | path | string(uuid) | true     | File ID     |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List chat models

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/models \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/models`

Experimental: this endpoint is subject to change.

### Example responses

> 200 Response

```json
{
  "providers": [
    {
      "available": true,
      "models": [
        {
          "display_name": "string",
          "id": "string",
          "model": "string",
          "provider": "string"
        }
      ],
      "provider": "string",
      "unavailable_reason": "missing_api_key"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ChatModelsResponse](schemas.md#codersdkchatmodelsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Watch chat events for a user via WebSockets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/watch \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/watch`

Experimental: this endpoint is subject to change.

### Example responses

> 200 Response

```json
{
  "chat": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "archived": true,
    "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
    "children": [
      {}
    ],
    "client_type": "ui",
    "created_at": "2019-08-24T14:15:22Z",
    "diff_status": {
      "additions": 0,
      "approved": true,
      "author_avatar_url": "string",
      "author_login": "string",
      "base_branch": "string",
      "changed_files": 0,
      "changes_requested": true,
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "commits": 0,
      "deletions": 0,
      "head_branch": "string",
      "pr_number": 0,
      "pull_request_draft": true,
      "pull_request_state": "string",
      "pull_request_title": "string",
      "refreshed_at": "2019-08-24T14:15:22Z",
      "reviewer_count": 0,
      "stale_at": "2019-08-24T14:15:22Z",
      "url": "string"
    },
    "files": [
      {
        "created_at": "2019-08-24T14:15:22Z",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "mime_type": "string",
        "name": "string",
        "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
        "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
      }
    ],
    "has_unread": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "labels": {
      "property1": "string",
      "property2": "string"
    },
    "last_error": {
      "detail": "string",
      "kind": "generic",
      "message": "string",
      "provider": "string",
      "retryable": true,
      "status_code": 0
    },
    "last_injected_context": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
    "last_turn_summary": "string",
    "mcp_server_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
    "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
    "pin_order": 0,
    "plan_mode": "plan",
    "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
    "status": "waiting",
    "title": "string",
    "updated_at": "2019-08-24T14:15:22Z",
    "warnings": [
      "string"
    ],
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "kind": "status_change",
  "tool_calls": [
    {
      "args": "string",
      "tool_call_id": "string",
      "tool_name": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ChatWatchEvent](schemas.md#codersdkchatwatchevent) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get chat by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/{chat} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/{chat}`

Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `chat` | path | string(uuid) | true     | Chat ID     |

### Example responses

> 200 Response

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "archived": true,
  "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
  "children": [
    {
      "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
      "archived": true,
      "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
      "children": [],
      "client_type": "ui",
      "created_at": "2019-08-24T14:15:22Z",
      "diff_status": {
        "additions": 0,
        "approved": true,
        "author_avatar_url": "string",
        "author_login": "string",
        "base_branch": "string",
        "changed_files": 0,
        "changes_requested": true,
        "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
        "commits": 0,
        "deletions": 0,
        "head_branch": "string",
        "pr_number": 0,
        "pull_request_draft": true,
        "pull_request_state": "string",
        "pull_request_title": "string",
        "refreshed_at": "2019-08-24T14:15:22Z",
        "reviewer_count": 0,
        "stale_at": "2019-08-24T14:15:22Z",
        "url": "string"
      },
      "files": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "mime_type": "string",
          "name": "string",
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
        }
      ],
      "has_unread": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "last_error": {
        "detail": "string",
        "kind": "generic",
        "message": "string",
        "provider": "string",
        "retryable": true,
        "status_code": 0
      },
      "last_injected_context": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
      "last_turn_summary": "string",
      "mcp_server_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
      "pin_order": 0,
      "plan_mode": "plan",
      "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
      "status": "waiting",
      "title": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "warnings": [
        "string"
      ],
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ],
  "client_type": "ui",
  "created_at": "2019-08-24T14:15:22Z",
  "diff_status": {
    "additions": 0,
    "approved": true,
    "author_avatar_url": "string",
    "author_login": "string",
    "base_branch": "string",
    "changed_files": 0,
    "changes_requested": true,
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "commits": 0,
    "deletions": 0,
    "head_branch": "string",
    "pr_number": 0,
    "pull_request_draft": true,
    "pull_request_state": "string",
    "pull_request_title": "string",
    "refreshed_at": "2019-08-24T14:15:22Z",
    "reviewer_count": 0,
    "stale_at": "2019-08-24T14:15:22Z",
    "url": "string"
  },
  "files": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "mime_type": "string",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
    }
  ],
  "has_unread": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "last_error": {
    "detail": "string",
    "kind": "generic",
    "message": "string",
    "provider": "string",
    "retryable": true,
    "status_code": 0
  },
  "last_injected_context": [
    {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    }
  ],
  "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
  "last_turn_summary": "string",
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
  "pin_order": 0,
  "plan_mode": "plan",
  "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
  "status": "waiting",
  "title": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "string"
  ],
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Chat](schemas.md#codersdkchat) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update chat

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/experimental/chats/{chat} \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/experimental/chats/{chat}`

Experimental: this endpoint is subject to change.

> Body parameter

```json
{
  "archived": true,
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "pin_order": 0,
  "plan_mode": "plan",
  "title": "string",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Parameters

| Name   | In   | Type                                                               | Required | Description         |
|--------|------|--------------------------------------------------------------------|----------|---------------------|
| `chat` | path | string(uuid)                                                       | true     | Chat ID             |
| `body` | body | [codersdk.UpdateChatRequest](schemas.md#codersdkupdatechatrequest) | true     | Update chat request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get chat diff contents

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/{chat}/diff \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/{chat}/diff`

Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `chat` | path | string(uuid) | true     | Chat ID     |

### Example responses

> 200 Response

```json
{
  "branch": "string",
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "diff": "string",
  "provider": "string",
  "pull_request_url": "string",
  "remote_origin": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ChatDiffContents](schemas.md#codersdkchatdiffcontents) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Interrupt chat

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/experimental/chats/{chat}/interrupt \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/experimental/chats/{chat}/interrupt`

Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `chat` | path | string(uuid) | true     | Chat ID     |

### Example responses

> 200 Response

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "archived": true,
  "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
  "children": [
    {
      "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
      "archived": true,
      "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
      "children": [],
      "client_type": "ui",
      "created_at": "2019-08-24T14:15:22Z",
      "diff_status": {
        "additions": 0,
        "approved": true,
        "author_avatar_url": "string",
        "author_login": "string",
        "base_branch": "string",
        "changed_files": 0,
        "changes_requested": true,
        "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
        "commits": 0,
        "deletions": 0,
        "head_branch": "string",
        "pr_number": 0,
        "pull_request_draft": true,
        "pull_request_state": "string",
        "pull_request_title": "string",
        "refreshed_at": "2019-08-24T14:15:22Z",
        "reviewer_count": 0,
        "stale_at": "2019-08-24T14:15:22Z",
        "url": "string"
      },
      "files": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "mime_type": "string",
          "name": "string",
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
        }
      ],
      "has_unread": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "last_error": {
        "detail": "string",
        "kind": "generic",
        "message": "string",
        "provider": "string",
        "retryable": true,
        "status_code": 0
      },
      "last_injected_context": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
      "last_turn_summary": "string",
      "mcp_server_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
      "pin_order": 0,
      "plan_mode": "plan",
      "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
      "status": "waiting",
      "title": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "warnings": [
        "string"
      ],
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ],
  "client_type": "ui",
  "created_at": "2019-08-24T14:15:22Z",
  "diff_status": {
    "additions": 0,
    "approved": true,
    "author_avatar_url": "string",
    "author_login": "string",
    "base_branch": "string",
    "changed_files": 0,
    "changes_requested": true,
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "commits": 0,
    "deletions": 0,
    "head_branch": "string",
    "pr_number": 0,
    "pull_request_draft": true,
    "pull_request_state": "string",
    "pull_request_title": "string",
    "refreshed_at": "2019-08-24T14:15:22Z",
    "reviewer_count": 0,
    "stale_at": "2019-08-24T14:15:22Z",
    "url": "string"
  },
  "files": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "mime_type": "string",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
    }
  ],
  "has_unread": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "last_error": {
    "detail": "string",
    "kind": "generic",
    "message": "string",
    "provider": "string",
    "retryable": true,
    "status_code": 0
  },
  "last_injected_context": [
    {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    }
  ],
  "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
  "last_turn_summary": "string",
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
  "pin_order": 0,
  "plan_mode": "plan",
  "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
  "status": "waiting",
  "title": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "string"
  ],
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Chat](schemas.md#codersdkchat) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List chat messages

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/{chat}/messages \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/{chat}/messages`

Experimental: this endpoint is subject to change.

### Parameters

| Name        | In    | Type         | Required | Description                          |
|-------------|-------|--------------|----------|--------------------------------------|
| `chat`      | path  | string(uuid) | true     | Chat ID                              |
| `before_id` | query | integer      | false    | Return messages with id < before_id  |
| `after_id`  | query | integer      | false    | Return messages with id > after_id   |
| `limit`     | query | integer      | false    | Page size, 1 to 200. Defaults to 50. |

### Example responses

> 200 Response

```json
{
  "has_more": true,
  "messages": [
    {
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "content": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
      "id": 0,
      "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
      "role": "system",
      "usage": {
        "cache_creation_tokens": 0,
        "cache_read_tokens": 0,
        "context_limit": 0,
        "input_tokens": 0,
        "output_tokens": 0,
        "reasoning_tokens": 0,
        "total_tokens": 0
      }
    }
  ],
  "queued_messages": [
    {
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "content": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "id": 0,
      "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ChatMessagesResponse](schemas.md#codersdkchatmessagesresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Send chat message

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/experimental/chats/{chat}/messages \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/experimental/chats/{chat}/messages`

Experimental: this endpoint is subject to change.

> Body parameter

```json
{
  "busy_behavior": "queue",
  "content": [
    {
      "content": "string",
      "end_line": 0,
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "file_name": "string",
      "start_line": 0,
      "text": "string",
      "type": "text"
    }
  ],
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
  "plan_mode": "plan"
}
```

### Parameters

| Name   | In   | Type                                                                             | Required | Description                 |
|--------|------|----------------------------------------------------------------------------------|----------|-----------------------------|
| `chat` | path | string(uuid)                                                                     | true     | Chat ID                     |
| `body` | body | [codersdk.CreateChatMessageRequest](schemas.md#codersdkcreatechatmessagerequest) | true     | Create chat message request |

### Example responses

> 200 Response

```json
{
  "message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
    "role": "system",
    "usage": {
      "cache_creation_tokens": 0,
      "cache_read_tokens": 0,
      "context_limit": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "reasoning_tokens": 0,
      "total_tokens": 0
    }
  },
  "queued": true,
  "queued_message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205"
  },
  "warnings": [
    "string"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                             |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.CreateChatMessageResponse](schemas.md#codersdkcreatechatmessageresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Edit chat message

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/experimental/chats/{chat}/messages/{message} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/experimental/chats/{chat}/messages/{message}`

Experimental: this endpoint is subject to change.

> Body parameter

```json
{
  "content": [
    {
      "content": "string",
      "end_line": 0,
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "file_name": "string",
      "start_line": 0,
      "text": "string",
      "type": "text"
    }
  ]
}
```

### Parameters

| Name      | In   | Type                                                                         | Required | Description               |
|-----------|------|------------------------------------------------------------------------------|----------|---------------------------|
| `chat`    | path | string(uuid)                                                                 | true     | Chat ID                   |
| `message` | path | integer                                                                      | true     | Message ID                |
| `body`    | body | [codersdk.EditChatMessageRequest](schemas.md#codersdkeditchatmessagerequest) | true     | Edit chat message request |

### Example responses

> 200 Response

```json
{
  "message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
    "role": "system",
    "usage": {
      "cache_creation_tokens": 0,
      "cache_read_tokens": 0,
      "context_limit": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "reasoning_tokens": 0,
      "total_tokens": 0
    }
  },
  "warnings": [
    "string"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                         |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.EditChatMessageResponse](schemas.md#codersdkeditchatmessageresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Stream chat events via WebSockets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/{chat}/stream \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/{chat}/stream`

Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `chat` | path | string(uuid) | true     | Chat ID     |

### Example responses

> 200 Response

```json
{
  "action_required": {
    "tool_calls": [
      {
        "args": "string",
        "tool_call_id": "string",
        "tool_name": "string"
      }
    ]
  },
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "error": {
    "detail": "string",
    "kind": "generic",
    "message": "string",
    "provider": "string",
    "retryable": true,
    "status_code": 0
  },
  "message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
    "role": "system",
    "usage": {
      "cache_creation_tokens": 0,
      "cache_read_tokens": 0,
      "context_limit": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "reasoning_tokens": 0,
      "total_tokens": 0
    }
  },
  "message_part": {
    "part": {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    },
    "role": "system"
  },
  "queued_messages": [
    {
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "content": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "id": 0,
      "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205"
    }
  ],
  "retry": {
    "attempt": 0,
    "delay_ms": 0,
    "error": "string",
    "kind": "generic",
    "provider": "string",
    "retrying_at": "2019-08-24T14:15:22Z",
    "status_code": 0
  },
  "status": {
    "status": "waiting"
  },
  "type": "message_part"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ChatStreamEvent](schemas.md#codersdkchatstreamevent) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Connect to chat workspace desktop via WebSockets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/{chat}/stream/desktop \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/{chat}/stream/desktop`

Raw binary WebSocket stream of the chat workspace desktop.
Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `chat` | path | string(uuid) | true     | Chat ID     |

### Responses

| Status | Meaning                                                                  | Description         | Schema |
|--------|--------------------------------------------------------------------------|---------------------|--------|
| 101    | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Watch chat workspace git state via WebSockets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/experimental/chats/{chat}/stream/git \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/experimental/chats/{chat}/stream/git`

Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `chat` | path | string(uuid) | true     | Chat ID     |

### Example responses

> 200 Response

```json
{
  "message": "string",
  "repositories": [
    {
      "branch": "string",
      "remote_origin": "string",
      "removed": true,
      "repo_root": "string",
      "unified_diff": "string"
    }
  ],
  "scanned_at": "2019-08-24T14:15:22Z",
  "type": "changes"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgentGitServerMessage](schemas.md#codersdkworkspaceagentgitservermessage) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Regenerate chat title

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/experimental/chats/{chat}/title/regenerate \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/experimental/chats/{chat}/title/regenerate`

Experimental: this endpoint is subject to change.

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `chat` | path | string(uuid) | true     | Chat ID     |

### Example responses

> 200 Response

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "archived": true,
  "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
  "children": [
    {
      "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
      "archived": true,
      "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
      "children": [],
      "client_type": "ui",
      "created_at": "2019-08-24T14:15:22Z",
      "diff_status": {
        "additions": 0,
        "approved": true,
        "author_avatar_url": "string",
        "author_login": "string",
        "base_branch": "string",
        "changed_files": 0,
        "changes_requested": true,
        "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
        "commits": 0,
        "deletions": 0,
        "head_branch": "string",
        "pr_number": 0,
        "pull_request_draft": true,
        "pull_request_state": "string",
        "pull_request_title": "string",
        "refreshed_at": "2019-08-24T14:15:22Z",
        "reviewer_count": 0,
        "stale_at": "2019-08-24T14:15:22Z",
        "url": "string"
      },
      "files": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "mime_type": "string",
          "name": "string",
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
        }
      ],
      "has_unread": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "last_error": {
        "detail": "string",
        "kind": "generic",
        "message": "string",
        "provider": "string",
        "retryable": true,
        "status_code": 0
      },
      "last_injected_context": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
      "last_turn_summary": "string",
      "mcp_server_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
      "pin_order": 0,
      "plan_mode": "plan",
      "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
      "status": "waiting",
      "title": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "warnings": [
        "string"
      ],
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ],
  "client_type": "ui",
  "created_at": "2019-08-24T14:15:22Z",
  "diff_status": {
    "additions": 0,
    "approved": true,
    "author_avatar_url": "string",
    "author_login": "string",
    "base_branch": "string",
    "changed_files": 0,
    "changes_requested": true,
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "commits": 0,
    "deletions": 0,
    "head_branch": "string",
    "pr_number": 0,
    "pull_request_draft": true,
    "pull_request_state": "string",
    "pull_request_title": "string",
    "refreshed_at": "2019-08-24T14:15:22Z",
    "reviewer_count": 0,
    "stale_at": "2019-08-24T14:15:22Z",
    "url": "string"
  },
  "files": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "mime_type": "string",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
    }
  ],
  "has_unread": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "last_error": {
    "detail": "string",
    "kind": "generic",
    "message": "string",
    "provider": "string",
    "retryable": true,
    "status_code": 0
  },
  "last_injected_context": [
    {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    }
  ],
  "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
  "last_turn_summary": "string",
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
  "pin_order": 0,
  "plan_mode": "plan",
  "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
  "status": "waiting",
  "title": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "string"
  ],
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Chat](schemas.md#codersdkchat) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Debug

Source: https://coder.com/docs/reference/api/debug

# Debug

## Debug Info Wireguard Coordinator

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/debug/coordinator \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/debug/coordinator`

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Debug Info Deployment Health

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/debug/health \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/debug/health`

### Parameters

| Name    | In    | Type    | Required | Description                |
|---------|-------|---------|----------|----------------------------|
| `force` | query | boolean | false    | Force a healthcheck to run |

### Example responses

> 200 Response

```json
{
  "access_url": {
    "access_url": "string",
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "healthz_response": "string",
    "reachable": true,
    "severity": "ok",
    "status_code": 0,
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "coder_version": "string",
  "database": {
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "latency": "string",
    "latency_ms": 0,
    "reachable": true,
    "severity": "ok",
    "threshold_ms": 0,
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "derp": {
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "netcheck": {
      "captivePortal": "string",
      "globalV4": "string",
      "globalV6": "string",
      "hairPinning": "string",
      "icmpv4": true,
      "ipv4": true,
      "ipv4CanSend": true,
      "ipv6": true,
      "ipv6CanSend": true,
      "mappingVariesByDestIP": "string",
      "oshasIPv6": true,
      "pcp": "string",
      "pmp": "string",
      "preferredDERP": 0,
      "regionLatency": {
        "property1": 0,
        "property2": 0
      },
      "regionV4Latency": {
        "property1": 0,
        "property2": 0
      },
      "regionV6Latency": {
        "property1": 0,
        "property2": 0
      },
      "udp": true,
      "upnP": "string"
    },
    "netcheck_err": "string",
    "netcheck_logs": [
      "string"
    ],
    "regions": {
      "property1": {
        "error": "string",
        "healthy": true,
        "node_reports": [
          {
            "can_exchange_messages": true,
            "client_errs": [
              [
                "string"
              ]
            ],
            "client_logs": [
              [
                "string"
              ]
            ],
            "error": "string",
            "healthy": true,
            "node": {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            },
            "node_info": {
              "tokenBucketBytesBurst": 0,
              "tokenBucketBytesPerSecond": 0
            },
            "round_trip_ping": "string",
            "round_trip_ping_ms": 0,
            "severity": "ok",
            "stun": {
              "canSTUN": true,
              "enabled": true,
              "error": "string"
            },
            "uses_websocket": true,
            "warnings": [
              {
                "code": "EUNKNOWN",
                "message": "string"
              }
            ]
          }
        ],
        "region": {
          "avoid": true,
          "embeddedRelay": true,
          "nodes": [
            {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            }
          ],
          "regionCode": "string",
          "regionID": 0,
          "regionName": "string"
        },
        "severity": "ok",
        "warnings": [
          {
            "code": "EUNKNOWN",
            "message": "string"
          }
        ]
      },
      "property2": {
        "error": "string",
        "healthy": true,
        "node_reports": [
          {
            "can_exchange_messages": true,
            "client_errs": [
              [
                "string"
              ]
            ],
            "client_logs": [
              [
                "string"
              ]
            ],
            "error": "string",
            "healthy": true,
            "node": {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            },
            "node_info": {
              "tokenBucketBytesBurst": 0,
              "tokenBucketBytesPerSecond": 0
            },
            "round_trip_ping": "string",
            "round_trip_ping_ms": 0,
            "severity": "ok",
            "stun": {
              "canSTUN": true,
              "enabled": true,
              "error": "string"
            },
            "uses_websocket": true,
            "warnings": [
              {
                "code": "EUNKNOWN",
                "message": "string"
              }
            ]
          }
        ],
        "region": {
          "avoid": true,
          "embeddedRelay": true,
          "nodes": [
            {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            }
          ],
          "regionCode": "string",
          "regionID": 0,
          "regionName": "string"
        },
        "severity": "ok",
        "warnings": [
          {
            "code": "EUNKNOWN",
            "message": "string"
          }
        ]
      }
    },
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "healthy": true,
  "provisioner_daemons": {
    "dismissed": true,
    "error": "string",
    "items": [
      {
        "provisioner_daemon": {
          "api_version": "string",
          "created_at": "2019-08-24T14:15:22Z",
          "current_job": {
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "status": "pending",
            "template_display_name": "string",
            "template_icon": "string",
            "template_name": "string"
          },
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
          "key_name": "string",
          "last_seen_at": "2019-08-24T14:15:22Z",
          "name": "string",
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "previous_job": {
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "status": "pending",
            "template_display_name": "string",
            "template_icon": "string",
            "template_name": "string"
          },
          "provisioners": [
            "string"
          ],
          "status": "offline",
          "tags": {
            "property1": "string",
            "property2": "string"
          },
          "version": "string"
        },
        "warnings": [
          {
            "code": "EUNKNOWN",
            "message": "string"
          }
        ]
      }
    ],
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "severity": "ok",
  "time": "2019-08-24T14:15:22Z",
  "websocket": {
    "body": "string",
    "code": 0,
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "workspace_proxy": {
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ],
    "workspace_proxies": {
      "regions": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "deleted": true,
          "derp_enabled": true,
          "derp_only": true,
          "display_name": "string",
          "healthy": true,
          "icon_url": "string",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "name": "string",
          "path_app_url": "string",
          "status": {
            "checked_at": "2019-08-24T14:15:22Z",
            "report": {
              "errors": [
                "string"
              ],
              "warnings": [
                "string"
              ]
            },
            "status": "ok"
          },
          "updated_at": "2019-08-24T14:15:22Z",
          "version": "string",
          "wildcard_hostname": "string"
        }
      ]
    }
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [healthsdk.HealthcheckReport](schemas.md#healthsdkhealthcheckreport) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get health settings

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/debug/health/settings \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/debug/health/settings`

### Example responses

> 200 Response

```json
{
  "dismissed_healthchecks": [
    "DERP"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [healthsdk.HealthSettings](schemas.md#healthsdkhealthsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update health settings

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/debug/health/settings \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/debug/health/settings`

> Body parameter

```json
{
  "dismissed_healthchecks": [
    "DERP"
  ]
}
```

### Parameters

| Name   | In   | Type                                                                       | Required | Description            |
|--------|------|----------------------------------------------------------------------------|----------|------------------------|
| `body` | body | [healthsdk.UpdateHealthSettings](schemas.md#healthsdkupdatehealthsettings) | true     | Update health settings |

### Example responses

> 200 Response

```json
{
  "dismissed_healthchecks": [
    "DERP"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                     |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [healthsdk.UpdateHealthSettings](schemas.md#healthsdkupdatehealthsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Debug Info Tailnet

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/debug/tailnet \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/debug/tailnet`

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Enterprise

Source: https://coder.com/docs/reference/api/enterprise

# Enterprise

## OAuth2 authorization server metadata

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/.well-known/oauth-authorization-server \
  -H 'Accept: application/json'
```

`GET /.well-known/oauth-authorization-server`

### Example responses

> 200 Response

```json
{
  "authorization_endpoint": "string",
  "code_challenge_methods_supported": [
    "S256"
  ],
  "grant_types_supported": [
    "authorization_code"
  ],
  "issuer": "string",
  "registration_endpoint": "string",
  "response_types_supported": [
    "code"
  ],
  "revocation_endpoint": "string",
  "scopes_supported": [
    "string"
  ],
  "token_endpoint": "string",
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OAuth2AuthorizationServerMetadata](schemas.md#codersdkoauth2authorizationservermetadata) |

## OAuth2 protected resource metadata

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/.well-known/oauth-protected-resource \
  -H 'Accept: application/json'
```

`GET /.well-known/oauth-protected-resource`

### Example responses

> 200 Response

```json
{
  "authorization_servers": [
    "string"
  ],
  "bearer_methods_supported": [
    "string"
  ],
  "resource": "string",
  "scopes_supported": [
    "string"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                         |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OAuth2ProtectedResourceMetadata](schemas.md#codersdkoauth2protectedresourcemetadata) |

## Get appearance

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/appearance \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/appearance`

### Example responses

> 200 Response

```json
{
  "announcement_banners": [
    {
      "background_color": "string",
      "enabled": true,
      "message": "string"
    }
  ],
  "application_name": "string",
  "docs_url": "string",
  "logo_url": "string",
  "service_banner": {
    "background_color": "string",
    "enabled": true,
    "message": "string"
  },
  "support_links": [
    {
      "icon": "bug",
      "location": "navbar",
      "name": "string",
      "target": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AppearanceConfig](schemas.md#codersdkappearanceconfig) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update appearance

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/appearance \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/appearance`

> Body parameter

```json
{
  "announcement_banners": [
    {
      "background_color": "string",
      "enabled": true,
      "message": "string"
    }
  ],
  "application_name": "string",
  "logo_url": "string",
  "service_banner": {
    "background_color": "string",
    "enabled": true,
    "message": "string"
  }
}
```

### Parameters

| Name   | In   | Type                                                                         | Required | Description               |
|--------|------|------------------------------------------------------------------------------|----------|---------------------------|
| `body` | body | [codersdk.UpdateAppearanceConfig](schemas.md#codersdkupdateappearanceconfig) | true     | Update appearance request |

### Example responses

> 200 Response

```json
{
  "announcement_banners": [
    {
      "background_color": "string",
      "enabled": true,
      "message": "string"
    }
  ],
  "application_name": "string",
  "logo_url": "string",
  "service_banner": {
    "background_color": "string",
    "enabled": true,
    "message": "string"
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                       |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UpdateAppearanceConfig](schemas.md#codersdkupdateappearanceconfig) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get connection logs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/connectionlog?limit=0 \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/connectionlog`

### Parameters

| Name     | In    | Type    | Required | Description  |
|----------|-------|---------|----------|--------------|
| `q`      | query | string  | false    | Search query |
| `limit`  | query | integer | true     | Page limit   |
| `offset` | query | integer | false    | Page offset  |

### Example responses

> 200 Response

```json
{
  "connection_logs": [
    {
      "agent_name": "string",
      "connect_time": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "ip": "string",
      "organization": {
        "display_name": "string",
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string"
      },
      "ssh_info": {
        "connection_id": "d3547de1-d1f2-4344-b4c2-17169b7526f9",
        "disconnect_reason": "string",
        "disconnect_time": "2019-08-24T14:15:22Z",
        "exit_code": 0
      },
      "type": "ssh",
      "web_info": {
        "slug_or_port": "string",
        "status_code": 0,
        "user": {
          "avatar_url": "http://example.com",
          "created_at": "2019-08-24T14:15:22Z",
          "email": "user@example.com",
          "has_ai_seat": true,
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "is_service_account": true,
          "last_seen_at": "2019-08-24T14:15:22Z",
          "login_type": "",
          "name": "string",
          "organization_ids": [
            "497f6eca-6276-4993-bfeb-53cbbbba6f08"
          ],
          "roles": [
            {
              "display_name": "string",
              "name": "string",
              "organization_id": "string"
            }
          ],
          "status": "active",
          "theme_preference": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "username": "string"
        },
        "user_agent": "string"
      },
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string",
      "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
      "workspace_owner_username": "string"
    }
  ],
  "count": 0,
  "count_cap": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                     |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ConnectionLogResponse](schemas.md#codersdkconnectionlogresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get entitlements

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/entitlements \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/entitlements`

### Example responses

> 200 Response

```json
{
  "errors": [
    "string"
  ],
  "features": {
    "property1": {
      "actual": 0,
      "enabled": true,
      "entitlement": "entitled",
      "limit": 0,
      "usage_period": {
        "end": "2019-08-24T14:15:22Z",
        "issued_at": "2019-08-24T14:15:22Z",
        "start": "2019-08-24T14:15:22Z"
      }
    },
    "property2": {
      "actual": 0,
      "enabled": true,
      "entitlement": "entitled",
      "limit": 0,
      "usage_period": {
        "end": "2019-08-24T14:15:22Z",
        "issued_at": "2019-08-24T14:15:22Z",
        "start": "2019-08-24T14:15:22Z"
      }
    }
  },
  "has_license": true,
  "refreshed_at": "2019-08-24T14:15:22Z",
  "require_telemetry": true,
  "trial": true,
  "warnings": [
    "string"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Entitlements](schemas.md#codersdkentitlements) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get groups

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/groups?organization=string&has_member=string&group_ids=string \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/groups`

### Parameters

| Name           | In    | Type   | Required | Description                       |
|----------------|-------|--------|----------|-----------------------------------|
| `organization` | query | string | true     | Organization ID or name           |
| `has_member`   | query | string | true     | User ID or name                   |
| `group_ids`    | query | string | true     | Comma separated list of group IDs |

### Example responses

> 200 Response

```json
[
  {
    "avatar_url": "http://example.com",
    "display_name": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "members": [
      {
        "avatar_url": "http://example.com",
        "created_at": "2019-08-24T14:15:22Z",
        "email": "user@example.com",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "is_service_account": true,
        "last_seen_at": "2019-08-24T14:15:22Z",
        "login_type": "",
        "name": "string",
        "status": "active",
        "theme_preference": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "username": "string"
      }
    ],
    "name": "string",
    "organization_display_name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_name": "string",
    "quota_allowance": 0,
    "source": "user",
    "total_member_count": 0
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                              |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Group](schemas.md#codersdkgroup) |

<h3 id="get-groups-responseschema">Response Schema</h3>

Status Code **200**

| Name                          | Type                                                   | Required | Restrictions | Description                                                                                                                                                           |
|-------------------------------|--------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                | array                                                  | false    |              |                                                                                                                                                                       |
| `» avatar_url`                | string(uri)                                            | false    |              |                                                                                                                                                                       |
| `» display_name`              | string                                                 | false    |              |                                                                                                                                                                       |
| `» id`                        | string(uuid)                                           | false    |              |                                                                                                                                                                       |
| `» members`                   | array                                                  | false    |              |                                                                                                                                                                       |
| `»» avatar_url`               | string(uri)                                            | false    |              |                                                                                                                                                                       |
| `»» created_at`               | string(date-time)                                      | true     |              |                                                                                                                                                                       |
| `»» email`                    | string(email)                                          | true     |              |                                                                                                                                                                       |
| `»» id`                       | string(uuid)                                           | true     |              |                                                                                                                                                                       |
| `»» is_service_account`       | boolean                                                | false    |              |                                                                                                                                                                       |
| `»» last_seen_at`             | string(date-time)                                      | false    |              |                                                                                                                                                                       |
| `»» login_type`               | [codersdk.LoginType](schemas.md#codersdklogintype)     | false    |              |                                                                                                                                                                       |
| `»» name`                     | string                                                 | false    |              |                                                                                                                                                                       |
| `»» status`                   | [codersdk.UserStatus](schemas.md#codersdkuserstatus)   | false    |              |                                                                                                                                                                       |
| `»» theme_preference`         | string                                                 | false    |              | Deprecated: this value should be retrieved from `codersdk.UserPreferenceSettings` instead.                                                                            |
| `»» updated_at`               | string(date-time)                                      | false    |              |                                                                                                                                                                       |
| `»» username`                 | string                                                 | true     |              |                                                                                                                                                                       |
| `» name`                      | string                                                 | false    |              |                                                                                                                                                                       |
| `» organization_display_name` | string                                                 | false    |              |                                                                                                                                                                       |
| `» organization_id`           | string(uuid)                                           | false    |              |                                                                                                                                                                       |
| `» organization_name`         | string                                                 | false    |              |                                                                                                                                                                       |
| `» quota_allowance`           | integer                                                | false    |              |                                                                                                                                                                       |
| `» source`                    | [codersdk.GroupSource](schemas.md#codersdkgroupsource) | false    |              |                                                                                                                                                                       |
| `» total_member_count`        | integer                                                | false    |              | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |

#### Enumerated Values

| Property     | Value(s)                                          |
|--------------|---------------------------------------------------|
| `login_type` | ``, `github`, `none`, `oidc`, `password`, `token` |
| `status`     | `active`, `suspended`                             |
| `source`     | `oidc`, `user`                                    |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get group by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/groups/{group} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/groups/{group}`

### Parameters

| Name              | In    | Type    | Required | Description                       |
|-------------------|-------|---------|----------|-----------------------------------|
| `group`           | path  | string  | true     | Group id                          |
| `exclude_members` | query | boolean | false    | Exclude members from the response |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "source": "user",
  "total_member_count": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                     |
|--------|---------------------------------------------------------|-------------|--------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Group](schemas.md#codersdkgroup) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete group by name

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/groups/{group} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/groups/{group}`

### Parameters

| Name    | In   | Type   | Required | Description |
|---------|------|--------|----------|-------------|
| `group` | path | string | true     | Group name  |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "source": "user",
  "total_member_count": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                     |
|--------|---------------------------------------------------------|-------------|--------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Group](schemas.md#codersdkgroup) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update group by name

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/groups/{group} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/groups/{group}`

> Body parameter

```json
{
  "add_users": [
    "string"
  ],
  "avatar_url": "string",
  "display_name": "string",
  "name": "string",
  "quota_allowance": 0,
  "remove_users": [
    "string"
  ]
}
```

### Parameters

| Name    | In   | Type                                                               | Required | Description         |
|---------|------|--------------------------------------------------------------------|----------|---------------------|
| `group` | path | string                                                             | true     | Group name          |
| `body`  | body | [codersdk.PatchGroupRequest](schemas.md#codersdkpatchgrouprequest) | true     | Patch group request |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "source": "user",
  "total_member_count": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                     |
|--------|---------------------------------------------------------|-------------|--------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Group](schemas.md#codersdkgroup) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get group members by group ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/groups/{group}/members \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/groups/{group}/members`

### Parameters

| Name       | In    | Type         | Required | Description         |
|------------|-------|--------------|----------|---------------------|
| `group`    | path  | string       | true     | Group id            |
| `q`        | query | string       | false    | Member search query |
| `after_id` | query | string(uuid) | false    | After ID            |
| `limit`    | query | integer      | false    | Page limit          |
| `offset`   | query | integer      | false    | Page offset         |

### Example responses

> 200 Response

```json
{
  "count": 0,
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GroupMembersResponse](schemas.md#codersdkgroupmembersresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get licenses

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/licenses \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/licenses`

### Example responses

> 200 Response

```json
[
  {
    "claims": {},
    "id": 0,
    "uploaded_at": "2019-08-24T14:15:22Z",
    "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                  |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.License](schemas.md#codersdklicense) |

<h3 id="get-licenses-responseschema">Response Schema</h3>

Status Code **200**

| Name            | Type              | Required | Restrictions | Description                                                                                                                                                                                             |
|-----------------|-------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`  | array             | false    |              |                                                                                                                                                                                                         |
| `» claims`      | object            | false    |              | Claims are the JWT claims asserted by the license.  Here we use a generic string map to ensure that all data from the server is parsed verbatim, not just the fields this version of Coder understands. |
| `» id`          | integer           | false    |              |                                                                                                                                                                                                         |
| `» uploaded_at` | string(date-time) | false    |              |                                                                                                                                                                                                         |
| `» uuid`        | string(uuid)      | false    |              |                                                                                                                                                                                                         |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Add new license

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/licenses \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/licenses`

> Body parameter

```json
{
  "license": "string"
}
```

### Parameters

| Name   | In   | Type                                                               | Required | Description         |
|--------|------|--------------------------------------------------------------------|----------|---------------------|
| `body` | body | [codersdk.AddLicenseRequest](schemas.md#codersdkaddlicenserequest) | true     | Add license request |

### Example responses

> 201 Response

```json
{
  "claims": {},
  "id": 0,
  "uploaded_at": "2019-08-24T14:15:22Z",
  "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                         |
|--------|--------------------------------------------------------------|-------------|------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.License](schemas.md#codersdklicense) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update license entitlements

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/licenses/refresh-entitlements \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/licenses/refresh-entitlements`

### Example responses

> 201 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                           |
|--------|--------------------------------------------------------------|-------------|--------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete license

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/licenses/{id} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/licenses/{id}`

### Parameters

| Name | In   | Type           | Required | Description |
|------|------|----------------|----------|-------------|
| `id` | path | string(number) | true     | License ID  |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update notification template dispatch method

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/notifications/templates/{notification_template}/method \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/notifications/templates/{notification_template}/method`

### Parameters

| Name                    | In   | Type   | Required | Description                |
|-------------------------|------|--------|----------|----------------------------|
| `notification_template` | path | string | true     | Notification template UUID |

### Responses

| Status | Meaning                                                         | Description  | Schema |
|--------|-----------------------------------------------------------------|--------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)         | Success      |        |
| 304    | [Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) | Not modified |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get OAuth2 applications

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/oauth2-provider/apps \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/oauth2-provider/apps`

### Parameters

| Name      | In    | Type   | Required | Description                                  |
|-----------|-------|--------|----------|----------------------------------------------|
| `user_id` | query | string | false    | Filter by applications authorized for a user |

### Example responses

> 200 Response

```json
[
  {
    "callback_url": "string",
    "endpoints": {
      "authorization": "string",
      "device_authorization": "string",
      "token": "string",
      "token_revoke": "string"
    },
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.OAuth2ProviderApp](schemas.md#codersdkoauth2providerapp) |

<h3 id="get-oauth2-applications.-responseschema">Response Schema</h3>

Status Code **200**

| Name                      | Type                                                                 | Required | Restrictions | Description                                                                                                                                                                                             |
|---------------------------|----------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`            | array                                                                | false    |              |                                                                                                                                                                                                         |
| `» callback_url`          | string                                                               | false    |              |                                                                                                                                                                                                         |
| `» endpoints`             | [codersdk.OAuth2AppEndpoints](schemas.md#codersdkoauth2appendpoints) | false    |              | Endpoints are included in the app response for easier discovery. The OAuth2 spec does not have a defined place to find these (for comparison, OIDC has a '/.well-known/openid-configuration' endpoint). |
| `»» authorization`        | string                                                               | false    |              |                                                                                                                                                                                                         |
| `»» device_authorization` | string                                                               | false    |              | Device authorization is optional.                                                                                                                                                                       |
| `»» token`                | string                                                               | false    |              |                                                                                                                                                                                                         |
| `»» token_revoke`         | string                                                               | false    |              |                                                                                                                                                                                                         |
| `» icon`                  | string                                                               | false    |              |                                                                                                                                                                                                         |
| `» id`                    | string(uuid)                                                         | false    |              |                                                                                                                                                                                                         |
| `» name`                  | string                                                               | false    |              |                                                                                                                                                                                                         |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create OAuth2 application

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/oauth2-provider/apps \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/oauth2-provider/apps`

> Body parameter

```json
{
  "callback_url": "string",
  "icon": "string",
  "name": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                     | Required | Description                       |
|--------|------|------------------------------------------------------------------------------------------|----------|-----------------------------------|
| `body` | body | [codersdk.PostOAuth2ProviderAppRequest](schemas.md#codersdkpostoauth2providerapprequest) | true     | The OAuth2 application to create. |

### Example responses

> 200 Response

```json
{
  "callback_url": "string",
  "endpoints": {
    "authorization": "string",
    "device_authorization": "string",
    "token": "string",
    "token_revoke": "string"
  },
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OAuth2ProviderApp](schemas.md#codersdkoauth2providerapp) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get OAuth2 application

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/oauth2-provider/apps/{app} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/oauth2-provider/apps/{app}`

### Parameters

| Name  | In   | Type   | Required | Description |
|-------|------|--------|----------|-------------|
| `app` | path | string | true     | App ID      |

### Example responses

> 200 Response

```json
{
  "callback_url": "string",
  "endpoints": {
    "authorization": "string",
    "device_authorization": "string",
    "token": "string",
    "token_revoke": "string"
  },
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OAuth2ProviderApp](schemas.md#codersdkoauth2providerapp) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update OAuth2 application

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/oauth2-provider/apps/{app} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/oauth2-provider/apps/{app}`

> Body parameter

```json
{
  "callback_url": "string",
  "icon": "string",
  "name": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                   | Required | Description                   |
|--------|------|----------------------------------------------------------------------------------------|----------|-------------------------------|
| `app`  | path | string                                                                                 | true     | App ID                        |
| `body` | body | [codersdk.PutOAuth2ProviderAppRequest](schemas.md#codersdkputoauth2providerapprequest) | true     | Update an OAuth2 application. |

### Example responses

> 200 Response

```json
{
  "callback_url": "string",
  "endpoints": {
    "authorization": "string",
    "device_authorization": "string",
    "token": "string",
    "token_revoke": "string"
  },
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OAuth2ProviderApp](schemas.md#codersdkoauth2providerapp) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete OAuth2 application

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/oauth2-provider/apps/{app} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/oauth2-provider/apps/{app}`

### Parameters

| Name  | In   | Type   | Required | Description |
|-------|------|--------|----------|-------------|
| `app` | path | string | true     | App ID      |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get OAuth2 application secrets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/oauth2-provider/apps/{app}/secrets \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/oauth2-provider/apps/{app}/secrets`

### Parameters

| Name  | In   | Type   | Required | Description |
|-------|------|--------|----------|-------------|
| `app` | path | string | true     | App ID      |

### Example responses

> 200 Response

```json
[
  {
    "client_secret_truncated": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "last_used_at": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                  |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.OAuth2ProviderAppSecret](schemas.md#codersdkoauth2providerappsecret) |

<h3 id="get-oauth2-application-secrets.-responseschema">Response Schema</h3>

Status Code **200**

| Name                        | Type         | Required | Restrictions | Description |
|-----------------------------|--------------|----------|--------------|-------------|
| `[array item]`              | array        | false    |              |             |
| `» client_secret_truncated` | string       | false    |              |             |
| `» id`                      | string(uuid) | false    |              |             |
| `» last_used_at`            | string       | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create OAuth2 application secret

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/oauth2-provider/apps/{app}/secrets \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/oauth2-provider/apps/{app}/secrets`

### Parameters

| Name  | In   | Type   | Required | Description |
|-------|------|--------|----------|-------------|
| `app` | path | string | true     | App ID      |

### Example responses

> 200 Response

```json
[
  {
    "client_secret_full": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                          |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.OAuth2ProviderAppSecretFull](schemas.md#codersdkoauth2providerappsecretfull) |

<h3 id="create-oauth2-application-secret.-responseschema">Response Schema</h3>

Status Code **200**

| Name                   | Type         | Required | Restrictions | Description |
|------------------------|--------------|----------|--------------|-------------|
| `[array item]`         | array        | false    |              |             |
| `» client_secret_full` | string       | false    |              |             |
| `» id`                 | string(uuid) | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete OAuth2 application secret

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/oauth2-provider/apps/{app}/secrets/{secretID} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/oauth2-provider/apps/{app}/secrets/{secretID}`

### Parameters

| Name       | In   | Type   | Required | Description |
|------------|------|--------|----------|-------------|
| `app`      | path | string | true     | App ID      |
| `secretID` | path | string | true     | Secret ID   |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get groups by organization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/groups`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  {
    "avatar_url": "http://example.com",
    "display_name": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "members": [
      {
        "avatar_url": "http://example.com",
        "created_at": "2019-08-24T14:15:22Z",
        "email": "user@example.com",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "is_service_account": true,
        "last_seen_at": "2019-08-24T14:15:22Z",
        "login_type": "",
        "name": "string",
        "status": "active",
        "theme_preference": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "username": "string"
      }
    ],
    "name": "string",
    "organization_display_name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_name": "string",
    "quota_allowance": 0,
    "source": "user",
    "total_member_count": 0
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                              |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Group](schemas.md#codersdkgroup) |

<h3 id="get-groups-by-organization-responseschema">Response Schema</h3>

Status Code **200**

| Name                          | Type                                                   | Required | Restrictions | Description                                                                                                                                                           |
|-------------------------------|--------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                | array                                                  | false    |              |                                                                                                                                                                       |
| `» avatar_url`                | string(uri)                                            | false    |              |                                                                                                                                                                       |
| `» display_name`              | string                                                 | false    |              |                                                                                                                                                                       |
| `» id`                        | string(uuid)                                           | false    |              |                                                                                                                                                                       |
| `» members`                   | array                                                  | false    |              |                                                                                                                                                                       |
| `»» avatar_url`               | string(uri)                                            | false    |              |                                                                                                                                                                       |
| `»» created_at`               | string(date-time)                                      | true     |              |                                                                                                                                                                       |
| `»» email`                    | string(email)                                          | true     |              |                                                                                                                                                                       |
| `»» id`                       | string(uuid)                                           | true     |              |                                                                                                                                                                       |
| `»» is_service_account`       | boolean                                                | false    |              |                                                                                                                                                                       |
| `»» last_seen_at`             | string(date-time)                                      | false    |              |                                                                                                                                                                       |
| `»» login_type`               | [codersdk.LoginType](schemas.md#codersdklogintype)     | false    |              |                                                                                                                                                                       |
| `»» name`                     | string                                                 | false    |              |                                                                                                                                                                       |
| `»» status`                   | [codersdk.UserStatus](schemas.md#codersdkuserstatus)   | false    |              |                                                                                                                                                                       |
| `»» theme_preference`         | string                                                 | false    |              | Deprecated: this value should be retrieved from `codersdk.UserPreferenceSettings` instead.                                                                            |
| `»» updated_at`               | string(date-time)                                      | false    |              |                                                                                                                                                                       |
| `»» username`                 | string                                                 | true     |              |                                                                                                                                                                       |
| `» name`                      | string                                                 | false    |              |                                                                                                                                                                       |
| `» organization_display_name` | string                                                 | false    |              |                                                                                                                                                                       |
| `» organization_id`           | string(uuid)                                           | false    |              |                                                                                                                                                                       |
| `» organization_name`         | string                                                 | false    |              |                                                                                                                                                                       |
| `» quota_allowance`           | integer                                                | false    |              |                                                                                                                                                                       |
| `» source`                    | [codersdk.GroupSource](schemas.md#codersdkgroupsource) | false    |              |                                                                                                                                                                       |
| `» total_member_count`        | integer                                                | false    |              | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |

#### Enumerated Values

| Property     | Value(s)                                          |
|--------------|---------------------------------------------------|
| `login_type` | ``, `github`, `none`, `oidc`, `password`, `token` |
| `status`     | `active`, `suspended`                             |
| `source`     | `oidc`, `user`                                    |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create group for organization

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/groups \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations/{organization}/groups`

> Body parameter

```json
{
  "avatar_url": "string",
  "display_name": "string",
  "name": "string",
  "quota_allowance": 0
}
```

### Parameters

| Name           | In   | Type                                                                 | Required | Description          |
|----------------|------|----------------------------------------------------------------------|----------|----------------------|
| `organization` | path | string                                                               | true     | Organization ID      |
| `body`         | body | [codersdk.CreateGroupRequest](schemas.md#codersdkcreategrouprequest) | true     | Create group request |

### Example responses

> 201 Response

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "source": "user",
  "total_member_count": 0
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                     |
|--------|--------------------------------------------------------------|-------------|--------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.Group](schemas.md#codersdkgroup) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get group by organization and group name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups/{groupName} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/groups/{groupName}`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |
| `groupName`    | path | string       | true     | Group name      |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "source": "user",
  "total_member_count": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                     |
|--------|---------------------------------------------------------|-------------|--------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Group](schemas.md#codersdkgroup) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get group members by organization and group name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups/{groupName}/members \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/groups/{groupName}/members`

### Parameters

| Name           | In    | Type         | Required | Description         |
|----------------|-------|--------------|----------|---------------------|
| `organization` | path  | string(uuid) | true     | Organization ID     |
| `groupName`    | path  | string       | true     | Group name          |
| `q`            | query | string       | false    | Member search query |
| `after_id`     | query | string(uuid) | false    | After ID            |
| `limit`        | query | integer      | false    | Page limit          |
| `offset`       | query | integer      | false    | Page offset         |

### Example responses

> 200 Response

```json
{
  "count": 0,
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                   |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GroupMembersResponse](schemas.md#codersdkgroupmembersresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace quota by user

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members/{user}/workspace-quota \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/members/{user}/workspace-quota`

### Parameters

| Name           | In   | Type         | Required | Description          |
|----------------|------|--------------|----------|----------------------|
| `user`         | path | string       | true     | User ID, name, or me |
| `organization` | path | string(uuid) | true     | Organization ID      |

### Example responses

> 200 Response

```json
{
  "budget": 0,
  "credits_consumed": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceQuota](schemas.md#codersdkworkspacequota) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Serve provisioner daemon

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerdaemons/serve \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/provisionerdaemons/serve`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Responses

| Status | Meaning                                                                  | Description         | Schema |
|--------|--------------------------------------------------------------------------|---------------------|--------|
| 101    | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List provisioner key

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/provisionerkeys`

### Parameters

| Name           | In   | Type   | Required | Description     |
|----------------|------|--------|----------|-----------------|
| `organization` | path | string | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "organization": "452c1a86-a0af-475b-b03f-724878b0f387",
    "tags": {
      "property1": "string",
      "property2": "string"
    }
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ProvisionerKey](schemas.md#codersdkprovisionerkey) |

<h3 id="list-provisioner-key-responseschema">Response Schema</h3>

Status Code **200**

| Name                | Type                                                                 | Required | Restrictions | Description |
|---------------------|----------------------------------------------------------------------|----------|--------------|-------------|
| `[array item]`      | array                                                                | false    |              |             |
| `» created_at`      | string(date-time)                                                    | false    |              |             |
| `» id`              | string(uuid)                                                         | false    |              |             |
| `» name`            | string                                                               | false    |              |             |
| `» organization`    | string(uuid)                                                         | false    |              |             |
| `» tags`            | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags) | false    |              |             |
| `»» [any property]` | string                                                               | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create provisioner key

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations/{organization}/provisionerkeys`

### Parameters

| Name           | In   | Type   | Required | Description     |
|----------------|------|--------|----------|-----------------|
| `organization` | path | string | true     | Organization ID |

### Example responses

> 201 Response

```json
{
  "key": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                                   |
|--------|--------------------------------------------------------------|-------------|------------------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.CreateProvisionerKeyResponse](schemas.md#codersdkcreateprovisionerkeyresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List provisioner key daemons

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/daemons \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/provisionerkeys/daemons`

### Parameters

| Name           | In   | Type   | Required | Description     |
|----------------|------|--------|----------|-----------------|
| `organization` | path | string | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  {
    "daemons": [
      {
        "api_version": "string",
        "created_at": "2019-08-24T14:15:22Z",
        "current_job": {
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "status": "pending",
          "template_display_name": "string",
          "template_icon": "string",
          "template_name": "string"
        },
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
        "key_name": "string",
        "last_seen_at": "2019-08-24T14:15:22Z",
        "name": "string",
        "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
        "previous_job": {
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "status": "pending",
          "template_display_name": "string",
          "template_icon": "string",
          "template_name": "string"
        },
        "provisioners": [
          "string"
        ],
        "status": "offline",
        "tags": {
          "property1": "string",
          "property2": "string"
        },
        "version": "string"
      }
    ],
    "key": {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "organization": "452c1a86-a0af-475b-b03f-724878b0f387",
      "tags": {
        "property1": "string",
        "property2": "string"
      }
    }
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                              |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ProvisionerKeyDaemons](schemas.md#codersdkprovisionerkeydaemons) |

<h3 id="list-provisioner-key-daemons-responseschema">Response Schema</h3>

Status Code **200**

| Name                        | Type                                                                           | Required | Restrictions | Description      |
|-----------------------------|--------------------------------------------------------------------------------|----------|--------------|------------------|
| `[array item]`              | array                                                                          | false    |              |                  |
| `» daemons`                 | array                                                                          | false    |              |                  |
| `»» api_version`            | string                                                                         | false    |              |                  |
| `»» created_at`             | string(date-time)                                                              | false    |              |                  |
| `»» current_job`            | [codersdk.ProvisionerDaemonJob](schemas.md#codersdkprovisionerdaemonjob)       | false    |              |                  |
| `»»» id`                    | string(uuid)                                                                   | false    |              |                  |
| `»»» status`                | [codersdk.ProvisionerJobStatus](schemas.md#codersdkprovisionerjobstatus)       | false    |              |                  |
| `»»» template_display_name` | string                                                                         | false    |              |                  |
| `»»» template_icon`         | string                                                                         | false    |              |                  |
| `»»» template_name`         | string                                                                         | false    |              |                  |
| `»» id`                     | string(uuid)                                                                   | false    |              |                  |
| `»» key_id`                 | string(uuid)                                                                   | false    |              |                  |
| `»» key_name`               | string                                                                         | false    |              | Optional fields. |
| `»» last_seen_at`           | string(date-time)                                                              | false    |              |                  |
| `»» name`                   | string                                                                         | false    |              |                  |
| `»» organization_id`        | string(uuid)                                                                   | false    |              |                  |
| `»» previous_job`           | [codersdk.ProvisionerDaemonJob](schemas.md#codersdkprovisionerdaemonjob)       | false    |              |                  |
| `»» provisioners`           | array                                                                          | false    |              |                  |
| `»» status`                 | [codersdk.ProvisionerDaemonStatus](schemas.md#codersdkprovisionerdaemonstatus) | false    |              |                  |
| `»» tags`                   | object                                                                         | false    |              |                  |
| `»»» [any property]`        | string                                                                         | false    |              |                  |
| `»» version`                | string                                                                         | false    |              |                  |
| `» key`                     | [codersdk.ProvisionerKey](schemas.md#codersdkprovisionerkey)                   | false    |              |                  |
| `»» created_at`             | string(date-time)                                                              | false    |              |                  |
| `»» id`                     | string(uuid)                                                                   | false    |              |                  |
| `»» name`                   | string                                                                         | false    |              |                  |
| `»» organization`           | string(uuid)                                                                   | false    |              |                  |
| `»» tags`                   | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags)           | false    |              |                  |
| `»»» [any property]`        | string                                                                         | false    |              |                  |

#### Enumerated Values

| Property | Value(s)                                                                                        |
|----------|-------------------------------------------------------------------------------------------------|
| `status` | `busy`, `canceled`, `canceling`, `failed`, `idle`, `offline`, `pending`, `running`, `succeeded` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete provisioner key

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/{provisionerkey} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/organizations/{organization}/provisionerkeys/{provisionerkey}`

### Parameters

| Name             | In   | Type   | Required | Description          |
|------------------|------|--------|----------|----------------------|
| `organization`   | path | string | true     | Organization ID      |
| `provisionerkey` | path | string | true     | Provisioner key name |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get the available organization idp sync claim fields

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/available-fields \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/settings/idpsync/available-fields`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  "string"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema          |
|--------|---------------------------------------------------------|-------------|-----------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of string |

<h3 id="get-the-available-organization-idp-sync-claim-fields-responseschema">Response Schema</h3>

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get the organization idp sync claim field values

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/field-values?claimField=string \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/settings/idpsync/field-values`

### Parameters

| Name           | In    | Type           | Required | Description     |
|----------------|-------|----------------|----------|-----------------|
| `organization` | path  | string(uuid)   | true     | Organization ID |
| `claimField`   | query | string(string) | true     | Claim Field     |

### Example responses

> 200 Response

```json
[
  "string"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema          |
|--------|---------------------------------------------------------|-------------|-----------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of string |

<h3 id="get-the-organization-idp-sync-claim-field-values-responseschema">Response Schema</h3>

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get group IdP Sync settings by organization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/groups \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/settings/idpsync/groups`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "legacy_group_name_mapping": {
    "property1": "string",
    "property2": "string"
  },
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "regex_filter": {}
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GroupSyncSettings](schemas.md#codersdkgroupsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update group IdP Sync settings by organization

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/groups \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}/settings/idpsync/groups`

> Body parameter

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "legacy_group_name_mapping": {
    "property1": "string",
    "property2": "string"
  },
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "regex_filter": {}
}
```

### Parameters

| Name           | In   | Type                                                               | Required | Description     |
|----------------|------|--------------------------------------------------------------------|----------|-----------------|
| `organization` | path | string(uuid)                                                       | true     | Organization ID |
| `body`         | body | [codersdk.GroupSyncSettings](schemas.md#codersdkgroupsyncsettings) | true     | New settings    |

### Example responses

> 200 Response

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "legacy_group_name_mapping": {
    "property1": "string",
    "property2": "string"
  },
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "regex_filter": {}
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GroupSyncSettings](schemas.md#codersdkgroupsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update group IdP Sync config

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/groups/config \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}/settings/idpsync/groups/config`

> Body parameter

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "regex_filter": {}
}
```

### Parameters

| Name           | In   | Type                                                                                         | Required | Description             |
|----------------|------|----------------------------------------------------------------------------------------------|----------|-------------------------|
| `organization` | path | string(uuid)                                                                                 | true     | Organization ID or name |
| `body`         | body | [codersdk.PatchGroupIDPSyncConfigRequest](schemas.md#codersdkpatchgroupidpsyncconfigrequest) | true     | New config values       |

### Example responses

> 200 Response

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "legacy_group_name_mapping": {
    "property1": "string",
    "property2": "string"
  },
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "regex_filter": {}
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GroupSyncSettings](schemas.md#codersdkgroupsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update group IdP Sync mapping

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/groups/mapping \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}/settings/idpsync/groups/mapping`

> Body parameter

```json
{
  "add": [
    {
      "gets": "string",
      "given": "string"
    }
  ],
  "remove": [
    {
      "gets": "string",
      "given": "string"
    }
  ]
}
```

### Parameters

| Name           | In   | Type                                                                                           | Required | Description                                   |
|----------------|------|------------------------------------------------------------------------------------------------|----------|-----------------------------------------------|
| `organization` | path | string(uuid)                                                                                   | true     | Organization ID or name                       |
| `body`         | body | [codersdk.PatchGroupIDPSyncMappingRequest](schemas.md#codersdkpatchgroupidpsyncmappingrequest) | true     | Description of the mappings to add and remove |

### Example responses

> 200 Response

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "legacy_group_name_mapping": {
    "property1": "string",
    "property2": "string"
  },
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "regex_filter": {}
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GroupSyncSettings](schemas.md#codersdkgroupsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get role IdP Sync settings by organization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/roles \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/settings/idpsync/roles`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.RoleSyncSettings](schemas.md#codersdkrolesyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update role IdP Sync settings by organization

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/roles \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}/settings/idpsync/roles`

> Body parameter

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  }
}
```

### Parameters

| Name           | In   | Type                                                             | Required | Description     |
|----------------|------|------------------------------------------------------------------|----------|-----------------|
| `organization` | path | string(uuid)                                                     | true     | Organization ID |
| `body`         | body | [codersdk.RoleSyncSettings](schemas.md#codersdkrolesyncsettings) | true     | New settings    |

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.RoleSyncSettings](schemas.md#codersdkrolesyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update role IdP Sync config

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/roles/config \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}/settings/idpsync/roles/config`

> Body parameter

```json
{
  "field": "string"
}
```

### Parameters

| Name           | In   | Type                                                                                       | Required | Description             |
|----------------|------|--------------------------------------------------------------------------------------------|----------|-------------------------|
| `organization` | path | string(uuid)                                                                               | true     | Organization ID or name |
| `body`         | body | [codersdk.PatchRoleIDPSyncConfigRequest](schemas.md#codersdkpatchroleidpsyncconfigrequest) | true     | New config values       |

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.RoleSyncSettings](schemas.md#codersdkrolesyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update role IdP Sync mapping

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/settings/idpsync/roles/mapping \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}/settings/idpsync/roles/mapping`

> Body parameter

```json
{
  "add": [
    {
      "gets": "string",
      "given": "string"
    }
  ],
  "remove": [
    {
      "gets": "string",
      "given": "string"
    }
  ]
}
```

### Parameters

| Name           | In   | Type                                                                                         | Required | Description                                   |
|----------------|------|----------------------------------------------------------------------------------------------|----------|-----------------------------------------------|
| `organization` | path | string(uuid)                                                                                 | true     | Organization ID or name                       |
| `body`         | body | [codersdk.PatchRoleIDPSyncMappingRequest](schemas.md#codersdkpatchroleidpsyncmappingrequest) | true     | Description of the mappings to add and remove |

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.RoleSyncSettings](schemas.md#codersdkrolesyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace sharing settings for organization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/settings/workspace-sharing \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/settings/workspace-sharing`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
{
  "shareable_workspace_owners": "none",
  "sharing_disabled": true,
  "sharing_globally_disabled": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceSharingSettings](schemas.md#codersdkworkspacesharingsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace sharing settings for organization

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/settings/workspace-sharing \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}/settings/workspace-sharing`

> Body parameter

```json
{
  "shareable_workspace_owners": "none",
  "sharing_disabled": true
}
```

### Parameters

| Name           | In   | Type                                                                                                       | Required | Description                |
|----------------|------|------------------------------------------------------------------------------------------------------------|----------|----------------------------|
| `organization` | path | string(uuid)                                                                                               | true     | Organization ID            |
| `body`         | body | [codersdk.UpdateWorkspaceSharingSettingsRequest](schemas.md#codersdkupdateworkspacesharingsettingsrequest) | true     | Workspace sharing settings |

### Example responses

> 200 Response

```json
{
  "shareable_workspace_owners": "none",
  "sharing_disabled": true,
  "sharing_globally_disabled": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceSharingSettings](schemas.md#codersdkworkspacesharingsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Fetch provisioner key details

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/provisionerkeys/{provisionerkey} \
  -H 'Accept: application/json'
```

`GET /api/v2/provisionerkeys/{provisionerkey}`

### Parameters

| Name             | In   | Type   | Required | Description     |
|------------------|------|--------|----------|-----------------|
| `provisionerkey` | path | string | true     | Provisioner Key |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "organization": "452c1a86-a0af-475b-b03f-724878b0f387",
  "tags": {
    "property1": "string",
    "property2": "string"
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ProvisionerKey](schemas.md#codersdkprovisionerkey) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get active replicas

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/replicas \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/replicas`

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "database_latency": 0,
    "error": "string",
    "hostname": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "region_id": 0,
    "relay_address": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                  |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Replica](schemas.md#codersdkreplica) |

<h3 id="get-active-replicas-responseschema">Response Schema</h3>

Status Code **200**

| Name                 | Type              | Required | Restrictions | Description                                                        |
|----------------------|-------------------|----------|--------------|--------------------------------------------------------------------|
| `[array item]`       | array             | false    |              |                                                                    |
| `» created_at`       | string(date-time) | false    |              | Created at is the timestamp when the replica was first seen.       |
| `» database_latency` | integer           | false    |              | Database latency is the latency in microseconds to the database.   |
| `» error`            | string            | false    |              | Error is the replica error.                                        |
| `» hostname`         | string            | false    |              | Hostname is the hostname of the replica.                           |
| `» id`               | string(uuid)      | false    |              | ID is the unique identifier for the replica.                       |
| `» region_id`        | integer           | false    |              | Region ID is the region of the replica.                            |
| `» relay_address`    | string            | false    |              | Relay address is the accessible address to relay DERP connections. |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get the available idp sync claim fields

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/settings/idpsync/available-fields \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/settings/idpsync/available-fields`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  "string"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema          |
|--------|---------------------------------------------------------|-------------|-----------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of string |

<h3 id="get-the-available-idp-sync-claim-fields-responseschema">Response Schema</h3>

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get the idp sync claim field values

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/settings/idpsync/field-values?claimField=string \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/settings/idpsync/field-values`

### Parameters

| Name           | In    | Type           | Required | Description     |
|----------------|-------|----------------|----------|-----------------|
| `organization` | path  | string(uuid)   | true     | Organization ID |
| `claimField`   | query | string(string) | true     | Claim Field     |

### Example responses

> 200 Response

```json
[
  "string"
]
```

### Responses

| Status | Meaning                                                 | Description | Schema          |
|--------|---------------------------------------------------------|-------------|-----------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of string |

<h3 id="get-the-idp-sync-claim-field-values-responseschema">Response Schema</h3>

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get organization IdP Sync settings

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/settings/idpsync/organization \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/settings/idpsync/organization`

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "organization_assign_default": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OrganizationSyncSettings](schemas.md#codersdkorganizationsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update organization IdP Sync settings

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/settings/idpsync/organization \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/settings/idpsync/organization`

> Body parameter

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "organization_assign_default": true
}
```

### Parameters

| Name   | In   | Type                                                                             | Required | Description  |
|--------|------|----------------------------------------------------------------------------------|----------|--------------|
| `body` | body | [codersdk.OrganizationSyncSettings](schemas.md#codersdkorganizationsyncsettings) | true     | New settings |

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "organization_assign_default": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OrganizationSyncSettings](schemas.md#codersdkorganizationsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update organization IdP Sync config

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/settings/idpsync/organization/config \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/settings/idpsync/organization/config`

> Body parameter

```json
{
  "assign_default": true,
  "field": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                                       | Required | Description       |
|--------|------|------------------------------------------------------------------------------------------------------------|----------|-------------------|
| `body` | body | [codersdk.PatchOrganizationIDPSyncConfigRequest](schemas.md#codersdkpatchorganizationidpsyncconfigrequest) | true     | New config values |

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "organization_assign_default": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OrganizationSyncSettings](schemas.md#codersdkorganizationsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update organization IdP Sync mapping

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/settings/idpsync/organization/mapping \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/settings/idpsync/organization/mapping`

> Body parameter

```json
{
  "add": [
    {
      "gets": "string",
      "given": "string"
    }
  ],
  "remove": [
    {
      "gets": "string",
      "given": "string"
    }
  ]
}
```

### Parameters

| Name   | In   | Type                                                                                                         | Required | Description                                   |
|--------|------|--------------------------------------------------------------------------------------------------------------|----------|-----------------------------------------------|
| `body` | body | [codersdk.PatchOrganizationIDPSyncMappingRequest](schemas.md#codersdkpatchorganizationidpsyncmappingrequest) | true     | Description of the mappings to add and remove |

### Example responses

> 200 Response

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "organization_assign_default": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OrganizationSyncSettings](schemas.md#codersdkorganizationsyncsettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template ACLs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates/{template}/acl \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates/{template}/acl`

### Parameters

| Name       | In   | Type         | Required | Description |
|------------|------|--------------|----------|-------------|
| `template` | path | string(uuid) | true     | Template ID |

### Example responses

> 200 Response

```json
{
  "group": [
    {
      "avatar_url": "http://example.com",
      "display_name": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "members": [
        {
          "avatar_url": "http://example.com",
          "created_at": "2019-08-24T14:15:22Z",
          "email": "user@example.com",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "is_service_account": true,
          "last_seen_at": "2019-08-24T14:15:22Z",
          "login_type": "",
          "name": "string",
          "status": "active",
          "theme_preference": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "username": "string"
        }
      ],
      "name": "string",
      "organization_display_name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "organization_name": "string",
      "quota_allowance": 0,
      "role": "admin",
      "source": "user",
      "total_member_count": 0
    }
  ],
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "has_ai_seat": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "organization_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "role": "admin",
      "roles": [
        {
          "display_name": "string",
          "name": "string",
          "organization_id": "string"
        }
      ],
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                 |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TemplateACL](schemas.md#codersdktemplateacl) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update template ACL

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/templates/{template}/acl \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/templates/{template}/acl`

> Body parameter

```json
{
  "group_perms": {
    "8bd26b20-f3e8-48be-a903-46bb920cf671": "use",
    "<group_id>": "admin"
  },
  "user_perms": {
    "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use",
    "<user_id>": "admin"
  }
}
```

### Parameters

| Name       | In   | Type                                                               | Required | Description                 |
|------------|------|--------------------------------------------------------------------|----------|-----------------------------|
| `template` | path | string(uuid)                                                       | true     | Template ID                 |
| `body`     | body | [codersdk.UpdateTemplateACL](schemas.md#codersdkupdatetemplateacl) | true     | Update template ACL request |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template available acl users/groups

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates/{template}/acl/available \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates/{template}/acl/available`

### Parameters

| Name       | In   | Type         | Required | Description |
|------------|------|--------------|----------|-------------|
| `template` | path | string(uuid) | true     | Template ID |

### Example responses

> 200 Response

```json
[
  {
    "groups": [
      {
        "avatar_url": "http://example.com",
        "display_name": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "members": [
          {
            "avatar_url": "http://example.com",
            "created_at": "2019-08-24T14:15:22Z",
            "email": "user@example.com",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "is_service_account": true,
            "last_seen_at": "2019-08-24T14:15:22Z",
            "login_type": "",
            "name": "string",
            "status": "active",
            "theme_preference": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "username": "string"
          }
        ],
        "name": "string",
        "organization_display_name": "string",
        "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
        "organization_name": "string",
        "quota_allowance": 0,
        "source": "user",
        "total_member_count": 0
      }
    ],
    "users": [
      {
        "avatar_url": "http://example.com",
        "created_at": "2019-08-24T14:15:22Z",
        "email": "user@example.com",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "is_service_account": true,
        "last_seen_at": "2019-08-24T14:15:22Z",
        "login_type": "",
        "name": "string",
        "status": "active",
        "theme_preference": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "username": "string"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                            |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ACLAvailable](schemas.md#codersdkaclavailable) |

<h3 id="get-template-available-acl-users/groups-responseschema">Response Schema</h3>

Status Code **200**

| Name                           | Type                                                   | Required | Restrictions | Description                                                                                                                                                           |
|--------------------------------|--------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                 | array                                                  | false    |              |                                                                                                                                                                       |
| `» groups`                     | array                                                  | false    |              |                                                                                                                                                                       |
| `»» avatar_url`                | string(uri)                                            | false    |              |                                                                                                                                                                       |
| `»» display_name`              | string                                                 | false    |              |                                                                                                                                                                       |
| `»» id`                        | string(uuid)                                           | false    |              |                                                                                                                                                                       |
| `»» members`                   | array                                                  | false    |              |                                                                                                                                                                       |
| `»»» avatar_url`               | string(uri)                                            | false    |              |                                                                                                                                                                       |
| `»»» created_at`               | string(date-time)                                      | true     |              |                                                                                                                                                                       |
| `»»» email`                    | string(email)                                          | true     |              |                                                                                                                                                                       |
| `»»» id`                       | string(uuid)                                           | true     |              |                                                                                                                                                                       |
| `»»» is_service_account`       | boolean                                                | false    |              |                                                                                                                                                                       |
| `»»» last_seen_at`             | string(date-time)                                      | false    |              |                                                                                                                                                                       |
| `»»» login_type`               | [codersdk.LoginType](schemas.md#codersdklogintype)     | false    |              |                                                                                                                                                                       |
| `»»» name`                     | string                                                 | false    |              |                                                                                                                                                                       |
| `»»» status`                   | [codersdk.UserStatus](schemas.md#codersdkuserstatus)   | false    |              |                                                                                                                                                                       |
| `»»» theme_preference`         | string                                                 | false    |              | Deprecated: this value should be retrieved from `codersdk.UserPreferenceSettings` instead.                                                                            |
| `»»» updated_at`               | string(date-time)                                      | false    |              |                                                                                                                                                                       |
| `»»» username`                 | string                                                 | true     |              |                                                                                                                                                                       |
| `»» name`                      | string                                                 | false    |              |                                                                                                                                                                       |
| `»» organization_display_name` | string                                                 | false    |              |                                                                                                                                                                       |
| `»» organization_id`           | string(uuid)                                           | false    |              |                                                                                                                                                                       |
| `»» organization_name`         | string                                                 | false    |              |                                                                                                                                                                       |
| `»» quota_allowance`           | integer                                                | false    |              |                                                                                                                                                                       |
| `»» source`                    | [codersdk.GroupSource](schemas.md#codersdkgroupsource) | false    |              |                                                                                                                                                                       |
| `»» total_member_count`        | integer                                                | false    |              | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |
| `» users`                      | array                                                  | false    |              |                                                                                                                                                                       |

#### Enumerated Values

| Property     | Value(s)                                          |
|--------------|---------------------------------------------------|
| `login_type` | ``, `github`, `none`, `oidc`, `password`, `token` |
| `status`     | `active`, `suspended`                             |
| `source`     | `oidc`, `user`                                    |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Invalidate presets for template

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/templates/{template}/prebuilds/invalidate \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/templates/{template}/prebuilds/invalidate`

### Parameters

| Name       | In   | Type         | Required | Description |
|------------|------|--------------|----------|-------------|
| `template` | path | string(uuid) | true     | Template ID |

### Example responses

> 200 Response

```json
{
  "invalidated": [
    {
      "preset_name": "string",
      "template_name": "string",
      "template_version_name": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                             |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.InvalidatePresetsResponse](schemas.md#codersdkinvalidatepresetsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user quiet hours schedule

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/quiet-hours \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/quiet-hours`

### Parameters

| Name   | In   | Type         | Required | Description |
|--------|------|--------------|----------|-------------|
| `user` | path | string(uuid) | true     | User ID     |

### Example responses

> 200 Response

```json
[
  {
    "next": "2019-08-24T14:15:22Z",
    "raw_schedule": "string",
    "time": "string",
    "timezone": "string",
    "user_can_set": true,
    "user_set": true
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                                |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.UserQuietHoursScheduleResponse](schemas.md#codersdkuserquiethoursscheduleresponse) |

<h3 id="get-user-quiet-hours-schedule-responseschema">Response Schema</h3>

Status Code **200**

| Name             | Type              | Required | Restrictions | Description                                                                                                                                                                      |
|------------------|-------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`   | array             | false    |              |                                                                                                                                                                                  |
| `» next`         | string(date-time) | false    |              | Next is the next time that the quiet hours window will start.                                                                                                                    |
| `» raw_schedule` | string            | false    |              |                                                                                                                                                                                  |
| `» time`         | string            | false    |              | Time is the time of day that the quiet hours window starts in the given Timezone each day.                                                                                       |
| `» timezone`     | string            | false    |              | raw format from the cron expression, UTC if unspecified                                                                                                                          |
| `» user_can_set` | boolean           | false    |              | User can set is true if the user is allowed to set their own quiet hours schedule. If false, the user cannot set a custom schedule and the default schedule will always be used. |
| `» user_set`     | boolean           | false    |              | User set is true if the user has set their own quiet hours schedule. If false, the user is using the default schedule.                                                           |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update user quiet hours schedule

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/quiet-hours \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/quiet-hours`

> Body parameter

```json
{
  "schedule": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                                   | Required | Description             |
|--------|------|--------------------------------------------------------------------------------------------------------|----------|-------------------------|
| `user` | path | string(uuid)                                                                                           | true     | User ID                 |
| `body` | body | [codersdk.UpdateUserQuietHoursScheduleRequest](schemas.md#codersdkupdateuserquiethoursschedulerequest) | true     | Update schedule request |

### Example responses

> 200 Response

```json
[
  {
    "next": "2019-08-24T14:15:22Z",
    "raw_schedule": "string",
    "time": "string",
    "timezone": "string",
    "user_can_set": true,
    "user_set": true
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                                |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.UserQuietHoursScheduleResponse](schemas.md#codersdkuserquiethoursscheduleresponse) |

<h3 id="update-user-quiet-hours-schedule-responseschema">Response Schema</h3>

Status Code **200**

| Name             | Type              | Required | Restrictions | Description                                                                                                                                                                      |
|------------------|-------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`   | array             | false    |              |                                                                                                                                                                                  |
| `» next`         | string(date-time) | false    |              | Next is the next time that the quiet hours window will start.                                                                                                                    |
| `» raw_schedule` | string            | false    |              |                                                                                                                                                                                  |
| `» time`         | string            | false    |              | Time is the time of day that the quiet hours window starts in the given Timezone each day.                                                                                       |
| `» timezone`     | string            | false    |              | raw format from the cron expression, UTC if unspecified                                                                                                                          |
| `» user_can_set` | boolean           | false    |              | User can set is true if the user is allowed to set their own quiet hours schedule. If false, the user cannot set a custom schedule and the default schedule will always be used. |
| `» user_set`     | boolean           | false    |              | User set is true if the user has set their own quiet hours schedule. If false, the user is using the default schedule.                                                           |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace quota by user deprecated

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspace-quota/{user} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspace-quota/{user}`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "budget": 0,
  "credits_consumed": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceQuota](schemas.md#codersdkworkspacequota) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace proxies

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceproxies \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceproxies`

### Example responses

> 200 Response

```json
[
  {
    "regions": [
      {
        "created_at": "2019-08-24T14:15:22Z",
        "deleted": true,
        "derp_enabled": true,
        "derp_only": true,
        "display_name": "string",
        "healthy": true,
        "icon_url": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string",
        "path_app_url": "string",
        "status": {
          "checked_at": "2019-08-24T14:15:22Z",
          "report": {
            "errors": [
              "string"
            ],
            "warnings": [
              "string"
            ]
          },
          "status": "ok"
        },
        "updated_at": "2019-08-24T14:15:22Z",
        "version": "string",
        "wildcard_hostname": "string"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                                                  |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.RegionsResponse-codersdk_WorkspaceProxy](schemas.md#codersdkregionsresponse-codersdk_workspaceproxy) |

<h3 id="get-workspace-proxies-responseschema">Response Schema</h3>

Status Code **200**

| Name                   | Type                                                                     | Required | Restrictions | Description                                                                                                                                                                       |
|------------------------|--------------------------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`         | array                                                                    | false    |              |                                                                                                                                                                                   |
| `» regions`            | array                                                                    | false    |              |                                                                                                                                                                                   |
| `»» created_at`        | string(date-time)                                                        | false    |              |                                                                                                                                                                                   |
| `»» deleted`           | boolean                                                                  | false    |              |                                                                                                                                                                                   |
| `»» derp_enabled`      | boolean                                                                  | false    |              |                                                                                                                                                                                   |
| `»» derp_only`         | boolean                                                                  | false    |              |                                                                                                                                                                                   |
| `»» display_name`      | string                                                                   | false    |              |                                                                                                                                                                                   |
| `»» healthy`           | boolean                                                                  | false    |              |                                                                                                                                                                                   |
| `»» icon_url`          | string                                                                   | false    |              |                                                                                                                                                                                   |
| `»» id`                | string(uuid)                                                             | false    |              |                                                                                                                                                                                   |
| `»» name`              | string                                                                   | false    |              |                                                                                                                                                                                   |
| `»» path_app_url`      | string                                                                   | false    |              | Path app URL is the URL to the base path for path apps. Optional unless wildcard_hostname is set. E.g. https://us.example.com                                                     |
| `»» status`            | [codersdk.WorkspaceProxyStatus](schemas.md#codersdkworkspaceproxystatus) | false    |              | Status is the latest status check of the proxy. This will be empty for deleted proxies. This value can be used to determine if a workspace proxy is healthy and ready to use.     |
| `»»» checked_at`       | string(date-time)                                                        | false    |              |                                                                                                                                                                                   |
| `»»» report`           | [codersdk.ProxyHealthReport](schemas.md#codersdkproxyhealthreport)       | false    |              | Report provides more information about the health of the workspace proxy.                                                                                                         |
| `»»»» errors`          | array                                                                    | false    |              | Errors are problems that prevent the workspace proxy from being healthy                                                                                                           |
| `»»»» warnings`        | array                                                                    | false    |              | Warnings do not prevent the workspace proxy from being healthy, but should be addressed.                                                                                          |
| `»»» status`           | [codersdk.ProxyHealthStatus](schemas.md#codersdkproxyhealthstatus)       | false    |              |                                                                                                                                                                                   |
| `»» updated_at`        | string(date-time)                                                        | false    |              |                                                                                                                                                                                   |
| `»» version`           | string                                                                   | false    |              |                                                                                                                                                                                   |
| `»» wildcard_hostname` | string                                                                   | false    |              | Wildcard hostname is the wildcard hostname for subdomain apps. E.g. *.us.example.com E.g.*--suffix.au.example.com Optional. Does not need to be on the same domain as PathAppURL. |

#### Enumerated Values

| Property | Value(s)                                         |
|----------|--------------------------------------------------|
| `status` | `ok`, `unhealthy`, `unreachable`, `unregistered` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create workspace proxy

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaceproxies \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaceproxies`

> Body parameter

```json
{
  "display_name": "string",
  "icon": "string",
  "name": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                   | Required | Description                    |
|--------|------|----------------------------------------------------------------------------------------|----------|--------------------------------|
| `body` | body | [codersdk.CreateWorkspaceProxyRequest](schemas.md#codersdkcreateworkspaceproxyrequest) | true     | Create workspace proxy request |

### Example responses

> 201 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "deleted": true,
  "derp_enabled": true,
  "derp_only": true,
  "display_name": "string",
  "healthy": true,
  "icon_url": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "path_app_url": "string",
  "status": {
    "checked_at": "2019-08-24T14:15:22Z",
    "report": {
      "errors": [
        "string"
      ],
      "warnings": [
        "string"
      ]
    },
    "status": "ok"
  },
  "updated_at": "2019-08-24T14:15:22Z",
  "version": "string",
  "wildcard_hostname": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                       |
|--------|--------------------------------------------------------------|-------------|--------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.WorkspaceProxy](schemas.md#codersdkworkspaceproxy) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace proxy

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaceproxies/{workspaceproxy} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaceproxies/{workspaceproxy}`

### Parameters

| Name             | In   | Type         | Required | Description      |
|------------------|------|--------------|----------|------------------|
| `workspaceproxy` | path | string(uuid) | true     | Proxy ID or name |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "deleted": true,
  "derp_enabled": true,
  "derp_only": true,
  "display_name": "string",
  "healthy": true,
  "icon_url": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "path_app_url": "string",
  "status": {
    "checked_at": "2019-08-24T14:15:22Z",
    "report": {
      "errors": [
        "string"
      ],
      "warnings": [
        "string"
      ]
    },
    "status": "ok"
  },
  "updated_at": "2019-08-24T14:15:22Z",
  "version": "string",
  "wildcard_hostname": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceProxy](schemas.md#codersdkworkspaceproxy) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete workspace proxy

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/workspaceproxies/{workspaceproxy} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/workspaceproxies/{workspaceproxy}`

### Parameters

| Name             | In   | Type         | Required | Description      |
|------------------|------|--------------|----------|------------------|
| `workspaceproxy` | path | string(uuid) | true     | Proxy ID or name |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace proxy

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/workspaceproxies/{workspaceproxy} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/workspaceproxies/{workspaceproxy}`

> Body parameter

```json
{
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "regenerate_token": true
}
```

### Parameters

| Name             | In   | Type                                                                   | Required | Description                    |
|------------------|------|------------------------------------------------------------------------|----------|--------------------------------|
| `workspaceproxy` | path | string(uuid)                                                           | true     | Proxy ID or name               |
| `body`           | body | [codersdk.PatchWorkspaceProxy](schemas.md#codersdkpatchworkspaceproxy) | true     | Update workspace proxy request |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "deleted": true,
  "derp_enabled": true,
  "derp_only": true,
  "display_name": "string",
  "healthy": true,
  "icon_url": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "path_app_url": "string",
  "status": {
    "checked_at": "2019-08-24T14:15:22Z",
    "report": {
      "errors": [
        "string"
      ],
      "warnings": [
        "string"
      ]
    },
    "status": "ok"
  },
  "updated_at": "2019-08-24T14:15:22Z",
  "version": "string",
  "wildcard_hostname": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceProxy](schemas.md#codersdkworkspaceproxy) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace external agent credentials

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/external-agent/{agent}/credentials \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/external-agent/{agent}/credentials`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |
| `agent`     | path | string       | true     | Agent name   |

### Example responses

> 200 Response

```json
{
  "agent_token": "string",
  "command": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ExternalAgentCredentials](schemas.md#codersdkexternalagentcredentials) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## OAuth2 authorization request (GET - show authorization page)

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/oauth2/authorize?client_id=string&state=string&response_type=code \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /oauth2/authorize`

### Parameters

| Name            | In    | Type   | Required | Description                       |
|-----------------|-------|--------|----------|-----------------------------------|
| `client_id`     | query | string | true     | Client ID                         |
| `state`         | query | string | true     | A random unguessable string       |
| `response_type` | query | string | true     | Response type                     |
| `redirect_uri`  | query | string | false    | Redirect here after authorization |
| `scope`         | query | string | false    | Token scopes (currently ignored)  |

#### Enumerated Values

| Parameter       | Value(s)        |
|-----------------|-----------------|
| `response_type` | `code`, `token` |

### Responses

| Status | Meaning                                                 | Description                     | Schema |
|--------|---------------------------------------------------------|---------------------------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Returns HTML authorization page |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## OAuth2 authorization request (POST - process authorization)

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/oauth2/authorize?client_id=string&state=string&response_type=code \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /oauth2/authorize`

### Parameters

| Name            | In    | Type   | Required | Description                       |
|-----------------|-------|--------|----------|-----------------------------------|
| `client_id`     | query | string | true     | Client ID                         |
| `state`         | query | string | true     | A random unguessable string       |
| `response_type` | query | string | true     | Response type                     |
| `redirect_uri`  | query | string | false    | Redirect here after authorization |
| `scope`         | query | string | false    | Token scopes (currently ignored)  |

#### Enumerated Values

| Parameter       | Value(s)        |
|-----------------|-----------------|
| `response_type` | `code`, `token` |

### Responses

| Status | Meaning                                                    | Description                              | Schema |
|--------|------------------------------------------------------------|------------------------------------------|--------|
| 302    | [Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) | Returns redirect with authorization code |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get OAuth2 client configuration (RFC 7592)

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/oauth2/clients/{client_id} \
  -H 'Accept: application/json'
```

`GET /oauth2/clients/{client_id}`

### Parameters

| Name        | In   | Type   | Required | Description |
|-------------|------|--------|----------|-------------|
| `client_id` | path | string | true     | Client ID   |

### Example responses

> 200 Response

```json
{
  "client_id": "string",
  "client_id_issued_at": 0,
  "client_name": "string",
  "client_secret_expires_at": 0,
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "registration_access_token": "string",
  "registration_client_uri": "string",
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                             |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OAuth2ClientConfiguration](schemas.md#codersdkoauth2clientconfiguration) |

## Update OAuth2 client configuration (RFC 7592)

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/oauth2/clients/{client_id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'
```

`PUT /oauth2/clients/{client_id}`

> Body parameter

```json
{
  "client_name": "string",
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_statement": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Parameters

| Name        | In   | Type                                                                                           | Required | Description           |
|-------------|------|------------------------------------------------------------------------------------------------|----------|-----------------------|
| `client_id` | path | string                                                                                         | true     | Client ID             |
| `body`      | body | [codersdk.OAuth2ClientRegistrationRequest](schemas.md#codersdkoauth2clientregistrationrequest) | true     | Client update request |

### Example responses

> 200 Response

```json
{
  "client_id": "string",
  "client_id_issued_at": 0,
  "client_name": "string",
  "client_secret_expires_at": 0,
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "registration_access_token": "string",
  "registration_client_uri": "string",
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                             |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OAuth2ClientConfiguration](schemas.md#codersdkoauth2clientconfiguration) |

## Delete OAuth2 client registration (RFC 7592)

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/oauth2/clients/{client_id}

```

`DELETE /oauth2/clients/{client_id}`

### Parameters

| Name        | In   | Type   | Required | Description |
|-------------|------|--------|----------|-------------|
| `client_id` | path | string | true     | Client ID   |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

## OAuth2 dynamic client registration (RFC 7591)

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/oauth2/register \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'
```

`POST /oauth2/register`

> Body parameter

```json
{
  "client_name": "string",
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_statement": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                           | Required | Description                 |
|--------|------|------------------------------------------------------------------------------------------------|----------|-----------------------------|
| `body` | body | [codersdk.OAuth2ClientRegistrationRequest](schemas.md#codersdkoauth2clientregistrationrequest) | true     | Client registration request |

### Example responses

> 201 Response

```json
{
  "client_id": "string",
  "client_id_issued_at": 0,
  "client_name": "string",
  "client_secret": "string",
  "client_secret_expires_at": 0,
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "registration_access_token": "string",
  "registration_client_uri": "string",
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                                           |
|--------|--------------------------------------------------------------|-------------|--------------------------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.OAuth2ClientRegistrationResponse](schemas.md#codersdkoauth2clientregistrationresponse) |

## Revoke OAuth2 tokens (RFC 7009)

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/oauth2/revoke \

```

`POST /oauth2/revoke`

> Body parameter

```yaml
client_id: string
token: string
token_type_hint: string

```

### Parameters

| Name                | In   | Type   | Required | Description                                           |
|---------------------|------|--------|----------|-------------------------------------------------------|
| `body`              | body | object | true     |                                                       |
| `» client_id`       | body | string | true     | Client ID for authentication                          |
| `» token`           | body | string | true     | The token to revoke                                   |
| `» token_type_hint` | body | string | false    | Hint about token type (access_token or refresh_token) |

### Responses

| Status | Meaning                                                 | Description                | Schema |
|--------|---------------------------------------------------------|----------------------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Token successfully revoked |        |

## OAuth2 token exchange

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/oauth2/tokens \
  -H 'Accept: application/json'
```

`POST /oauth2/tokens`

> Body parameter

```yaml
client_id: string
client_secret: string
code: string
refresh_token: string
grant_type: authorization_code

```

### Parameters

| Name              | In   | Type   | Required | Description                                                   |
|-------------------|------|--------|----------|---------------------------------------------------------------|
| `body`            | body | object | false    |                                                               |
| `» client_id`     | body | string | false    | Client ID, required if grant_type=authorization_code          |
| `» client_secret` | body | string | false    | Client secret, required if grant_type=authorization_code      |
| `» code`          | body | string | false    | Authorization code, required if grant_type=authorization_code |
| `» refresh_token` | body | string | false    | Refresh token, required if grant_type=refresh_token           |
| `» grant_type`    | body | string | true     | Grant type                                                    |

#### Enumerated Values

| Parameter      | Value(s)                                                                            |
|----------------|-------------------------------------------------------------------------------------|
| `» grant_type` | `authorization_code`, `client_credentials`, `implicit`, `password`, `refresh_token` |

### Example responses

> 200 Response

```json
{
  "access_token": "string",
  "expires_in": 0,
  "expiry": "string",
  "refresh_token": "string",
  "token_type": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                 |
|--------|---------------------------------------------------------|-------------|----------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [oauth2.Token](schemas.md#oauth2token) |

## Delete OAuth2 application tokens

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/oauth2/tokens?client_id=string \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /oauth2/tokens`

### Parameters

| Name        | In    | Type   | Required | Description |
|-------------|-------|--------|----------|-------------|
| `client_id` | query | string | true     | Client ID   |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## SCIM 2.0: Service Provider Config

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/scim/v2/ServiceProviderConfig

```

`GET /scim/v2/ServiceProviderConfig`

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

## SCIM 2.0: Get users

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/scim/v2/Users \
  -H 'Authorizaiton: API_KEY'
```

`GET /scim/v2/Users`

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## SCIM 2.0: Create new user

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/scim/v2/Users \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorizaiton: API_KEY'
```

`POST /scim/v2/Users`

> Body parameter

```json
{
  "active": true,
  "emails": [
    {
      "display": "string",
      "primary": true,
      "type": "string",
      "value": "user@example.com"
    }
  ],
  "groups": [
    null
  ],
  "id": "string",
  "meta": {
    "resourceType": "string"
  },
  "name": {
    "familyName": "string",
    "givenName": "string"
  },
  "schemas": [
    "string"
  ],
  "userName": "string"
}
```

### Parameters

| Name   | In   | Type                                         | Required | Description |
|--------|------|----------------------------------------------|----------|-------------|
| `body` | body | [coderd.SCIMUser](schemas.md#coderdscimuser) | true     | New user    |

### Example responses

> 200 Response

```json
{
  "active": true,
  "emails": [
    {
      "display": "string",
      "primary": true,
      "type": "string",
      "value": "user@example.com"
    }
  ],
  "groups": [
    null
  ],
  "id": "string",
  "meta": {
    "resourceType": "string"
  },
  "name": {
    "familyName": "string",
    "givenName": "string"
  },
  "schemas": [
    "string"
  ],
  "userName": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [coderd.SCIMUser](schemas.md#coderdscimuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## SCIM 2.0: Get user by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/scim/v2/Users/{id} \
  -H 'Authorizaiton: API_KEY'
```

`GET /scim/v2/Users/{id}`

### Parameters

| Name | In   | Type         | Required | Description |
|------|------|--------------|----------|-------------|
| `id` | path | string(uuid) | true     | User ID     |

### Responses

| Status | Meaning                                                        | Description | Schema |
|--------|----------------------------------------------------------------|-------------|--------|
| 404    | [Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) | Not Found   |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## SCIM 2.0: Replace user account

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/scim/v2/Users/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/scim+json' \
  -H 'Authorizaiton: API_KEY'
```

`PUT /scim/v2/Users/{id}`

> Body parameter

```json
{
  "active": true,
  "emails": [
    {
      "display": "string",
      "primary": true,
      "type": "string",
      "value": "user@example.com"
    }
  ],
  "groups": [
    null
  ],
  "id": "string",
  "meta": {
    "resourceType": "string"
  },
  "name": {
    "familyName": "string",
    "givenName": "string"
  },
  "schemas": [
    "string"
  ],
  "userName": "string"
}
```

### Parameters

| Name   | In   | Type                                         | Required | Description          |
|--------|------|----------------------------------------------|----------|----------------------|
| `id`   | path | string(uuid)                                 | true     | User ID              |
| `body` | body | [coderd.SCIMUser](schemas.md#coderdscimuser) | true     | Replace user request |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## SCIM 2.0: Update user account

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/scim/v2/Users/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/scim+json' \
  -H 'Authorizaiton: API_KEY'
```

`PATCH /scim/v2/Users/{id}`

> Body parameter

```json
{
  "active": true,
  "emails": [
    {
      "display": "string",
      "primary": true,
      "type": "string",
      "value": "user@example.com"
    }
  ],
  "groups": [
    null
  ],
  "id": "string",
  "meta": {
    "resourceType": "string"
  },
  "name": {
    "familyName": "string",
    "givenName": "string"
  },
  "schemas": [
    "string"
  ],
  "userName": "string"
}
```

### Parameters

| Name   | In   | Type                                         | Required | Description         |
|--------|------|----------------------------------------------|----------|---------------------|
| `id`   | path | string(uuid)                                 | true     | User ID             |
| `body` | body | [coderd.SCIMUser](schemas.md#coderdscimuser) | true     | Update user request |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Files

Source: https://coder.com/docs/reference/api/files

# Files

## Upload file

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/files \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/x-tar' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/files`

> Body parameter

```yaml
file: string

```

### Parameters

| Name           | In     | Type   | Required | Description                                                                                    |
|----------------|--------|--------|----------|------------------------------------------------------------------------------------------------|
| `Content-Type` | header | string | true     | Content-Type must be `application/x-tar` or `application/zip`                                  |
| `body`         | body   | object | true     |                                                                                                |
| `» file`       | body   | binary | true     | File to be uploaded. If using tar format, file must conform to ustar (pax may cause problems). |

### Example responses

> 200 Response

```json
{
  "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd"
}
```

### Responses

| Status | Meaning                                                      | Description                        | Schema                                                       |
|--------|--------------------------------------------------------------|------------------------------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)      | Returns existing file if duplicate | [codersdk.UploadResponse](schemas.md#codersdkuploadresponse) |
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Returns newly created file         | [codersdk.UploadResponse](schemas.md#codersdkuploadresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get file by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/files/{fileID} \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/files/{fileID}`

### Parameters

| Name     | In   | Type         | Required | Description |
|----------|------|--------------|----------|-------------|
| `fileID` | path | string(uuid) | true     | File ID     |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Git

Source: https://coder.com/docs/reference/api/git

# Git

## Get user external auths

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/external-auth \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/external-auth`

### Example responses

> 200 Response

```json
{
  "authenticated": true,
  "created_at": "2019-08-24T14:15:22Z",
  "expires": "2019-08-24T14:15:22Z",
  "has_refresh_token": true,
  "provider_id": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "validate_error": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ExternalAuthLink](schemas.md#codersdkexternalauthlink) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get external auth by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/external-auth/{externalauth} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/external-auth/{externalauth}`

### Parameters

| Name           | In   | Type           | Required | Description     |
|----------------|------|----------------|----------|-----------------|
| `externalauth` | path | string(string) | true     | Git Provider ID |

### Example responses

> 200 Response

```json
{
  "app_install_url": "string",
  "app_installable": true,
  "authenticated": true,
  "device": true,
  "display_name": "string",
  "installations": [
    {
      "account": {
        "avatar_url": "string",
        "id": 0,
        "login": "string",
        "name": "string",
        "profile_url": "string"
      },
      "configure_url": "string",
      "id": 0
    }
  ],
  "supports_revocation": true,
  "user": {
    "avatar_url": "string",
    "id": 0,
    "login": "string",
    "name": "string",
    "profile_url": "string"
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ExternalAuth](schemas.md#codersdkexternalauth) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete external auth user link by ID

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/external-auth/{externalauth} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/external-auth/{externalauth}`

### Parameters

| Name           | In   | Type           | Required | Description     |
|----------------|------|----------------|----------|-----------------|
| `externalauth` | path | string(string) | true     | Git Provider ID |

### Example responses

> 200 Response

```json
{
  "token_revocation_error": "string",
  "token_revoked": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.DeleteExternalAuthByIDResponse](schemas.md#codersdkdeleteexternalauthbyidresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get external auth device by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/external-auth/{externalauth}/device \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/external-auth/{externalauth}/device`

### Parameters

| Name           | In   | Type           | Required | Description     |
|----------------|------|----------------|----------|-----------------|
| `externalauth` | path | string(string) | true     | Git Provider ID |

### Example responses

> 200 Response

```json
{
  "device_code": "string",
  "expires_in": 0,
  "interval": 0,
  "user_code": "string",
  "verification_uri": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ExternalAuthDevice](schemas.md#codersdkexternalauthdevice) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Post external auth device by ID

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/external-auth/{externalauth}/device \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/external-auth/{externalauth}/device`

### Parameters

| Name           | In   | Type           | Required | Description          |
|----------------|------|----------------|----------|----------------------|
| `externalauth` | path | string(string) | true     | External Provider ID |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# InitScript

Source: https://coder.com/docs/reference/api/initscript

# InitScript

## Get agent init script

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/init-script/{os}/{arch}

```

`GET /api/v2/init-script/{os}/{arch}`

### Parameters

| Name   | In   | Type   | Required | Description      |
|--------|------|--------|----------|------------------|
| `os`   | path | string | true     | Operating system |
| `arch` | path | string | true     | Architecture     |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | Success     |        |

---

# Insights

Source: https://coder.com/docs/reference/api/insights

# Insights

## Get deployment DAUs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/insights/daus?tz_offset=0 \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/insights/daus`

### Parameters

| Name        | In    | Type    | Required | Description                |
|-------------|-------|---------|----------|----------------------------|
| `tz_offset` | query | integer | true     | Time-zone offset (e.g. -2) |

### Example responses

> 200 Response

```json
{
  "entries": [
    {
      "amount": 0,
      "date": "string"
    }
  ],
  "tz_hour_offset": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.DAUsResponse](schemas.md#codersdkdausresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get insights about templates

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/insights/templates?start_time=2019-08-24T14%3A15%3A22Z&end_time=2019-08-24T14%3A15%3A22Z&interval=week \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/insights/templates`

### Parameters

| Name           | In    | Type              | Required | Description  |
|----------------|-------|-------------------|----------|--------------|
| `start_time`   | query | string(date-time) | true     | Start time   |
| `end_time`     | query | string(date-time) | true     | End time     |
| `interval`     | query | string            | true     | Interval     |
| `template_ids` | query | array[string]     | false    | Template IDs |

#### Enumerated Values

| Parameter  | Value(s)      |
|------------|---------------|
| `interval` | `day`, `week` |

### Example responses

> 200 Response

```json
{
  "interval_reports": [
    {
      "active_users": 14,
      "end_time": "2019-08-24T14:15:22Z",
      "interval": "week",
      "start_time": "2019-08-24T14:15:22Z",
      "template_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ]
    }
  ],
  "report": {
    "active_users": 22,
    "apps_usage": [
      {
        "display_name": "Visual Studio Code",
        "icon": "string",
        "seconds": 80500,
        "slug": "vscode",
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "times_used": 2,
        "type": "builtin"
      }
    ],
    "end_time": "2019-08-24T14:15:22Z",
    "parameters_usage": [
      {
        "description": "string",
        "display_name": "string",
        "name": "string",
        "options": [
          {
            "description": "string",
            "icon": "string",
            "name": "string",
            "value": "string"
          }
        ],
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "type": "string",
        "values": [
          {
            "count": 0,
            "value": "string"
          }
        ]
      }
    ],
    "start_time": "2019-08-24T14:15:22Z",
    "template_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TemplateInsightsResponse](schemas.md#codersdktemplateinsightsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get insights about user activity

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/insights/user-activity?start_time=2019-08-24T14%3A15%3A22Z&end_time=2019-08-24T14%3A15%3A22Z \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/insights/user-activity`

### Parameters

| Name           | In    | Type              | Required | Description  |
|----------------|-------|-------------------|----------|--------------|
| `start_time`   | query | string(date-time) | true     | Start time   |
| `end_time`     | query | string(date-time) | true     | End time     |
| `template_ids` | query | array[string]     | false    | Template IDs |

### Example responses

> 200 Response

```json
{
  "report": {
    "end_time": "2019-08-24T14:15:22Z",
    "start_time": "2019-08-24T14:15:22Z",
    "template_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "users": [
      {
        "avatar_url": "http://example.com",
        "seconds": 80500,
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
        "username": "string"
      }
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserActivityInsightsResponse](schemas.md#codersdkuseractivityinsightsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get insights about user latency

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/insights/user-latency?start_time=2019-08-24T14%3A15%3A22Z&end_time=2019-08-24T14%3A15%3A22Z \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/insights/user-latency`

### Parameters

| Name           | In    | Type              | Required | Description  |
|----------------|-------|-------------------|----------|--------------|
| `start_time`   | query | string(date-time) | true     | Start time   |
| `end_time`     | query | string(date-time) | true     | End time     |
| `template_ids` | query | array[string]     | false    | Template IDs |

### Example responses

> 200 Response

```json
{
  "report": {
    "end_time": "2019-08-24T14:15:22Z",
    "start_time": "2019-08-24T14:15:22Z",
    "template_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "users": [
      {
        "avatar_url": "http://example.com",
        "latency_ms": {
          "p50": 31.312,
          "p95": 119.832
        },
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
        "username": "string"
      }
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                 |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserLatencyInsightsResponse](schemas.md#codersdkuserlatencyinsightsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get insights about user status counts

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/insights/user-status-counts \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/insights/user-status-counts`

### Parameters

| Name        | In    | Type    | Required | Description                                                   |
|-------------|-------|---------|----------|---------------------------------------------------------------|
| `timezone`  | query | string  | false    | IANA timezone name (e.g. America/St_Johns)                    |
| `tz_offset` | query | integer | false    | Deprecated: Time-zone offset (e.g. -2). Use timezone instead. |

### Example responses

> 200 Response

```json
{
  "status_counts": {
    "property1": [
      {
        "count": 10,
        "date": "2019-08-24T14:15:22Z"
      }
    ],
    "property2": [
      {
        "count": 10,
        "date": "2019-08-24T14:15:22Z"
      }
    ]
  }
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                 |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GetUserStatusCountsResponse](schemas.md#codersdkgetuserstatuscountsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Members

Source: https://coder.com/docs/reference/api/members

# Members

## List organization members

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/members`

### Parameters

| Name           | In   | Type   | Required | Description     |
|----------------|------|--------|----------|-----------------|
| `organization` | path | string | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  {
    "avatar_url": "string",
    "created_at": "2019-08-24T14:15:22Z",
    "email": "string",
    "global_roles": [
      {
        "display_name": "string",
        "name": "string",
        "organization_id": "string"
      }
    ],
    "has_ai_seat": true,
    "is_service_account": true,
    "last_seen_at": "2019-08-24T14:15:22Z",
    "login_type": "",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "roles": [
      {
        "display_name": "string",
        "name": "string",
        "organization_id": "string"
      }
    ],
    "status": "active",
    "updated_at": "2019-08-24T14:15:22Z",
    "user_created_at": "2019-08-24T14:15:22Z",
    "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
    "user_updated_at": "2019-08-24T14:15:22Z",
    "username": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                                |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.OrganizationMemberWithUserData](schemas.md#codersdkorganizationmemberwithuserdata) |

<h3 id="list-organization-members-responseschema">Response Schema</h3>

Status Code **200**

| Name                   | Type                                                 | Required | Restrictions | Description                                                                                      |
|------------------------|------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------|
| `[array item]`         | array                                                | false    |              |                                                                                                  |
| `» avatar_url`         | string                                               | false    |              |                                                                                                  |
| `» created_at`         | string(date-time)                                    | false    |              |                                                                                                  |
| `» email`              | string                                               | false    |              |                                                                                                  |
| `» global_roles`       | array                                                | false    |              |                                                                                                  |
| `»» display_name`      | string                                               | false    |              |                                                                                                  |
| `»» name`              | string                                               | false    |              |                                                                                                  |
| `»» organization_id`   | string                                               | false    |              |                                                                                                  |
| `» has_ai_seat`        | boolean                                              | false    |              | Has ai seat intentionally omits omitempty so the API always includes the field, even when false. |
| `» is_service_account` | boolean                                              | false    |              |                                                                                                  |
| `» last_seen_at`       | string(date-time)                                    | false    |              |                                                                                                  |
| `» login_type`         | [codersdk.LoginType](schemas.md#codersdklogintype)   | false    |              |                                                                                                  |
| `» name`               | string                                               | false    |              |                                                                                                  |
| `» organization_id`    | string(uuid)                                         | false    |              |                                                                                                  |
| `» roles`              | array                                                | false    |              |                                                                                                  |
| `» status`             | [codersdk.UserStatus](schemas.md#codersdkuserstatus) | false    |              |                                                                                                  |
| `» updated_at`         | string(date-time)                                    | false    |              |                                                                                                  |
| `» user_created_at`    | string(date-time)                                    | false    |              |                                                                                                  |
| `» user_id`            | string(uuid)                                         | false    |              |                                                                                                  |
| `» user_updated_at`    | string(date-time)                                    | false    |              |                                                                                                  |
| `» username`           | string                                               | false    |              |                                                                                                  |

#### Enumerated Values

| Property     | Value(s)                                          |
|--------------|---------------------------------------------------|
| `login_type` | ``, `github`, `none`, `oidc`, `password`, `token` |
| `status`     | `active`, `suspended`                             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get member roles by organization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members/roles \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/members/roles`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  {
    "assignable": true,
    "built_in": true,
    "display_name": "string",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_member_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "organization_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "site_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "user_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                  |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.AssignableRoles](schemas.md#codersdkassignableroles) |

<h3 id="get-member-roles-by-organization-responseschema">Response Schema</h3>

Status Code **200**

| Name                                | Type                                                     | Required | Restrictions | Description                                                                                            |
|-------------------------------------|----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------|
| `[array item]`                      | array                                                    | false    |              |                                                                                                        |
| `» assignable`                      | boolean                                                  | false    |              |                                                                                                        |
| `» built_in`                        | boolean                                                  | false    |              | Built in roles are immutable                                                                           |
| `» display_name`                    | string                                                   | false    |              |                                                                                                        |
| `» name`                            | string                                                   | false    |              |                                                                                                        |
| `» organization_id`                 | string(uuid)                                             | false    |              |                                                                                                        |
| `» organization_member_permissions` | array                                                    | false    |              | Organization member permissions are specific for the organization in the field 'OrganizationID' above. |
| `»» action`                         | [codersdk.RBACAction](schemas.md#codersdkrbacaction)     | false    |              |                                                                                                        |
| `»» negate`                         | boolean                                                  | false    |              | Negate makes this a negative permission                                                                |
| `»» resource_type`                  | [codersdk.RBACResource](schemas.md#codersdkrbacresource) | false    |              |                                                                                                        |
| `» organization_permissions`        | array                                                    | false    |              | Organization permissions are specific for the organization in the field 'OrganizationID' above.        |
| `» site_permissions`                | array                                                    | false    |              |                                                                                                        |
| `» user_permissions`                | array                                                    | false    |              |                                                                                                        |

#### Enumerated Values

| Property        | Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `action`        | `application_connect`, `assign`, `create`, `create_agent`, `delete`, `delete_agent`, `read`, `read_personal`, `share`, `ssh`, `start`, `stop`, `unassign`, `update`, `update_agent`, `update_personal`, `use`, `view_insights`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `resource_type` | `*`, `ai_seat`, `aibridge_interception`, `api_key`, `assign_org_role`, `assign_role`, `audit_log`, `boundary_usage`, `chat`, `connection_log`, `crypto_key`, `debug_info`, `deployment_config`, `deployment_stats`, `file`, `group`, `group_member`, `idpsync_settings`, `inbox_notification`, `license`, `notification_message`, `notification_preference`, `notification_template`, `oauth2_app`, `oauth2_app_code_token`, `oauth2_app_secret`, `organization`, `organization_member`, `prebuilt_workspace`, `provisioner_daemon`, `provisioner_jobs`, `replicas`, `system`, `tailnet_coordinator`, `task`, `template`, `usage_event`, `user`, `user_secret`, `webpush_subscription`, `workspace`, `workspace_agent_devcontainers`, `workspace_agent_resource_monitor`, `workspace_dormant`, `workspace_proxy` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update a custom organization role

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members/roles \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/organizations/{organization}/members/roles`

> Body parameter

```json
{
  "display_name": "string",
  "name": "string",
  "organization_member_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "organization_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "site_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "user_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ]
}
```

### Parameters

| Name           | In   | Type                                                               | Required | Description         |
|----------------|------|--------------------------------------------------------------------|----------|---------------------|
| `organization` | path | string(uuid)                                                       | true     | Organization ID     |
| `body`         | body | [codersdk.CustomRoleRequest](schemas.md#codersdkcustomrolerequest) | true     | Update role request |

### Example responses

> 200 Response

```json
[
  {
    "display_name": "string",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_member_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "organization_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "site_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "user_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                            |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Role](schemas.md#codersdkrole) |

<h3 id="update-a-custom-organization-role-responseschema">Response Schema</h3>

Status Code **200**

| Name                                | Type                                                     | Required | Restrictions | Description                                                                                            |
|-------------------------------------|----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------|
| `[array item]`                      | array                                                    | false    |              |                                                                                                        |
| `» display_name`                    | string                                                   | false    |              |                                                                                                        |
| `» name`                            | string                                                   | false    |              |                                                                                                        |
| `» organization_id`                 | string(uuid)                                             | false    |              |                                                                                                        |
| `» organization_member_permissions` | array                                                    | false    |              | Organization member permissions are specific for the organization in the field 'OrganizationID' above. |
| `»» action`                         | [codersdk.RBACAction](schemas.md#codersdkrbacaction)     | false    |              |                                                                                                        |
| `»» negate`                         | boolean                                                  | false    |              | Negate makes this a negative permission                                                                |
| `»» resource_type`                  | [codersdk.RBACResource](schemas.md#codersdkrbacresource) | false    |              |                                                                                                        |
| `» organization_permissions`        | array                                                    | false    |              | Organization permissions are specific for the organization in the field 'OrganizationID' above.        |
| `» site_permissions`                | array                                                    | false    |              |                                                                                                        |
| `» user_permissions`                | array                                                    | false    |              |                                                                                                        |

#### Enumerated Values

| Property        | Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `action`        | `application_connect`, `assign`, `create`, `create_agent`, `delete`, `delete_agent`, `read`, `read_personal`, `share`, `ssh`, `start`, `stop`, `unassign`, `update`, `update_agent`, `update_personal`, `use`, `view_insights`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `resource_type` | `*`, `ai_seat`, `aibridge_interception`, `api_key`, `assign_org_role`, `assign_role`, `audit_log`, `boundary_usage`, `chat`, `connection_log`, `crypto_key`, `debug_info`, `deployment_config`, `deployment_stats`, `file`, `group`, `group_member`, `idpsync_settings`, `inbox_notification`, `license`, `notification_message`, `notification_preference`, `notification_template`, `oauth2_app`, `oauth2_app_code_token`, `oauth2_app_secret`, `organization`, `organization_member`, `prebuilt_workspace`, `provisioner_daemon`, `provisioner_jobs`, `replicas`, `system`, `tailnet_coordinator`, `task`, `template`, `usage_event`, `user`, `user_secret`, `webpush_subscription`, `workspace`, `workspace_agent_devcontainers`, `workspace_agent_resource_monitor`, `workspace_dormant`, `workspace_proxy` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Insert a custom organization role

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/members/roles \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations/{organization}/members/roles`

> Body parameter

```json
{
  "display_name": "string",
  "name": "string",
  "organization_member_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "organization_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "site_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "user_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ]
}
```

### Parameters

| Name           | In   | Type                                                               | Required | Description         |
|----------------|------|--------------------------------------------------------------------|----------|---------------------|
| `organization` | path | string(uuid)                                                       | true     | Organization ID     |
| `body`         | body | [codersdk.CustomRoleRequest](schemas.md#codersdkcustomrolerequest) | true     | Insert role request |

### Example responses

> 200 Response

```json
[
  {
    "display_name": "string",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_member_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "organization_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "site_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "user_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                            |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Role](schemas.md#codersdkrole) |

<h3 id="insert-a-custom-organization-role-responseschema">Response Schema</h3>

Status Code **200**

| Name                                | Type                                                     | Required | Restrictions | Description                                                                                            |
|-------------------------------------|----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------|
| `[array item]`                      | array                                                    | false    |              |                                                                                                        |
| `» display_name`                    | string                                                   | false    |              |                                                                                                        |
| `» name`                            | string                                                   | false    |              |                                                                                                        |
| `» organization_id`                 | string(uuid)                                             | false    |              |                                                                                                        |
| `» organization_member_permissions` | array                                                    | false    |              | Organization member permissions are specific for the organization in the field 'OrganizationID' above. |
| `»» action`                         | [codersdk.RBACAction](schemas.md#codersdkrbacaction)     | false    |              |                                                                                                        |
| `»» negate`                         | boolean                                                  | false    |              | Negate makes this a negative permission                                                                |
| `»» resource_type`                  | [codersdk.RBACResource](schemas.md#codersdkrbacresource) | false    |              |                                                                                                        |
| `» organization_permissions`        | array                                                    | false    |              | Organization permissions are specific for the organization in the field 'OrganizationID' above.        |
| `» site_permissions`                | array                                                    | false    |              |                                                                                                        |
| `» user_permissions`                | array                                                    | false    |              |                                                                                                        |

#### Enumerated Values

| Property        | Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `action`        | `application_connect`, `assign`, `create`, `create_agent`, `delete`, `delete_agent`, `read`, `read_personal`, `share`, `ssh`, `start`, `stop`, `unassign`, `update`, `update_agent`, `update_personal`, `use`, `view_insights`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `resource_type` | `*`, `ai_seat`, `aibridge_interception`, `api_key`, `assign_org_role`, `assign_role`, `audit_log`, `boundary_usage`, `chat`, `connection_log`, `crypto_key`, `debug_info`, `deployment_config`, `deployment_stats`, `file`, `group`, `group_member`, `idpsync_settings`, `inbox_notification`, `license`, `notification_message`, `notification_preference`, `notification_template`, `oauth2_app`, `oauth2_app_code_token`, `oauth2_app_secret`, `organization`, `organization_member`, `prebuilt_workspace`, `provisioner_daemon`, `provisioner_jobs`, `replicas`, `system`, `tailnet_coordinator`, `task`, `template`, `usage_event`, `user`, `user_secret`, `webpush_subscription`, `workspace`, `workspace_agent_devcontainers`, `workspace_agent_resource_monitor`, `workspace_dormant`, `workspace_proxy` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete a custom organization role

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization}/members/roles/{roleName} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/organizations/{organization}/members/roles/{roleName}`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |
| `roleName`     | path | string       | true     | Role name       |

### Example responses

> 200 Response

```json
[
  {
    "display_name": "string",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_member_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "organization_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "site_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "user_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                            |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Role](schemas.md#codersdkrole) |

<h3 id="delete-a-custom-organization-role-responseschema">Response Schema</h3>

Status Code **200**

| Name                                | Type                                                     | Required | Restrictions | Description                                                                                            |
|-------------------------------------|----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------|
| `[array item]`                      | array                                                    | false    |              |                                                                                                        |
| `» display_name`                    | string                                                   | false    |              |                                                                                                        |
| `» name`                            | string                                                   | false    |              |                                                                                                        |
| `» organization_id`                 | string(uuid)                                             | false    |              |                                                                                                        |
| `» organization_member_permissions` | array                                                    | false    |              | Organization member permissions are specific for the organization in the field 'OrganizationID' above. |
| `»» action`                         | [codersdk.RBACAction](schemas.md#codersdkrbacaction)     | false    |              |                                                                                                        |
| `»» negate`                         | boolean                                                  | false    |              | Negate makes this a negative permission                                                                |
| `»» resource_type`                  | [codersdk.RBACResource](schemas.md#codersdkrbacresource) | false    |              |                                                                                                        |
| `» organization_permissions`        | array                                                    | false    |              | Organization permissions are specific for the organization in the field 'OrganizationID' above.        |
| `» site_permissions`                | array                                                    | false    |              |                                                                                                        |
| `» user_permissions`                | array                                                    | false    |              |                                                                                                        |

#### Enumerated Values

| Property        | Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `action`        | `application_connect`, `assign`, `create`, `create_agent`, `delete`, `delete_agent`, `read`, `read_personal`, `share`, `ssh`, `start`, `stop`, `unassign`, `update`, `update_agent`, `update_personal`, `use`, `view_insights`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `resource_type` | `*`, `ai_seat`, `aibridge_interception`, `api_key`, `assign_org_role`, `assign_role`, `audit_log`, `boundary_usage`, `chat`, `connection_log`, `crypto_key`, `debug_info`, `deployment_config`, `deployment_stats`, `file`, `group`, `group_member`, `idpsync_settings`, `inbox_notification`, `license`, `notification_message`, `notification_preference`, `notification_template`, `oauth2_app`, `oauth2_app_code_token`, `oauth2_app_secret`, `organization`, `organization_member`, `prebuilt_workspace`, `provisioner_daemon`, `provisioner_jobs`, `replicas`, `system`, `tailnet_coordinator`, `task`, `template`, `usage_event`, `user`, `user_secret`, `webpush_subscription`, `workspace`, `workspace_agent_devcontainers`, `workspace_agent_resource_monitor`, `workspace_dormant`, `workspace_proxy` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get organization member

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members/{user} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/members/{user}`

### Parameters

| Name           | In   | Type   | Required | Description          |
|----------------|------|--------|----------|----------------------|
| `organization` | path | string | true     | Organization ID      |
| `user`         | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "avatar_url": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "string",
  "global_roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "has_ai_seat": true,
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_created_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
  "user_updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OrganizationMemberWithUserData](schemas.md#codersdkorganizationmemberwithuserdata) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Add organization member

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/members/{user} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations/{organization}/members/{user}`

### Parameters

| Name           | In   | Type   | Required | Description          |
|----------------|------|--------|----------|----------------------|
| `organization` | path | string | true     | Organization ID      |
| `user`         | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OrganizationMember](schemas.md#codersdkorganizationmember) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Remove organization member

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization}/members/{user} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/organizations/{organization}/members/{user}`

### Parameters

| Name           | In   | Type   | Required | Description          |
|----------------|------|--------|----------|----------------------|
| `organization` | path | string | true     | Organization ID      |
| `user`         | path | string | true     | User ID, name, or me |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Assign role to organization member

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members/{user}/roles \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/organizations/{organization}/members/{user}/roles`

> Body parameter

```json
{
  "roles": [
    "string"
  ]
}
```

### Parameters

| Name           | In   | Type                                                   | Required | Description          |
|----------------|------|--------------------------------------------------------|----------|----------------------|
| `organization` | path | string                                                 | true     | Organization ID      |
| `user`         | path | string                                                 | true     | User ID, name, or me |
| `body`         | body | [codersdk.UpdateRoles](schemas.md#codersdkupdateroles) | true     | Update roles request |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OrganizationMember](schemas.md#codersdkorganizationmember) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Paginated organization members

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/paginated-members \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/paginated-members`

### Parameters

| Name           | In    | Type         | Required | Description                          |
|----------------|-------|--------------|----------|--------------------------------------|
| `organization` | path  | string       | true     | Organization ID                      |
| `q`            | query | string       | false    | Member search query                  |
| `after_id`     | query | string(uuid) | false    | After ID                             |
| `limit`        | query | integer      | false    | Page limit, if 0 returns all members |
| `offset`       | query | integer      | false    | Page offset                          |

### Example responses

> 200 Response

```json
[
  {
    "count": 0,
    "members": [
      {
        "avatar_url": "string",
        "created_at": "2019-08-24T14:15:22Z",
        "email": "string",
        "global_roles": [
          {
            "display_name": "string",
            "name": "string",
            "organization_id": "string"
          }
        ],
        "has_ai_seat": true,
        "is_service_account": true,
        "last_seen_at": "2019-08-24T14:15:22Z",
        "login_type": "",
        "name": "string",
        "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
        "roles": [
          {
            "display_name": "string",
            "name": "string",
            "organization_id": "string"
          }
        ],
        "status": "active",
        "updated_at": "2019-08-24T14:15:22Z",
        "user_created_at": "2019-08-24T14:15:22Z",
        "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
        "user_updated_at": "2019-08-24T14:15:22Z",
        "username": "string"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                    |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.PaginatedMembersResponse](schemas.md#codersdkpaginatedmembersresponse) |

<h3 id="paginated-organization-members-responseschema">Response Schema</h3>

Status Code **200**

| Name                    | Type                                                 | Required | Restrictions | Description                                                                                      |
|-------------------------|------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------|
| `[array item]`          | array                                                | false    |              |                                                                                                  |
| `» count`               | integer                                              | false    |              |                                                                                                  |
| `» members`             | array                                                | false    |              |                                                                                                  |
| `»» avatar_url`         | string                                               | false    |              |                                                                                                  |
| `»» created_at`         | string(date-time)                                    | false    |              |                                                                                                  |
| `»» email`              | string                                               | false    |              |                                                                                                  |
| `»» global_roles`       | array                                                | false    |              |                                                                                                  |
| `»»» display_name`      | string                                               | false    |              |                                                                                                  |
| `»»» name`              | string                                               | false    |              |                                                                                                  |
| `»»» organization_id`   | string                                               | false    |              |                                                                                                  |
| `»» has_ai_seat`        | boolean                                              | false    |              | Has ai seat intentionally omits omitempty so the API always includes the field, even when false. |
| `»» is_service_account` | boolean                                              | false    |              |                                                                                                  |
| `»» last_seen_at`       | string(date-time)                                    | false    |              |                                                                                                  |
| `»» login_type`         | [codersdk.LoginType](schemas.md#codersdklogintype)   | false    |              |                                                                                                  |
| `»» name`               | string                                               | false    |              |                                                                                                  |
| `»» organization_id`    | string(uuid)                                         | false    |              |                                                                                                  |
| `»» roles`              | array                                                | false    |              |                                                                                                  |
| `»» status`             | [codersdk.UserStatus](schemas.md#codersdkuserstatus) | false    |              |                                                                                                  |
| `»» updated_at`         | string(date-time)                                    | false    |              |                                                                                                  |
| `»» user_created_at`    | string(date-time)                                    | false    |              |                                                                                                  |
| `»» user_id`            | string(uuid)                                         | false    |              |                                                                                                  |
| `»» user_updated_at`    | string(date-time)                                    | false    |              |                                                                                                  |
| `»» username`           | string                                               | false    |              |                                                                                                  |

#### Enumerated Values

| Property     | Value(s)                                          |
|--------------|---------------------------------------------------|
| `login_type` | ``, `github`, `none`, `oidc`, `password`, `token` |
| `status`     | `active`, `suspended`                             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get site member roles

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/roles \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/roles`

### Example responses

> 200 Response

```json
[
  {
    "assignable": true,
    "built_in": true,
    "display_name": "string",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_member_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "organization_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "site_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ],
    "user_permissions": [
      {
        "action": "application_connect",
        "negate": true,
        "resource_type": "*"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                  |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.AssignableRoles](schemas.md#codersdkassignableroles) |

<h3 id="get-site-member-roles-responseschema">Response Schema</h3>

Status Code **200**

| Name                                | Type                                                     | Required | Restrictions | Description                                                                                            |
|-------------------------------------|----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------|
| `[array item]`                      | array                                                    | false    |              |                                                                                                        |
| `» assignable`                      | boolean                                                  | false    |              |                                                                                                        |
| `» built_in`                        | boolean                                                  | false    |              | Built in roles are immutable                                                                           |
| `» display_name`                    | string                                                   | false    |              |                                                                                                        |
| `» name`                            | string                                                   | false    |              |                                                                                                        |
| `» organization_id`                 | string(uuid)                                             | false    |              |                                                                                                        |
| `» organization_member_permissions` | array                                                    | false    |              | Organization member permissions are specific for the organization in the field 'OrganizationID' above. |
| `»» action`                         | [codersdk.RBACAction](schemas.md#codersdkrbacaction)     | false    |              |                                                                                                        |
| `»» negate`                         | boolean                                                  | false    |              | Negate makes this a negative permission                                                                |
| `»» resource_type`                  | [codersdk.RBACResource](schemas.md#codersdkrbacresource) | false    |              |                                                                                                        |
| `» organization_permissions`        | array                                                    | false    |              | Organization permissions are specific for the organization in the field 'OrganizationID' above.        |
| `» site_permissions`                | array                                                    | false    |              |                                                                                                        |
| `» user_permissions`                | array                                                    | false    |              |                                                                                                        |

#### Enumerated Values

| Property        | Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `action`        | `application_connect`, `assign`, `create`, `create_agent`, `delete`, `delete_agent`, `read`, `read_personal`, `share`, `ssh`, `start`, `stop`, `unassign`, `update`, `update_agent`, `update_personal`, `use`, `view_insights`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `resource_type` | `*`, `ai_seat`, `aibridge_interception`, `api_key`, `assign_org_role`, `assign_role`, `audit_log`, `boundary_usage`, `chat`, `connection_log`, `crypto_key`, `debug_info`, `deployment_config`, `deployment_stats`, `file`, `group`, `group_member`, `idpsync_settings`, `inbox_notification`, `license`, `notification_message`, `notification_preference`, `notification_template`, `oauth2_app`, `oauth2_app_code_token`, `oauth2_app_secret`, `organization`, `organization_member`, `prebuilt_workspace`, `provisioner_daemon`, `provisioner_jobs`, `replicas`, `system`, `tailnet_coordinator`, `task`, `template`, `usage_event`, `user`, `user_secret`, `webpush_subscription`, `workspace`, `workspace_agent_devcontainers`, `workspace_agent_resource_monitor`, `workspace_dormant`, `workspace_proxy` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Notifications

Source: https://coder.com/docs/reference/api/notifications

# Notifications

## Send a custom notification

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/notifications/custom \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/notifications/custom`

> Body parameter

```json
{
  "content": {
    "message": "string",
    "title": "string"
  }
}
```

### Parameters

| Name   | In   | Type                                                                               | Required | Description                          |
|--------|------|------------------------------------------------------------------------------------|----------|--------------------------------------|
| `body` | body | [codersdk.CustomNotificationRequest](schemas.md#codersdkcustomnotificationrequest) | true     | Provide a non-empty title or message |

### Example responses

> 400 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                                    | Description                                   | Schema                                           |
|--------|----------------------------------------------------------------------------|-----------------------------------------------|--------------------------------------------------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5)            | No Content                                    |                                                  |
| 400    | [Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1)           | Invalid request body                          | [codersdk.Response](schemas.md#codersdkresponse) |
| 403    | [Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3)             | System users cannot send custom notifications | [codersdk.Response](schemas.md#codersdkresponse) |
| 500    | [Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) | Failed to send custom notification            | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get notification dispatch methods

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/notifications/dispatch-methods \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/notifications/dispatch-methods`

### Example responses

> 200 Response

```json
[
  {
    "available": [
      "string"
    ],
    "default": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                          |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.NotificationMethodsResponse](schemas.md#codersdknotificationmethodsresponse) |

<h3 id="get-notification-dispatch-methods-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `[array item]` | array  | false    |              |             |
| `» available`  | array  | false    |              |             |
| `» default`    | string | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List inbox notifications

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/notifications/inbox \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/notifications/inbox`

### Parameters

| Name              | In    | Type         | Required | Description                                                                                                     |
|-------------------|-------|--------------|----------|-----------------------------------------------------------------------------------------------------------------|
| `targets`         | query | string       | false    | Comma-separated list of target IDs to filter notifications                                                      |
| `templates`       | query | string       | false    | Comma-separated list of template IDs to filter notifications                                                    |
| `read_status`     | query | string       | false    | Filter notifications by read status. Possible values: read, unread, all                                         |
| `starting_before` | query | string(uuid) | false    | ID of the last notification from the current page. Notifications returned will be older than the associated one |

### Example responses

> 200 Response

```json
{
  "notifications": [
    {
      "actions": [
        {
          "label": "string",
          "url": "string"
        }
      ],
      "content": "string",
      "created_at": "2019-08-24T14:15:22Z",
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "read_at": "string",
      "targets": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "title": "string",
      "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
    }
  ],
  "unread_count": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ListInboxNotificationsResponse](schemas.md#codersdklistinboxnotificationsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Mark all unread notifications as read

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/notifications/inbox/mark-all-as-read \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/notifications/inbox/mark-all-as-read`

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Watch for new inbox notifications

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/notifications/inbox/watch \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/notifications/inbox/watch`

### Parameters

| Name          | In    | Type   | Required | Description                                                             |
|---------------|-------|--------|----------|-------------------------------------------------------------------------|
| `targets`     | query | string | false    | Comma-separated list of target IDs to filter notifications              |
| `templates`   | query | string | false    | Comma-separated list of template IDs to filter notifications            |
| `read_status` | query | string | false    | Filter notifications by read status. Possible values: read, unread, all |
| `format`      | query | string | false    | Define the output format for notifications title and body.              |

#### Enumerated Values

| Parameter | Value(s)                |
|-----------|-------------------------|
| `format`  | `markdown`, `plaintext` |

### Example responses

> 200 Response

```json
{
  "notification": {
    "actions": [
      {
        "label": "string",
        "url": "string"
      }
    ],
    "content": "string",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "read_at": "string",
    "targets": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "title": "string",
    "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
  },
  "unread_count": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GetInboxNotificationResponse](schemas.md#codersdkgetinboxnotificationresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update read status of a notification

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/notifications/inbox/{id}/read-status \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/notifications/inbox/{id}/read-status`

### Parameters

| Name | In   | Type   | Required | Description            |
|------|------|--------|----------|------------------------|
| `id` | path | string | true     | id of the notification |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get notifications settings

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/notifications/settings \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/notifications/settings`

### Example responses

> 200 Response

```json
{
  "notifier_paused": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                     |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.NotificationsSettings](schemas.md#codersdknotificationssettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update notifications settings

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/notifications/settings \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/notifications/settings`

> Body parameter

```json
{
  "notifier_paused": true
}
```

### Parameters

| Name   | In   | Type                                                                       | Required | Description                    |
|--------|------|----------------------------------------------------------------------------|----------|--------------------------------|
| `body` | body | [codersdk.NotificationsSettings](schemas.md#codersdknotificationssettings) | true     | Notifications settings request |

### Example responses

> 200 Response

```json
{
  "notifier_paused": true
}
```

### Responses

| Status | Meaning                                                         | Description  | Schema                                                                     |
|--------|-----------------------------------------------------------------|--------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)         | OK           | [codersdk.NotificationsSettings](schemas.md#codersdknotificationssettings) |
| 304    | [Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) | Not Modified |                                                                            |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get custom notification templates

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/notifications/templates/custom \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/notifications/templates/custom`

### Example responses

> 200 Response

```json
[
  {
    "actions": "string",
    "body_template": "string",
    "enabled_by_default": true,
    "group": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "kind": "string",
    "method": "string",
    "name": "string",
    "title_template": "string"
  }
]
```

### Responses

| Status | Meaning                                                                    | Description                                        | Schema                                                                            |
|--------|----------------------------------------------------------------------------|----------------------------------------------------|-----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)                    | OK                                                 | array of [codersdk.NotificationTemplate](schemas.md#codersdknotificationtemplate) |
| 500    | [Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) | Failed to retrieve 'custom' notifications template | [codersdk.Response](schemas.md#codersdkresponse)                                  |

<h3 id="get-custom-notification-templates-responseschema">Response Schema</h3>

Status Code **200**

| Name                   | Type         | Required | Restrictions | Description |
|------------------------|--------------|----------|--------------|-------------|
| `[array item]`         | array        | false    |              |             |
| `» actions`            | string       | false    |              |             |
| `» body_template`      | string       | false    |              |             |
| `» enabled_by_default` | boolean      | false    |              |             |
| `» group`              | string       | false    |              |             |
| `» id`                 | string(uuid) | false    |              |             |
| `» kind`               | string       | false    |              |             |
| `» method`             | string       | false    |              |             |
| `» name`               | string       | false    |              |             |
| `» title_template`     | string       | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get system notification templates

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/notifications/templates/system \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/notifications/templates/system`

### Example responses

> 200 Response

```json
[
  {
    "actions": "string",
    "body_template": "string",
    "enabled_by_default": true,
    "group": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "kind": "string",
    "method": "string",
    "name": "string",
    "title_template": "string"
  }
]
```

### Responses

| Status | Meaning                                                                    | Description                                        | Schema                                                                            |
|--------|----------------------------------------------------------------------------|----------------------------------------------------|-----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)                    | OK                                                 | array of [codersdk.NotificationTemplate](schemas.md#codersdknotificationtemplate) |
| 500    | [Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) | Failed to retrieve 'system' notifications template | [codersdk.Response](schemas.md#codersdkresponse)                                  |

<h3 id="get-system-notification-templates-responseschema">Response Schema</h3>

Status Code **200**

| Name                   | Type         | Required | Restrictions | Description |
|------------------------|--------------|----------|--------------|-------------|
| `[array item]`         | array        | false    |              |             |
| `» actions`            | string       | false    |              |             |
| `» body_template`      | string       | false    |              |             |
| `» enabled_by_default` | boolean      | false    |              |             |
| `» group`              | string       | false    |              |             |
| `» id`                 | string(uuid) | false    |              |             |
| `» kind`               | string       | false    |              |             |
| `» method`             | string       | false    |              |             |
| `» name`               | string       | false    |              |             |
| `» title_template`     | string       | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Send a test notification

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/notifications/test \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/notifications/test`

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user notification preferences

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/notifications/preferences \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/notifications/preferences`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
[
  {
    "disabled": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "updated_at": "2019-08-24T14:15:22Z"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.NotificationPreference](schemas.md#codersdknotificationpreference) |

<h3 id="get-user-notification-preferences-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type              | Required | Restrictions | Description |
|----------------|-------------------|----------|--------------|-------------|
| `[array item]` | array             | false    |              |             |
| `» disabled`   | boolean           | false    |              |             |
| `» id`         | string(uuid)      | false    |              |             |
| `» updated_at` | string(date-time) | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update user notification preferences

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/notifications/preferences \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/notifications/preferences`

> Body parameter

```json
{
  "template_disabled_map": {
    "property1": true,
    "property2": true
  }
}
```

### Parameters

| Name   | In   | Type                                                                                               | Required | Description          |
|--------|------|----------------------------------------------------------------------------------------------------|----------|----------------------|
| `user` | path | string                                                                                             | true     | User ID, name, or me |
| `body` | body | [codersdk.UpdateUserNotificationPreferences](schemas.md#codersdkupdateusernotificationpreferences) | true     | Preferences          |

### Example responses

> 200 Response

```json
[
  {
    "disabled": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "updated_at": "2019-08-24T14:15:22Z"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.NotificationPreference](schemas.md#codersdknotificationpreference) |

<h3 id="update-user-notification-preferences-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type              | Required | Restrictions | Description |
|----------------|-------------------|----------|--------------|-------------|
| `[array item]` | array             | false    |              |             |
| `» disabled`   | boolean           | false    |              |             |
| `» id`         | string(uuid)      | false    |              |             |
| `» updated_at` | string(date-time) | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Organizations

Source: https://coder.com/docs/reference/api/organizations

# Organizations

## Get organizations

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations`

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "description": "string",
    "display_name": "string",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "is_default": true,
    "name": "string",
    "updated_at": "2019-08-24T14:15:22Z"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                            |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Organization](schemas.md#codersdkorganization) |

<h3 id="get-organizations-responseschema">Response Schema</h3>

Status Code **200**

| Name             | Type              | Required | Restrictions | Description |
|------------------|-------------------|----------|--------------|-------------|
| `[array item]`   | array             | false    |              |             |
| `» created_at`   | string(date-time) | true     |              |             |
| `» description`  | string            | false    |              |             |
| `» display_name` | string            | false    |              |             |
| `» icon`         | string            | false    |              |             |
| `» id`           | string(uuid)      | true     |              |             |
| `» is_default`   | boolean           | true     |              |             |
| `» name`         | string            | false    |              |             |
| `» updated_at`   | string(date-time) | true     |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create organization

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations`

> Body parameter

```json
{
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "name": "string"
}
```

### Parameters

| Name   | In   | Type                                                                               | Required | Description                 |
|--------|------|------------------------------------------------------------------------------------|----------|-----------------------------|
| `body` | body | [codersdk.CreateOrganizationRequest](schemas.md#codersdkcreateorganizationrequest) | true     | Create organization request |

### Example responses

> 201 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_default": true,
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                   |
|--------|--------------------------------------------------------------|-------------|----------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.Organization](schemas.md#codersdkorganization) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get organization by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_default": true,
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Organization](schemas.md#codersdkorganization) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete organization

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/organizations/{organization}`

### Parameters

| Name           | In   | Type   | Required | Description             |
|----------------|------|--------|----------|-------------------------|
| `organization` | path | string | true     | Organization ID or name |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update organization

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/organizations/{organization}`

> Body parameter

```json
{
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "name": "string"
}
```

### Parameters

| Name           | In   | Type                                                                               | Required | Description                |
|----------------|------|------------------------------------------------------------------------------------|----------|----------------------------|
| `organization` | path | string                                                                             | true     | Organization ID or name    |
| `body`         | body | [codersdk.UpdateOrganizationRequest](schemas.md#codersdkupdateorganizationrequest) | true     | Patch organization request |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_default": true,
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Organization](schemas.md#codersdkorganization) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get provisioner jobs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerjobs \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/provisionerjobs`

### Parameters

| Name           | In    | Type         | Required | Description                                                                        |
|----------------|-------|--------------|----------|------------------------------------------------------------------------------------|
| `organization` | path  | string(uuid) | true     | Organization ID                                                                    |
| `limit`        | query | integer      | false    | Page limit                                                                         |
| `ids`          | query | array(uuid)  | false    | Filter results by job IDs                                                          |
| `status`       | query | string       | false    | Filter results by status                                                           |
| `tags`         | query | object       | false    | Provisioner tags to filter by (JSON of the form {'tag1':'value1','tag2':'value2'}) |
| `initiator`    | query | string(uuid) | false    | Filter results by initiator                                                        |

#### Enumerated Values

| Parameter | Value(s)                                                                        |
|-----------|---------------------------------------------------------------------------------|
| `status`  | `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded`, `unknown` |

### Example responses

> 200 Response

```json
[
  {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob) |

<h3 id="get-provisioner-jobs-responseschema">Response Schema</h3>

Status Code **200**

| Name                            | Type                                                                         | Required | Restrictions | Description |
|---------------------------------|------------------------------------------------------------------------------|----------|--------------|-------------|
| `[array item]`                  | array                                                                        | false    |              |             |
| `» available_workers`           | array                                                                        | false    |              |             |
| `» canceled_at`                 | string(date-time)                                                            | false    |              |             |
| `» completed_at`                | string(date-time)                                                            | false    |              |             |
| `» created_at`                  | string(date-time)                                                            | false    |              |             |
| `» error`                       | string                                                                       | false    |              |             |
| `» error_code`                  | [codersdk.JobErrorCode](schemas.md#codersdkjoberrorcode)                     | false    |              |             |
| `» file_id`                     | string(uuid)                                                                 | false    |              |             |
| `» id`                          | string(uuid)                                                                 | false    |              |             |
| `» initiator_id`                | string(uuid)                                                                 | false    |              |             |
| `» input`                       | [codersdk.ProvisionerJobInput](schemas.md#codersdkprovisionerjobinput)       | false    |              |             |
| `»» error`                      | string                                                                       | false    |              |             |
| `»» template_version_id`        | string(uuid)                                                                 | false    |              |             |
| `»» workspace_build_id`         | string(uuid)                                                                 | false    |              |             |
| `» logs_overflowed`             | boolean                                                                      | false    |              |             |
| `» metadata`                    | [codersdk.ProvisionerJobMetadata](schemas.md#codersdkprovisionerjobmetadata) | false    |              |             |
| `»» template_display_name`      | string                                                                       | false    |              |             |
| `»» template_icon`              | string                                                                       | false    |              |             |
| `»» template_id`                | string(uuid)                                                                 | false    |              |             |
| `»» template_name`              | string                                                                       | false    |              |             |
| `»» template_version_name`      | string                                                                       | false    |              |             |
| `»» workspace_build_transition` | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)       | false    |              |             |
| `»» workspace_id`               | string(uuid)                                                                 | false    |              |             |
| `»» workspace_name`             | string                                                                       | false    |              |             |
| `» organization_id`             | string(uuid)                                                                 | false    |              |             |
| `» queue_position`              | integer                                                                      | false    |              |             |
| `» queue_size`                  | integer                                                                      | false    |              |             |
| `» started_at`                  | string(date-time)                                                            | false    |              |             |
| `» status`                      | [codersdk.ProvisionerJobStatus](schemas.md#codersdkprovisionerjobstatus)     | false    |              |             |
| `» tags`                        | object                                                                       | false    |              |             |
| `»» [any property]`             | string                                                                       | false    |              |             |
| `» type`                        | [codersdk.ProvisionerJobType](schemas.md#codersdkprovisionerjobtype)         | false    |              |             |
| `» worker_id`                   | string(uuid)                                                                 | false    |              |             |
| `» worker_name`                 | string                                                                       | false    |              |             |

#### Enumerated Values

| Property                     | Value(s)                                                                 |
|------------------------------|--------------------------------------------------------------------------|
| `error_code`                 | `INSUFFICIENT_QUOTA`, `REQUIRED_TEMPLATE_VARIABLES`                      |
| `workspace_build_transition` | `delete`, `start`, `stop`                                                |
| `status`                     | `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded`     |
| `type`                       | `template_version_dry_run`, `template_version_import`, `workspace_build` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get provisioner job

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerjobs/{job} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/provisionerjobs/{job}`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |
| `job`          | path | string(uuid) | true     | Job ID          |

### Example responses

> 200 Response

```json
{
  "available_workers": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "canceled_at": "2019-08-24T14:15:22Z",
  "completed_at": "2019-08-24T14:15:22Z",
  "created_at": "2019-08-24T14:15:22Z",
  "error": "string",
  "error_code": "REQUIRED_TEMPLATE_VARIABLES",
  "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "input": {
    "error": "string",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
  },
  "logs_overflowed": true,
  "metadata": {
    "template_display_name": "string",
    "template_icon": "string",
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "template_name": "string",
    "template_version_name": "string",
    "workspace_build_transition": "start",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string"
  },
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "queue_position": 0,
  "queue_size": 0,
  "started_at": "2019-08-24T14:15:22Z",
  "status": "pending",
  "tags": {
    "property1": "string",
    "property2": "string"
  },
  "type": "template_version_import",
  "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
  "worker_name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# PortSharing

Source: https://coder.com/docs/reference/api/portsharing

# PortSharing

## Get workspace agent port shares

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/port-share \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/port-share`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Example responses

> 200 Response

```json
{
  "shares": [
    {
      "agent_name": "string",
      "port": 0,
      "protocol": "http",
      "share_level": "owner",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgentPortShares](schemas.md#codersdkworkspaceagentportshares) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Upsert workspace agent port share

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/port-share \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaces/{workspace}/port-share`

> Body parameter

```json
{
  "agent_name": "string",
  "port": 0,
  "protocol": "http",
  "share_level": "owner"
}
```

### Parameters

| Name        | In   | Type                                                                                                     | Required | Description                       |
|-------------|------|----------------------------------------------------------------------------------------------------------|----------|-----------------------------------|
| `workspace` | path | string(uuid)                                                                                             | true     | Workspace ID                      |
| `body`      | body | [codersdk.UpsertWorkspaceAgentPortShareRequest](schemas.md#codersdkupsertworkspaceagentportsharerequest) | true     | Upsert port sharing level request |

### Example responses

> 200 Response

```json
{
  "agent_name": "string",
  "port": 0,
  "protocol": "http",
  "share_level": "owner",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                         |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceAgentPortShare](schemas.md#codersdkworkspaceagentportshare) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete workspace agent port share

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/workspaces/{workspace}/port-share \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/workspaces/{workspace}/port-share`

> Body parameter

```json
{
  "agent_name": "string",
  "port": 0
}
```

### Parameters

| Name        | In   | Type                                                                                                     | Required | Description                       |
|-------------|------|----------------------------------------------------------------------------------------------------------|----------|-----------------------------------|
| `workspace` | path | string(uuid)                                                                                             | true     | Workspace ID                      |
| `body`      | body | [codersdk.DeleteWorkspaceAgentPortShareRequest](schemas.md#codersdkdeleteworkspaceagentportsharerequest) | true     | Delete port sharing level request |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Prebuilds

Source: https://coder.com/docs/reference/api/prebuilds

# Prebuilds

## Get prebuilds settings

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/prebuilds/settings \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/prebuilds/settings`

### Example responses

> 200 Response

```json
{
  "reconciliation_paused": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.PrebuildsSettings](schemas.md#codersdkprebuildssettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update prebuilds settings

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/prebuilds/settings \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/prebuilds/settings`

> Body parameter

```json
{
  "reconciliation_paused": true
}
```

### Parameters

| Name   | In   | Type                                                               | Required | Description                |
|--------|------|--------------------------------------------------------------------|----------|----------------------------|
| `body` | body | [codersdk.PrebuildsSettings](schemas.md#codersdkprebuildssettings) | true     | Prebuilds settings request |

### Example responses

> 200 Response

```json
{
  "reconciliation_paused": true
}
```

### Responses

| Status | Meaning                                                         | Description  | Schema                                                             |
|--------|-----------------------------------------------------------------|--------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)         | OK           | [codersdk.PrebuildsSettings](schemas.md#codersdkprebuildssettings) |
| 304    | [Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) | Not Modified |                                                                    |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Provisioning

Source: https://coder.com/docs/reference/api/provisioning

# Provisioning

## Get provisioner daemons

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerdaemons \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/provisionerdaemons`

### Parameters

| Name           | In    | Type         | Required | Description                                                                        |
|----------------|-------|--------------|----------|------------------------------------------------------------------------------------|
| `organization` | path  | string(uuid) | true     | Organization ID                                                                    |
| `limit`        | query | integer      | false    | Page limit                                                                         |
| `ids`          | query | array(uuid)  | false    | Filter results by job IDs                                                          |
| `status`       | query | string       | false    | Filter results by status                                                           |
| `tags`         | query | object       | false    | Provisioner tags to filter by (JSON of the form {'tag1':'value1','tag2':'value2'}) |

#### Enumerated Values

| Parameter | Value(s)                                                                        |
|-----------|---------------------------------------------------------------------------------|
| `status`  | `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded`, `unknown` |

### Example responses

> 200 Response

```json
[
  {
    "api_version": "string",
    "created_at": "2019-08-24T14:15:22Z",
    "current_job": {
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "status": "pending",
      "template_display_name": "string",
      "template_icon": "string",
      "template_name": "string"
    },
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
    "key_name": "string",
    "last_seen_at": "2019-08-24T14:15:22Z",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "previous_job": {
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "status": "pending",
      "template_display_name": "string",
      "template_icon": "string",
      "template_name": "string"
    },
    "provisioners": [
      "string"
    ],
    "status": "offline",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "version": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ProvisionerDaemon](schemas.md#codersdkprovisionerdaemon) |

<h3 id="get-provisioner-daemons-responseschema">Response Schema</h3>

Status Code **200**

| Name                       | Type                                                                           | Required | Restrictions | Description      |
|----------------------------|--------------------------------------------------------------------------------|----------|--------------|------------------|
| `[array item]`             | array                                                                          | false    |              |                  |
| `» api_version`            | string                                                                         | false    |              |                  |
| `» created_at`             | string(date-time)                                                              | false    |              |                  |
| `» current_job`            | [codersdk.ProvisionerDaemonJob](schemas.md#codersdkprovisionerdaemonjob)       | false    |              |                  |
| `»» id`                    | string(uuid)                                                                   | false    |              |                  |
| `»» status`                | [codersdk.ProvisionerJobStatus](schemas.md#codersdkprovisionerjobstatus)       | false    |              |                  |
| `»» template_display_name` | string                                                                         | false    |              |                  |
| `»» template_icon`         | string                                                                         | false    |              |                  |
| `»» template_name`         | string                                                                         | false    |              |                  |
| `» id`                     | string(uuid)                                                                   | false    |              |                  |
| `» key_id`                 | string(uuid)                                                                   | false    |              |                  |
| `» key_name`               | string                                                                         | false    |              | Optional fields. |
| `» last_seen_at`           | string(date-time)                                                              | false    |              |                  |
| `» name`                   | string                                                                         | false    |              |                  |
| `» organization_id`        | string(uuid)                                                                   | false    |              |                  |
| `» previous_job`           | [codersdk.ProvisionerDaemonJob](schemas.md#codersdkprovisionerdaemonjob)       | false    |              |                  |
| `» provisioners`           | array                                                                          | false    |              |                  |
| `» status`                 | [codersdk.ProvisionerDaemonStatus](schemas.md#codersdkprovisionerdaemonstatus) | false    |              |                  |
| `» tags`                   | object                                                                         | false    |              |                  |
| `»» [any property]`        | string                                                                         | false    |              |                  |
| `» version`                | string                                                                         | false    |              |                  |

#### Enumerated Values

| Property | Value(s)                                                                                        |
|----------|-------------------------------------------------------------------------------------------------|
| `status` | `busy`, `canceled`, `canceling`, `failed`, `idle`, `offline`, `pending`, `running`, `succeeded` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Schemas

Source: https://coder.com/docs/reference/api/schemas

# Schemas

## agentsdk.AWSInstanceIdentityToken

```json
{
  "agent_name": "string",
  "document": "string",
  "signature": "string"
}
```

### Properties

| Name         | Type   | Required | Restrictions | Description                                                                                                                                      |
|--------------|--------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| `agent_name` | string | false    |              | Agent name optionally selects a specific agent when multiple agents share the same instance identity. An empty string is treated as unspecified. |
| `document`   | string | true     |              |                                                                                                                                                  |
| `signature`  | string | true     |              |                                                                                                                                                  |

## agentsdk.AuthenticateResponse

```json
{
  "session_token": "string"
}
```

### Properties

| Name            | Type   | Required | Restrictions | Description |
|-----------------|--------|----------|--------------|-------------|
| `session_token` | string | false    |              |             |

## agentsdk.AzureInstanceIdentityToken

```json
{
  "agent_name": "string",
  "encoding": "string",
  "signature": "string"
}
```

### Properties

| Name         | Type   | Required | Restrictions | Description                                                                                                                                      |
|--------------|--------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| `agent_name` | string | false    |              | Agent name optionally selects a specific agent when multiple agents share the same instance identity. An empty string is treated as unspecified. |
| `encoding`   | string | true     |              |                                                                                                                                                  |
| `signature`  | string | true     |              |                                                                                                                                                  |

## agentsdk.ExternalAuthResponse

```json
{
  "access_token": "string",
  "password": "string",
  "token_extra": {},
  "type": "string",
  "url": "string",
  "username": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description                                                                              |
|----------------|--------|----------|--------------|------------------------------------------------------------------------------------------|
| `access_token` | string | false    |              |                                                                                          |
| `password`     | string | false    |              |                                                                                          |
| `token_extra`  | object | false    |              |                                                                                          |
| `type`         | string | false    |              |                                                                                          |
| `url`          | string | false    |              |                                                                                          |
| `username`     | string | false    |              | Deprecated: Only supported on `/workspaceagents/me/gitauth` for backwards compatibility. |

## agentsdk.GitSSHKey

```json
{
  "private_key": "string",
  "public_key": "string"
}
```

### Properties

| Name          | Type   | Required | Restrictions | Description |
|---------------|--------|----------|--------------|-------------|
| `private_key` | string | false    |              |             |
| `public_key`  | string | false    |              |             |

## agentsdk.GoogleInstanceIdentityToken

```json
{
  "agent_name": "string",
  "json_web_token": "string"
}
```

### Properties

| Name             | Type   | Required | Restrictions | Description                                                                                                                                      |
|------------------|--------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| `agent_name`     | string | false    |              | Agent name optionally selects a specific agent when multiple agents share the same instance identity. An empty string is treated as unspecified. |
| `json_web_token` | string | true     |              |                                                                                                                                                  |

## agentsdk.Log

```json
{
  "created_at": "string",
  "level": "trace",
  "output": "string"
}
```

### Properties

| Name         | Type                                   | Required | Restrictions | Description |
|--------------|----------------------------------------|----------|--------------|-------------|
| `created_at` | string                                 | false    |              |             |
| `level`      | [codersdk.LogLevel](#codersdkloglevel) | false    |              |             |
| `output`     | string                                 | false    |              |             |

## agentsdk.PatchAppStatus

```json
{
  "app_slug": "string",
  "icon": "string",
  "message": "string",
  "needs_user_attention": true,
  "state": "working",
  "uri": "string"
}
```

### Properties

| Name                   | Type                                                                 | Required | Restrictions | Description                                                               |
|------------------------|----------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------|
| `app_slug`             | string                                                               | false    |              |                                                                           |
| `icon`                 | string                                                               | false    |              | Deprecated: this field is unused and will be removed in a future version. |
| `message`              | string                                                               | false    |              |                                                                           |
| `needs_user_attention` | boolean                                                              | false    |              | Deprecated: this field is unused and will be removed in a future version. |
| `state`                | [codersdk.WorkspaceAppStatusState](#codersdkworkspaceappstatusstate) | false    |              |                                                                           |
| `uri`                  | string                                                               | false    |              |                                                                           |

## agentsdk.PatchLogs

```json
{
  "log_source_id": "string",
  "logs": [
    {
      "created_at": "string",
      "level": "trace",
      "output": "string"
    }
  ]
}
```

### Properties

| Name            | Type                                  | Required | Restrictions | Description |
|-----------------|---------------------------------------|----------|--------------|-------------|
| `log_source_id` | string                                | false    |              |             |
| `logs`          | array of [agentsdk.Log](#agentsdklog) | false    |              |             |

## agentsdk.PostLogSourceRequest

```json
{
  "display_name": "string",
  "icon": "string",
  "id": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description                                                                                                                                                                                    |
|----------------|--------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `display_name` | string | false    |              |                                                                                                                                                                                                |
| `icon`         | string | false    |              |                                                                                                                                                                                                |
| `id`           | string | false    |              | ID is a unique identifier for the log source. It is scoped to a workspace agent, and can be statically defined inside code to prevent duplicate sources from being created for the same agent. |

## agentsdk.ReinitializationEvent

```json
{
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "reason": "prebuild_claimed",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Properties

| Name           | Type                                                               | Required | Restrictions | Description |
|----------------|--------------------------------------------------------------------|----------|--------------|-------------|
| `owner_id`     | string                                                             | false    |              |             |
| `reason`       | [agentsdk.ReinitializationReason](#agentsdkreinitializationreason) | false    |              |             |
| `workspace_id` | string                                                             | false    |              |             |

## agentsdk.ReinitializationReason

```json
"prebuild_claimed"
```

### Properties

#### Enumerated Values

| Value(s)           |
|--------------------|
| `prebuild_claimed` |

## coderd.SCIMUser

```json
{
  "active": true,
  "emails": [
    {
      "display": "string",
      "primary": true,
      "type": "string",
      "value": "user@example.com"
    }
  ],
  "groups": [
    null
  ],
  "id": "string",
  "meta": {
    "resourceType": "string"
  },
  "name": {
    "familyName": "string",
    "givenName": "string"
  },
  "schemas": [
    "string"
  ],
  "userName": "string"
}
```

### Properties

| Name             | Type               | Required | Restrictions | Description                                                                 |
|------------------|--------------------|----------|--------------|-----------------------------------------------------------------------------|
| `active`         | boolean            | false    |              | Active is a ptr to prevent the empty value from being interpreted as false. |
| `emails`         | array of object    | false    |              |                                                                             |
| `» display`      | string             | false    |              |                                                                             |
| `» primary`      | boolean            | false    |              |                                                                             |
| `» type`         | string             | false    |              |                                                                             |
| `» value`        | string             | false    |              |                                                                             |
| `groups`         | array of undefined | false    |              |                                                                             |
| `id`             | string             | false    |              |                                                                             |
| `meta`           | object             | false    |              |                                                                             |
| `» resourceType` | string             | false    |              |                                                                             |
| `name`           | object             | false    |              |                                                                             |
| `» familyName`   | string             | false    |              |                                                                             |
| `» givenName`    | string             | false    |              |                                                                             |
| `schemas`        | array of string    | false    |              |                                                                             |
| `userName`       | string             | false    |              |                                                                             |

## coderd.cspViolation

```json
{
  "csp-report": {}
}
```

### Properties

| Name         | Type   | Required | Restrictions | Description |
|--------------|--------|----------|--------------|-------------|
| `csp-report` | object | false    |              |             |

## codersdk.ACLAvailable

```json
{
  "groups": [
    {
      "avatar_url": "http://example.com",
      "display_name": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "members": [
        {
          "avatar_url": "http://example.com",
          "created_at": "2019-08-24T14:15:22Z",
          "email": "user@example.com",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "is_service_account": true,
          "last_seen_at": "2019-08-24T14:15:22Z",
          "login_type": "",
          "name": "string",
          "status": "active",
          "theme_preference": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "username": "string"
        }
      ],
      "name": "string",
      "organization_display_name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "organization_name": "string",
      "quota_allowance": 0,
      "source": "user",
      "total_member_count": 0
    }
  ],
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Properties

| Name     | Type                                                  | Required | Restrictions | Description |
|----------|-------------------------------------------------------|----------|--------------|-------------|
| `groups` | array of [codersdk.Group](#codersdkgroup)             | false    |              |             |
| `users`  | array of [codersdk.ReducedUser](#codersdkreduceduser) | false    |              |             |

## codersdk.AIBridgeAgenticAction

```json
{
  "model": "string",
  "thinking": [
    {
      "text": "string"
    }
  ],
  "token_usage": {
    "cache_read_input_tokens": 0,
    "cache_write_input_tokens": 0,
    "input_tokens": 0,
    "metadata": {
      "property1": null,
      "property2": null
    },
    "output_tokens": 0
  },
  "tool_calls": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "injected": true,
      "input": "string",
      "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
      "metadata": {
        "property1": null,
        "property2": null
      },
      "provider_response_id": "string",
      "server_url": "string",
      "tool": "string"
    }
  ]
}
```

### Properties

| Name          | Type                                                                                   | Required | Restrictions | Description |
|---------------|----------------------------------------------------------------------------------------|----------|--------------|-------------|
| `model`       | string                                                                                 | false    |              |             |
| `thinking`    | array of [codersdk.AIBridgeModelThought](#codersdkaibridgemodelthought)                | false    |              |             |
| `token_usage` | [codersdk.AIBridgeSessionThreadsTokenUsage](#codersdkaibridgesessionthreadstokenusage) | false    |              |             |
| `tool_calls`  | array of [codersdk.AIBridgeToolCall](#codersdkaibridgetoolcall)                        | false    |              |             |

## codersdk.AIBridgeAnthropicConfig

```json
{
  "base_url": "string",
  "key": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `base_url` | string | false    |              |             |
| `key`      | string | false    |              |             |

## codersdk.AIBridgeBedrockConfig

```json
{
  "access_key": "string",
  "access_key_secret": "string",
  "base_url": "string",
  "model": "string",
  "region": "string",
  "small_fast_model": "string"
}
```

### Properties

| Name                | Type   | Required | Restrictions | Description |
|---------------------|--------|----------|--------------|-------------|
| `access_key`        | string | false    |              |             |
| `access_key_secret` | string | false    |              |             |
| `base_url`          | string | false    |              |             |
| `model`             | string | false    |              |             |
| `region`            | string | false    |              |             |
| `small_fast_model`  | string | false    |              |             |

## codersdk.AIBridgeConfig

```json
{
  "allow_byok": true,
  "anthropic": {
    "base_url": "string",
    "key": "string"
  },
  "bedrock": {
    "access_key": "string",
    "access_key_secret": "string",
    "base_url": "string",
    "model": "string",
    "region": "string",
    "small_fast_model": "string"
  },
  "circuit_breaker_enabled": true,
  "circuit_breaker_failure_threshold": 0,
  "circuit_breaker_interval": 0,
  "circuit_breaker_max_requests": 0,
  "circuit_breaker_timeout": 0,
  "enabled": true,
  "inject_coder_mcp_tools": true,
  "max_concurrency": 0,
  "openai": {
    "base_url": "string",
    "key": "string"
  },
  "providers": [
    {
      "base_url": "string",
      "bedrock_model": "string",
      "bedrock_region": "string",
      "bedrock_small_fast_model": "string",
      "dump_dir": "string",
      "name": "string",
      "type": "string"
    }
  ],
  "rate_limit": 0,
  "retention": 0,
  "send_actor_headers": true,
  "structured_logging": true
}
```

### Properties

| Name                                | Type                                                                        | Required | Restrictions | Description                                                                                                                                                                 |
|-------------------------------------|-----------------------------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `allow_byok`                        | boolean                                                                     | false    |              |                                                                                                                                                                             |
| `anthropic`                         | [codersdk.AIBridgeAnthropicConfig](#codersdkaibridgeanthropicconfig)        | false    |              | Deprecated: Use Providers with indexed CODER_AIBRIDGE_PROVIDER_<N>_* env vars instead.                                                                                      |
| `bedrock`                           | [codersdk.AIBridgeBedrockConfig](#codersdkaibridgebedrockconfig)            | false    |              | Deprecated: Use Providers with indexed CODER_AIBRIDGE_PROVIDER_<N>_* env vars instead.                                                                                      |
| `circuit_breaker_enabled`           | boolean                                                                     | false    |              | Circuit breaker protects against cascading failures from upstream AI provider overload (503, 529).                                                                          |
| `circuit_breaker_failure_threshold` | integer                                                                     | false    |              |                                                                                                                                                                             |
| `circuit_breaker_interval`          | integer                                                                     | false    |              |                                                                                                                                                                             |
| `circuit_breaker_max_requests`      | integer                                                                     | false    |              |                                                                                                                                                                             |
| `circuit_breaker_timeout`           | integer                                                                     | false    |              |                                                                                                                                                                             |
| `enabled`                           | boolean                                                                     | false    |              |                                                                                                                                                                             |
| `inject_coder_mcp_tools`            | boolean                                                                     | false    |              | Deprecated: Injected MCP in AI Bridge is deprecated and will be removed in a future release.                                                                                |
| `max_concurrency`                   | integer                                                                     | false    |              |                                                                                                                                                                             |
| `openai`                            | [codersdk.AIBridgeOpenAIConfig](#codersdkaibridgeopenaiconfig)              | false    |              | Deprecated: Use Providers with indexed CODER_AIBRIDGE_PROVIDER_<N>_* env vars instead.                                                                                      |
| `providers`                         | array of [codersdk.AIBridgeProviderConfig](#codersdkaibridgeproviderconfig) | false    |              | Providers holds provider instances populated from CODER_AIBRIDGE_PROVIDER_<N>_<KEY> env vars and/or the deprecated LegacyOpenAI/LegacyAnthropic/LegacyBedrock fields above. |
| `rate_limit`                        | integer                                                                     | false    |              |                                                                                                                                                                             |
| `retention`                         | integer                                                                     | false    |              |                                                                                                                                                                             |
| `send_actor_headers`                | boolean                                                                     | false    |              |                                                                                                                                                                             |
| `structured_logging`                | boolean                                                                     | false    |              |                                                                                                                                                                             |

## codersdk.AIBridgeInterception

```json
{
  "api_key_id": "string",
  "client": "string",
  "ended_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "metadata": {
    "property1": null,
    "property2": null
  },
  "model": "string",
  "provider": "string",
  "provider_name": "string",
  "started_at": "2019-08-24T14:15:22Z",
  "token_usages": [
    {
      "cache_read_input_tokens": 0,
      "cache_write_input_tokens": 0,
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "input_tokens": 0,
      "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
      "metadata": {
        "property1": null,
        "property2": null
      },
      "output_tokens": 0,
      "provider_response_id": "string"
    }
  ],
  "tool_usages": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "injected": true,
      "input": "string",
      "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
      "invocation_error": "string",
      "metadata": {
        "property1": null,
        "property2": null
      },
      "provider_response_id": "string",
      "server_url": "string",
      "tool": "string"
    }
  ],
  "user_prompts": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
      "metadata": {
        "property1": null,
        "property2": null
      },
      "prompt": "string",
      "provider_response_id": "string"
    }
  ]
}
```

### Properties

| Name               | Type                                                                | Required | Restrictions | Description |
|--------------------|---------------------------------------------------------------------|----------|--------------|-------------|
| `api_key_id`       | string                                                              | false    |              |             |
| `client`           | string                                                              | false    |              |             |
| `ended_at`         | string                                                              | false    |              |             |
| `id`               | string                                                              | false    |              |             |
| `initiator`        | [codersdk.MinimalUser](#codersdkminimaluser)                        | false    |              |             |
| `metadata`         | object                                                              | false    |              |             |
| » `[any property]` | any                                                                 | false    |              |             |
| `model`            | string                                                              | false    |              |             |
| `provider`         | string                                                              | false    |              |             |
| `provider_name`    | string                                                              | false    |              |             |
| `started_at`       | string                                                              | false    |              |             |
| `token_usages`     | array of [codersdk.AIBridgeTokenUsage](#codersdkaibridgetokenusage) | false    |              |             |
| `tool_usages`      | array of [codersdk.AIBridgeToolUsage](#codersdkaibridgetoolusage)   | false    |              |             |
| `user_prompts`     | array of [codersdk.AIBridgeUserPrompt](#codersdkaibridgeuserprompt) | false    |              |             |

## codersdk.AIBridgeListInterceptionsResponse

```json
{
  "count": 0,
  "results": [
    {
      "api_key_id": "string",
      "client": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator": {
        "avatar_url": "http://example.com",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string",
        "username": "string"
      },
      "metadata": {
        "property1": null,
        "property2": null
      },
      "model": "string",
      "provider": "string",
      "provider_name": "string",
      "started_at": "2019-08-24T14:15:22Z",
      "token_usages": [
        {
          "cache_read_input_tokens": 0,
          "cache_write_input_tokens": 0,
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "input_tokens": 0,
          "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
          "metadata": {
            "property1": null,
            "property2": null
          },
          "output_tokens": 0,
          "provider_response_id": "string"
        }
      ],
      "tool_usages": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "injected": true,
          "input": "string",
          "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
          "invocation_error": "string",
          "metadata": {
            "property1": null,
            "property2": null
          },
          "provider_response_id": "string",
          "server_url": "string",
          "tool": "string"
        }
      ],
      "user_prompts": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
          "metadata": {
            "property1": null,
            "property2": null
          },
          "prompt": "string",
          "provider_response_id": "string"
        }
      ]
    }
  ]
}
```

### Properties

| Name      | Type                                                                    | Required | Restrictions | Description |
|-----------|-------------------------------------------------------------------------|----------|--------------|-------------|
| `count`   | integer                                                                 | false    |              |             |
| `results` | array of [codersdk.AIBridgeInterception](#codersdkaibridgeinterception) | false    |              |             |

## codersdk.AIBridgeListSessionsResponse

```json
{
  "count": 0,
  "sessions": [
    {
      "client": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "id": "string",
      "initiator": {
        "avatar_url": "http://example.com",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string",
        "username": "string"
      },
      "last_active_at": "2019-08-24T14:15:22Z",
      "last_prompt": "string",
      "metadata": {
        "property1": null,
        "property2": null
      },
      "models": [
        "string"
      ],
      "providers": [
        "string"
      ],
      "started_at": "2019-08-24T14:15:22Z",
      "threads": 0,
      "token_usage_summary": {
        "cache_read_input_tokens": 0,
        "cache_write_input_tokens": 0,
        "input_tokens": 0,
        "output_tokens": 0
      }
    }
  ]
}
```

### Properties

| Name       | Type                                                          | Required | Restrictions | Description |
|------------|---------------------------------------------------------------|----------|--------------|-------------|
| `count`    | integer                                                       | false    |              |             |
| `sessions` | array of [codersdk.AIBridgeSession](#codersdkaibridgesession) | false    |              |             |

## codersdk.AIBridgeModelThought

```json
{
  "text": "string"
}
```

### Properties

| Name   | Type   | Required | Restrictions | Description |
|--------|--------|----------|--------------|-------------|
| `text` | string | false    |              |             |

## codersdk.AIBridgeOpenAIConfig

```json
{
  "base_url": "string",
  "key": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `base_url` | string | false    |              |             |
| `key`      | string | false    |              |             |

## codersdk.AIBridgeProviderConfig

```json
{
  "base_url": "string",
  "bedrock_model": "string",
  "bedrock_region": "string",
  "bedrock_small_fast_model": "string",
  "dump_dir": "string",
  "name": "string",
  "type": "string"
}
```

### Properties

| Name                       | Type   | Required | Restrictions | Description                                                                                |
|----------------------------|--------|----------|--------------|--------------------------------------------------------------------------------------------|
| `base_url`                 | string | false    |              | Base URL is the base URL of the upstream provider API.                                     |
| `bedrock_model`            | string | false    |              |                                                                                            |
| `bedrock_region`           | string | false    |              |                                                                                            |
| `bedrock_small_fast_model` | string | false    |              |                                                                                            |
| `dump_dir`                 | string | false    |              | Dump dir is the directory path for dumping API requests and responses.                     |
| `name`                     | string | false    |              | Name is the unique instance identifier used for routing. Defaults to Type if not provided. |
| `type`                     | string | false    |              | Type is the provider type: "openai", "anthropic", or "copilot".                            |

## codersdk.AIBridgeProxyConfig

```json
{
  "allowed_private_cidrs": [
    "string"
  ],
  "cert_file": "string",
  "domain_allowlist": [
    "string"
  ],
  "enabled": true,
  "key_file": "string",
  "listen_addr": "string",
  "tls_cert_file": "string",
  "tls_key_file": "string",
  "upstream_proxy": "string",
  "upstream_proxy_ca": "string"
}
```

### Properties

| Name                    | Type            | Required | Restrictions | Description |
|-------------------------|-----------------|----------|--------------|-------------|
| `allowed_private_cidrs` | array of string | false    |              |             |
| `cert_file`             | string          | false    |              |             |
| `domain_allowlist`      | array of string | false    |              |             |
| `enabled`               | boolean         | false    |              |             |
| `key_file`              | string          | false    |              |             |
| `listen_addr`           | string          | false    |              |             |
| `tls_cert_file`         | string          | false    |              |             |
| `tls_key_file`          | string          | false    |              |             |
| `upstream_proxy`        | string          | false    |              |             |
| `upstream_proxy_ca`     | string          | false    |              |             |

## codersdk.AIBridgeSession

```json
{
  "client": "string",
  "ended_at": "2019-08-24T14:15:22Z",
  "id": "string",
  "initiator": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "last_active_at": "2019-08-24T14:15:22Z",
  "last_prompt": "string",
  "metadata": {
    "property1": null,
    "property2": null
  },
  "models": [
    "string"
  ],
  "providers": [
    "string"
  ],
  "started_at": "2019-08-24T14:15:22Z",
  "threads": 0,
  "token_usage_summary": {
    "cache_read_input_tokens": 0,
    "cache_write_input_tokens": 0,
    "input_tokens": 0,
    "output_tokens": 0
  }
}
```

### Properties

| Name                  | Type                                                                                   | Required | Restrictions | Description |
|-----------------------|----------------------------------------------------------------------------------------|----------|--------------|-------------|
| `client`              | string                                                                                 | false    |              |             |
| `ended_at`            | string                                                                                 | false    |              |             |
| `id`                  | string                                                                                 | false    |              |             |
| `initiator`           | [codersdk.MinimalUser](#codersdkminimaluser)                                           | false    |              |             |
| `last_active_at`      | string                                                                                 | false    |              |             |
| `last_prompt`         | string                                                                                 | false    |              |             |
| `metadata`            | object                                                                                 | false    |              |             |
| » `[any property]`    | any                                                                                    | false    |              |             |
| `models`              | array of string                                                                        | false    |              |             |
| `providers`           | array of string                                                                        | false    |              |             |
| `started_at`          | string                                                                                 | false    |              |             |
| `threads`             | integer                                                                                | false    |              |             |
| `token_usage_summary` | [codersdk.AIBridgeSessionTokenUsageSummary](#codersdkaibridgesessiontokenusagesummary) | false    |              |             |

## codersdk.AIBridgeSessionThreadsResponse

```json
{
  "client": "string",
  "ended_at": "2019-08-24T14:15:22Z",
  "id": "string",
  "initiator": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "metadata": {
    "property1": null,
    "property2": null
  },
  "models": [
    "string"
  ],
  "page_ended_at": "2019-08-24T14:15:22Z",
  "page_started_at": "2019-08-24T14:15:22Z",
  "providers": [
    "string"
  ],
  "started_at": "2019-08-24T14:15:22Z",
  "threads": [
    {
      "agentic_actions": [
        {
          "model": "string",
          "thinking": [
            {
              "text": "string"
            }
          ],
          "token_usage": {
            "cache_read_input_tokens": 0,
            "cache_write_input_tokens": 0,
            "input_tokens": 0,
            "metadata": {
              "property1": null,
              "property2": null
            },
            "output_tokens": 0
          },
          "tool_calls": [
            {
              "created_at": "2019-08-24T14:15:22Z",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "injected": true,
              "input": "string",
              "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
              "metadata": {
                "property1": null,
                "property2": null
              },
              "provider_response_id": "string",
              "server_url": "string",
              "tool": "string"
            }
          ]
        }
      ],
      "credential_hint": "string",
      "credential_kind": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "model": "string",
      "prompt": "string",
      "provider": "string",
      "started_at": "2019-08-24T14:15:22Z",
      "token_usage": {
        "cache_read_input_tokens": 0,
        "cache_write_input_tokens": 0,
        "input_tokens": 0,
        "metadata": {
          "property1": null,
          "property2": null
        },
        "output_tokens": 0
      }
    }
  ],
  "token_usage_summary": {
    "cache_read_input_tokens": 0,
    "cache_write_input_tokens": 0,
    "input_tokens": 0,
    "metadata": {
      "property1": null,
      "property2": null
    },
    "output_tokens": 0
  }
}
```

### Properties

| Name                  | Type                                                                                   | Required | Restrictions | Description |
|-----------------------|----------------------------------------------------------------------------------------|----------|--------------|-------------|
| `client`              | string                                                                                 | false    |              |             |
| `ended_at`            | string                                                                                 | false    |              |             |
| `id`                  | string                                                                                 | false    |              |             |
| `initiator`           | [codersdk.MinimalUser](#codersdkminimaluser)                                           | false    |              |             |
| `metadata`            | object                                                                                 | false    |              |             |
| » `[any property]`    | any                                                                                    | false    |              |             |
| `models`              | array of string                                                                        | false    |              |             |
| `page_ended_at`       | string                                                                                 | false    |              |             |
| `page_started_at`     | string                                                                                 | false    |              |             |
| `providers`           | array of string                                                                        | false    |              |             |
| `started_at`          | string                                                                                 | false    |              |             |
| `threads`             | array of [codersdk.AIBridgeThread](#codersdkaibridgethread)                            | false    |              |             |
| `token_usage_summary` | [codersdk.AIBridgeSessionThreadsTokenUsage](#codersdkaibridgesessionthreadstokenusage) | false    |              |             |

## codersdk.AIBridgeSessionThreadsTokenUsage

```json
{
  "cache_read_input_tokens": 0,
  "cache_write_input_tokens": 0,
  "input_tokens": 0,
  "metadata": {
    "property1": null,
    "property2": null
  },
  "output_tokens": 0
}
```

### Properties

| Name                       | Type    | Required | Restrictions | Description |
|----------------------------|---------|----------|--------------|-------------|
| `cache_read_input_tokens`  | integer | false    |              |             |
| `cache_write_input_tokens` | integer | false    |              |             |
| `input_tokens`             | integer | false    |              |             |
| `metadata`                 | object  | false    |              |             |
| » `[any property]`         | any     | false    |              |             |
| `output_tokens`            | integer | false    |              |             |

## codersdk.AIBridgeSessionTokenUsageSummary

```json
{
  "cache_read_input_tokens": 0,
  "cache_write_input_tokens": 0,
  "input_tokens": 0,
  "output_tokens": 0
}
```

### Properties

| Name                       | Type    | Required | Restrictions | Description |
|----------------------------|---------|----------|--------------|-------------|
| `cache_read_input_tokens`  | integer | false    |              |             |
| `cache_write_input_tokens` | integer | false    |              |             |
| `input_tokens`             | integer | false    |              |             |
| `output_tokens`            | integer | false    |              |             |

## codersdk.AIBridgeThread

```json
{
  "agentic_actions": [
    {
      "model": "string",
      "thinking": [
        {
          "text": "string"
        }
      ],
      "token_usage": {
        "cache_read_input_tokens": 0,
        "cache_write_input_tokens": 0,
        "input_tokens": 0,
        "metadata": {
          "property1": null,
          "property2": null
        },
        "output_tokens": 0
      },
      "tool_calls": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "injected": true,
          "input": "string",
          "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
          "metadata": {
            "property1": null,
            "property2": null
          },
          "provider_response_id": "string",
          "server_url": "string",
          "tool": "string"
        }
      ]
    }
  ],
  "credential_hint": "string",
  "credential_kind": "string",
  "ended_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "model": "string",
  "prompt": "string",
  "provider": "string",
  "started_at": "2019-08-24T14:15:22Z",
  "token_usage": {
    "cache_read_input_tokens": 0,
    "cache_write_input_tokens": 0,
    "input_tokens": 0,
    "metadata": {
      "property1": null,
      "property2": null
    },
    "output_tokens": 0
  }
}
```

### Properties

| Name              | Type                                                                                   | Required | Restrictions | Description |
|-------------------|----------------------------------------------------------------------------------------|----------|--------------|-------------|
| `agentic_actions` | array of [codersdk.AIBridgeAgenticAction](#codersdkaibridgeagenticaction)              | false    |              |             |
| `credential_hint` | string                                                                                 | false    |              |             |
| `credential_kind` | string                                                                                 | false    |              |             |
| `ended_at`        | string                                                                                 | false    |              |             |
| `id`              | string                                                                                 | false    |              |             |
| `model`           | string                                                                                 | false    |              |             |
| `prompt`          | string                                                                                 | false    |              |             |
| `provider`        | string                                                                                 | false    |              |             |
| `started_at`      | string                                                                                 | false    |              |             |
| `token_usage`     | [codersdk.AIBridgeSessionThreadsTokenUsage](#codersdkaibridgesessionthreadstokenusage) | false    |              |             |

## codersdk.AIBridgeTokenUsage

```json
{
  "cache_read_input_tokens": 0,
  "cache_write_input_tokens": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "input_tokens": 0,
  "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
  "metadata": {
    "property1": null,
    "property2": null
  },
  "output_tokens": 0,
  "provider_response_id": "string"
}
```

### Properties

| Name                       | Type    | Required | Restrictions | Description |
|----------------------------|---------|----------|--------------|-------------|
| `cache_read_input_tokens`  | integer | false    |              |             |
| `cache_write_input_tokens` | integer | false    |              |             |
| `created_at`               | string  | false    |              |             |
| `id`                       | string  | false    |              |             |
| `input_tokens`             | integer | false    |              |             |
| `interception_id`          | string  | false    |              |             |
| `metadata`                 | object  | false    |              |             |
| » `[any property]`         | any     | false    |              |             |
| `output_tokens`            | integer | false    |              |             |
| `provider_response_id`     | string  | false    |              |             |

## codersdk.AIBridgeToolCall

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "injected": true,
  "input": "string",
  "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
  "metadata": {
    "property1": null,
    "property2": null
  },
  "provider_response_id": "string",
  "server_url": "string",
  "tool": "string"
}
```

### Properties

| Name                   | Type    | Required | Restrictions | Description |
|------------------------|---------|----------|--------------|-------------|
| `created_at`           | string  | false    |              |             |
| `id`                   | string  | false    |              |             |
| `injected`             | boolean | false    |              |             |
| `input`                | string  | false    |              |             |
| `interception_id`      | string  | false    |              |             |
| `metadata`             | object  | false    |              |             |
| » `[any property]`     | any     | false    |              |             |
| `provider_response_id` | string  | false    |              |             |
| `server_url`           | string  | false    |              |             |
| `tool`                 | string  | false    |              |             |

## codersdk.AIBridgeToolUsage

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "injected": true,
  "input": "string",
  "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
  "invocation_error": "string",
  "metadata": {
    "property1": null,
    "property2": null
  },
  "provider_response_id": "string",
  "server_url": "string",
  "tool": "string"
}
```

### Properties

| Name                   | Type    | Required | Restrictions | Description |
|------------------------|---------|----------|--------------|-------------|
| `created_at`           | string  | false    |              |             |
| `id`                   | string  | false    |              |             |
| `injected`             | boolean | false    |              |             |
| `input`                | string  | false    |              |             |
| `interception_id`      | string  | false    |              |             |
| `invocation_error`     | string  | false    |              |             |
| `metadata`             | object  | false    |              |             |
| » `[any property]`     | any     | false    |              |             |
| `provider_response_id` | string  | false    |              |             |
| `server_url`           | string  | false    |              |             |
| `tool`                 | string  | false    |              |             |

## codersdk.AIBridgeUserPrompt

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "interception_id": "34d9b688-63ad-46f4-88b5-665c1e7f7824",
  "metadata": {
    "property1": null,
    "property2": null
  },
  "prompt": "string",
  "provider_response_id": "string"
}
```

### Properties

| Name                   | Type   | Required | Restrictions | Description |
|------------------------|--------|----------|--------------|-------------|
| `created_at`           | string | false    |              |             |
| `id`                   | string | false    |              |             |
| `interception_id`      | string | false    |              |             |
| `metadata`             | object | false    |              |             |
| » `[any property]`     | any    | false    |              |             |
| `prompt`               | string | false    |              |             |
| `provider_response_id` | string | false    |              |             |

## codersdk.AIConfig

```json
{
  "aibridge_proxy": {
    "allowed_private_cidrs": [
      "string"
    ],
    "cert_file": "string",
    "domain_allowlist": [
      "string"
    ],
    "enabled": true,
    "key_file": "string",
    "listen_addr": "string",
    "tls_cert_file": "string",
    "tls_key_file": "string",
    "upstream_proxy": "string",
    "upstream_proxy_ca": "string"
  },
  "bridge": {
    "allow_byok": true,
    "anthropic": {
      "base_url": "string",
      "key": "string"
    },
    "bedrock": {
      "access_key": "string",
      "access_key_secret": "string",
      "base_url": "string",
      "model": "string",
      "region": "string",
      "small_fast_model": "string"
    },
    "circuit_breaker_enabled": true,
    "circuit_breaker_failure_threshold": 0,
    "circuit_breaker_interval": 0,
    "circuit_breaker_max_requests": 0,
    "circuit_breaker_timeout": 0,
    "enabled": true,
    "inject_coder_mcp_tools": true,
    "max_concurrency": 0,
    "openai": {
      "base_url": "string",
      "key": "string"
    },
    "providers": [
      {
        "base_url": "string",
        "bedrock_model": "string",
        "bedrock_region": "string",
        "bedrock_small_fast_model": "string",
        "dump_dir": "string",
        "name": "string",
        "type": "string"
      }
    ],
    "rate_limit": 0,
    "retention": 0,
    "send_actor_headers": true,
    "structured_logging": true
  },
  "chat": {
    "acquire_batch_size": 0,
    "debug_logging_enabled": true
  }
}
```

### Properties

| Name             | Type                                                         | Required | Restrictions | Description |
|------------------|--------------------------------------------------------------|----------|--------------|-------------|
| `aibridge_proxy` | [codersdk.AIBridgeProxyConfig](#codersdkaibridgeproxyconfig) | false    |              |             |
| `bridge`         | [codersdk.AIBridgeConfig](#codersdkaibridgeconfig)           | false    |              |             |
| `chat`           | [codersdk.ChatConfig](#codersdkchatconfig)                   | false    |              |             |

## codersdk.APIAllowListTarget

```json
{
  "id": "string",
  "type": "*"
}
```

### Properties

| Name   | Type                                           | Required | Restrictions | Description |
|--------|------------------------------------------------|----------|--------------|-------------|
| `id`   | string                                         | false    |              |             |
| `type` | [codersdk.RBACResource](#codersdkrbacresource) | false    |              |             |

## codersdk.APIKey

```json
{
  "allow_list": [
    {
      "id": "string",
      "type": "*"
    }
  ],
  "created_at": "2019-08-24T14:15:22Z",
  "expires_at": "2019-08-24T14:15:22Z",
  "id": "string",
  "last_used": "2019-08-24T14:15:22Z",
  "lifetime_seconds": 0,
  "login_type": "password",
  "scope": "all",
  "scopes": [
    "all"
  ],
  "token_name": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Properties

| Name               | Type                                                                | Required | Restrictions | Description                     |
|--------------------|---------------------------------------------------------------------|----------|--------------|---------------------------------|
| `allow_list`       | array of [codersdk.APIAllowListTarget](#codersdkapiallowlisttarget) | false    |              |                                 |
| `created_at`       | string                                                              | true     |              |                                 |
| `expires_at`       | string                                                              | true     |              |                                 |
| `id`               | string                                                              | true     |              |                                 |
| `last_used`        | string                                                              | true     |              |                                 |
| `lifetime_seconds` | integer                                                             | true     |              |                                 |
| `login_type`       | [codersdk.LoginType](#codersdklogintype)                            | true     |              |                                 |
| `scope`            | [codersdk.APIKeyScope](#codersdkapikeyscope)                        | false    |              | Deprecated: use Scopes instead. |
| `scopes`           | array of [codersdk.APIKeyScope](#codersdkapikeyscope)               | false    |              |                                 |
| `token_name`       | string                                                              | true     |              |                                 |
| `updated_at`       | string                                                              | true     |              |                                 |
| `user_id`          | string                                                              | true     |              |                                 |

#### Enumerated Values

| Property     | Value(s)                              |
|--------------|---------------------------------------|
| `login_type` | `github`, `oidc`, `password`, `token` |
| `scope`      | `all`, `application_connect`          |

## codersdk.APIKeyScope

```json
"all"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ai_seat:*`, `ai_seat:create`, `ai_seat:read`, `aibridge_interception:*`, `aibridge_interception:create`, `aibridge_interception:read`, `aibridge_interception:update`, `all`, `api_key:*`, `api_key:create`, `api_key:delete`, `api_key:read`, `api_key:update`, `application_connect`, `assign_org_role:*`, `assign_org_role:assign`, `assign_org_role:create`, `assign_org_role:delete`, `assign_org_role:read`, `assign_org_role:unassign`, `assign_org_role:update`, `assign_role:*`, `assign_role:assign`, `assign_role:read`, `assign_role:unassign`, `audit_log:*`, `audit_log:create`, `audit_log:read`, `boundary_usage:*`, `boundary_usage:delete`, `boundary_usage:read`, `boundary_usage:update`, `chat:*`, `chat:create`, `chat:delete`, `chat:read`, `chat:update`, `coder:all`, `coder:apikeys.manage_self`, `coder:application_connect`, `coder:templates.author`, `coder:templates.build`, `coder:workspaces.access`, `coder:workspaces.create`, `coder:workspaces.delete`, `coder:workspaces.operate`, `connection_log:*`, `connection_log:read`, `connection_log:update`, `crypto_key:*`, `crypto_key:create`, `crypto_key:delete`, `crypto_key:read`, `crypto_key:update`, `debug_info:*`, `debug_info:read`, `deployment_config:*`, `deployment_config:read`, `deployment_config:update`, `deployment_stats:*`, `deployment_stats:read`, `file:*`, `file:create`, `file:read`, `group:*`, `group:create`, `group:delete`, `group:read`, `group:update`, `group_member:*`, `group_member:read`, `idpsync_settings:*`, `idpsync_settings:read`, `idpsync_settings:update`, `inbox_notification:*`, `inbox_notification:create`, `inbox_notification:read`, `inbox_notification:update`, `license:*`, `license:create`, `license:delete`, `license:read`, `notification_message:*`, `notification_message:create`, `notification_message:delete`, `notification_message:read`, `notification_message:update`, `notification_preference:*`, `notification_preference:read`, `notification_preference:update`, `notification_template:*`, `notification_template:read`, `notification_template:update`, `oauth2_app:*`, `oauth2_app:create`, `oauth2_app:delete`, `oauth2_app:read`, `oauth2_app:update`, `oauth2_app_code_token:*`, `oauth2_app_code_token:create`, `oauth2_app_code_token:delete`, `oauth2_app_code_token:read`, `oauth2_app_secret:*`, `oauth2_app_secret:create`, `oauth2_app_secret:delete`, `oauth2_app_secret:read`, `oauth2_app_secret:update`, `organization:*`, `organization:create`, `organization:delete`, `organization:read`, `organization:update`, `organization_member:*`, `organization_member:create`, `organization_member:delete`, `organization_member:read`, `organization_member:update`, `prebuilt_workspace:*`, `prebuilt_workspace:delete`, `prebuilt_workspace:update`, `provisioner_daemon:*`, `provisioner_daemon:create`, `provisioner_daemon:delete`, `provisioner_daemon:read`, `provisioner_daemon:update`, `provisioner_jobs:*`, `provisioner_jobs:create`, `provisioner_jobs:read`, `provisioner_jobs:update`, `replicas:*`, `replicas:read`, `system:*`, `system:create`, `system:delete`, `system:read`, `system:update`, `tailnet_coordinator:*`, `tailnet_coordinator:create`, `tailnet_coordinator:delete`, `tailnet_coordinator:read`, `tailnet_coordinator:update`, `task:*`, `task:create`, `task:delete`, `task:read`, `task:update`, `template:*`, `template:create`, `template:delete`, `template:read`, `template:update`, `template:use`, `template:view_insights`, `usage_event:*`, `usage_event:create`, `usage_event:read`, `usage_event:update`, `user:*`, `user:create`, `user:delete`, `user:read`, `user:read_personal`, `user:update`, `user:update_personal`, `user_secret:*`, `user_secret:create`, `user_secret:delete`, `user_secret:read`, `user_secret:update`, `webpush_subscription:*`, `webpush_subscription:create`, `webpush_subscription:delete`, `webpush_subscription:read`, `workspace:*`, `workspace:application_connect`, `workspace:create`, `workspace:create_agent`, `workspace:delete`, `workspace:delete_agent`, `workspace:read`, `workspace:share`, `workspace:ssh`, `workspace:start`, `workspace:stop`, `workspace:update`, `workspace:update_agent`, `workspace_agent_devcontainers:*`, `workspace_agent_devcontainers:create`, `workspace_agent_resource_monitor:*`, `workspace_agent_resource_monitor:create`, `workspace_agent_resource_monitor:read`, `workspace_agent_resource_monitor:update`, `workspace_dormant:*`, `workspace_dormant:application_connect`, `workspace_dormant:create`, `workspace_dormant:create_agent`, `workspace_dormant:delete`, `workspace_dormant:delete_agent`, `workspace_dormant:read`, `workspace_dormant:share`, `workspace_dormant:ssh`, `workspace_dormant:start`, `workspace_dormant:stop`, `workspace_dormant:update`, `workspace_dormant:update_agent`, `workspace_proxy:*`, `workspace_proxy:create`, `workspace_proxy:delete`, `workspace_proxy:read`, `workspace_proxy:update` |

## codersdk.AddLicenseRequest

```json
{
  "license": "string"
}
```

### Properties

| Name      | Type   | Required | Restrictions | Description |
|-----------|--------|----------|--------------|-------------|
| `license` | string | true     |              |             |

## codersdk.AgentConnectionTiming

```json
{
  "ended_at": "2019-08-24T14:15:22Z",
  "stage": "init",
  "started_at": "2019-08-24T14:15:22Z",
  "workspace_agent_id": "string",
  "workspace_agent_name": "string"
}
```

### Properties

| Name                   | Type                                         | Required | Restrictions | Description |
|------------------------|----------------------------------------------|----------|--------------|-------------|
| `ended_at`             | string                                       | false    |              |             |
| `stage`                | [codersdk.TimingStage](#codersdktimingstage) | false    |              |             |
| `started_at`           | string                                       | false    |              |             |
| `workspace_agent_id`   | string                                       | false    |              |             |
| `workspace_agent_name` | string                                       | false    |              |             |

## codersdk.AgentDisplayMode

```json
"auto"
```

### Properties

#### Enumerated Values

| Value(s)                                      |
|-----------------------------------------------|
| `always_collapsed`, `always_expanded`, `auto` |

## codersdk.AgentScriptTiming

```json
{
  "display_name": "string",
  "ended_at": "2019-08-24T14:15:22Z",
  "exit_code": 0,
  "stage": "init",
  "started_at": "2019-08-24T14:15:22Z",
  "status": "string",
  "workspace_agent_id": "string",
  "workspace_agent_name": "string"
}
```

### Properties

| Name                   | Type                                         | Required | Restrictions | Description |
|------------------------|----------------------------------------------|----------|--------------|-------------|
| `display_name`         | string                                       | false    |              |             |
| `ended_at`             | string                                       | false    |              |             |
| `exit_code`            | integer                                      | false    |              |             |
| `stage`                | [codersdk.TimingStage](#codersdktimingstage) | false    |              |             |
| `started_at`           | string                                       | false    |              |             |
| `status`               | string                                       | false    |              |             |
| `workspace_agent_id`   | string                                       | false    |              |             |
| `workspace_agent_name` | string                                       | false    |              |             |

## codersdk.AgentSubsystem

```json
"envbox"
```

### Properties

#### Enumerated Values

| Value(s)                            |
|-------------------------------------|
| `envbox`, `envbuilder`, `exectrace` |

## codersdk.AppHostResponse

```json
{
  "host": "string"
}
```

### Properties

| Name   | Type   | Required | Restrictions | Description                                                   |
|--------|--------|----------|--------------|---------------------------------------------------------------|
| `host` | string | false    |              | Host is the externally accessible URL for the Coder instance. |

## codersdk.AppearanceConfig

```json
{
  "announcement_banners": [
    {
      "background_color": "string",
      "enabled": true,
      "message": "string"
    }
  ],
  "application_name": "string",
  "docs_url": "string",
  "logo_url": "string",
  "service_banner": {
    "background_color": "string",
    "enabled": true,
    "message": "string"
  },
  "support_links": [
    {
      "icon": "bug",
      "location": "navbar",
      "name": "string",
      "target": "string"
    }
  ]
}
```

### Properties

| Name                   | Type                                                    | Required | Restrictions | Description                                                         |
|------------------------|---------------------------------------------------------|----------|--------------|---------------------------------------------------------------------|
| `announcement_banners` | array of [codersdk.BannerConfig](#codersdkbannerconfig) | false    |              |                                                                     |
| `application_name`     | string                                                  | false    |              |                                                                     |
| `docs_url`             | string                                                  | false    |              |                                                                     |
| `logo_url`             | string                                                  | false    |              |                                                                     |
| `service_banner`       | [codersdk.BannerConfig](#codersdkbannerconfig)          | false    |              | Deprecated: ServiceBanner has been replaced by AnnouncementBanners. |
| `support_links`        | array of [codersdk.LinkConfig](#codersdklinkconfig)     | false    |              |                                                                     |

## codersdk.ArchiveTemplateVersionsRequest

```json
{
  "all": true
}
```

### Properties

| Name  | Type    | Required | Restrictions | Description                                                                                                              |
|-------|---------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------|
| `all` | boolean | false    |              | By default, only failed versions are archived. Set this to true to archive all unused versions regardless of job status. |

## codersdk.AssignableRoles

```json
{
  "assignable": true,
  "built_in": true,
  "display_name": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_member_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "organization_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "site_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "user_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ]
}
```

### Properties

| Name                              | Type                                                | Required | Restrictions | Description                                                                                            |
|-----------------------------------|-----------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------|
| `assignable`                      | boolean                                             | false    |              |                                                                                                        |
| `built_in`                        | boolean                                             | false    |              | Built in roles are immutable                                                                           |
| `display_name`                    | string                                              | false    |              |                                                                                                        |
| `name`                            | string                                              | false    |              |                                                                                                        |
| `organization_id`                 | string                                              | false    |              |                                                                                                        |
| `organization_member_permissions` | array of [codersdk.Permission](#codersdkpermission) | false    |              | Organization member permissions are specific for the organization in the field 'OrganizationID' above. |
| `organization_permissions`        | array of [codersdk.Permission](#codersdkpermission) | false    |              | Organization permissions are specific for the organization in the field 'OrganizationID' above.        |
| `site_permissions`                | array of [codersdk.Permission](#codersdkpermission) | false    |              |                                                                                                        |
| `user_permissions`                | array of [codersdk.Permission](#codersdkpermission) | false    |              |                                                                                                        |

## codersdk.AuditAction

```json
"create"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                                        |
|-------------------------------------------------------------------------------------------------------------------------------------------------|
| `close`, `connect`, `create`, `delete`, `disconnect`, `login`, `logout`, `open`, `register`, `request_password_reset`, `start`, `stop`, `write` |

## codersdk.AuditDiff

```json
{
  "property1": {
    "new": null,
    "old": null,
    "secret": true
  },
  "property2": {
    "new": null,
    "old": null,
    "secret": true
  }
}
```

### Properties

| Name             | Type                                               | Required | Restrictions | Description |
|------------------|----------------------------------------------------|----------|--------------|-------------|
| `[any property]` | [codersdk.AuditDiffField](#codersdkauditdifffield) | false    |              |             |

## codersdk.AuditDiffField

```json
{
  "new": null,
  "old": null,
  "secret": true
}
```

### Properties

| Name     | Type    | Required | Restrictions | Description |
|----------|---------|----------|--------------|-------------|
| `new`    | any     | false    |              |             |
| `old`    | any     | false    |              |             |
| `secret` | boolean | false    |              |             |

## codersdk.AuditLog

```json
{
  "action": "create",
  "additional_fields": {},
  "description": "string",
  "diff": {
    "property1": {
      "new": null,
      "old": null,
      "secret": true
    },
    "property2": {
      "new": null,
      "old": null,
      "secret": true
    }
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "ip": "string",
  "is_deleted": true,
  "organization": {
    "display_name": "string",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string"
  },
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "request_id": "266ea41d-adf5-480b-af50-15b940c2b846",
  "resource_icon": "string",
  "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  "resource_link": "string",
  "resource_target": "string",
  "resource_type": "template",
  "status_code": 0,
  "time": "2019-08-24T14:15:22Z",
  "user": {
    "avatar_url": "http://example.com",
    "created_at": "2019-08-24T14:15:22Z",
    "email": "user@example.com",
    "has_ai_seat": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "is_service_account": true,
    "last_seen_at": "2019-08-24T14:15:22Z",
    "login_type": "",
    "name": "string",
    "organization_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "roles": [
      {
        "display_name": "string",
        "name": "string",
        "organization_id": "string"
      }
    ],
    "status": "active",
    "theme_preference": "string",
    "updated_at": "2019-08-24T14:15:22Z",
    "username": "string"
  },
  "user_agent": "string"
}
```

### Properties

| Name                | Type                                                         | Required | Restrictions | Description                                  |
|---------------------|--------------------------------------------------------------|----------|--------------|----------------------------------------------|
| `action`            | [codersdk.AuditAction](#codersdkauditaction)                 | false    |              |                                              |
| `additional_fields` | object                                                       | false    |              |                                              |
| `description`       | string                                                       | false    |              |                                              |
| `diff`              | [codersdk.AuditDiff](#codersdkauditdiff)                     | false    |              |                                              |
| `id`                | string                                                       | false    |              |                                              |
| `ip`                | string                                                       | false    |              |                                              |
| `is_deleted`        | boolean                                                      | false    |              |                                              |
| `organization`      | [codersdk.MinimalOrganization](#codersdkminimalorganization) | false    |              |                                              |
| `organization_id`   | string                                                       | false    |              | Deprecated: Use 'organization.id' instead.   |
| `request_id`        | string                                                       | false    |              |                                              |
| `resource_icon`     | string                                                       | false    |              |                                              |
| `resource_id`       | string                                                       | false    |              |                                              |
| `resource_link`     | string                                                       | false    |              |                                              |
| `resource_target`   | string                                                       | false    |              | Resource target is the name of the resource. |
| `resource_type`     | [codersdk.ResourceType](#codersdkresourcetype)               | false    |              |                                              |
| `status_code`       | integer                                                      | false    |              |                                              |
| `time`              | string                                                       | false    |              |                                              |
| `user`              | [codersdk.User](#codersdkuser)                               | false    |              |                                              |
| `user_agent`        | string                                                       | false    |              |                                              |

## codersdk.AuditLogResponse

```json
{
  "audit_logs": [
    {
      "action": "create",
      "additional_fields": {},
      "description": "string",
      "diff": {
        "property1": {
          "new": null,
          "old": null,
          "secret": true
        },
        "property2": {
          "new": null,
          "old": null,
          "secret": true
        }
      },
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "ip": "string",
      "is_deleted": true,
      "organization": {
        "display_name": "string",
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "request_id": "266ea41d-adf5-480b-af50-15b940c2b846",
      "resource_icon": "string",
      "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
      "resource_link": "string",
      "resource_target": "string",
      "resource_type": "template",
      "status_code": 0,
      "time": "2019-08-24T14:15:22Z",
      "user": {
        "avatar_url": "http://example.com",
        "created_at": "2019-08-24T14:15:22Z",
        "email": "user@example.com",
        "has_ai_seat": true,
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "is_service_account": true,
        "last_seen_at": "2019-08-24T14:15:22Z",
        "login_type": "",
        "name": "string",
        "organization_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "roles": [
          {
            "display_name": "string",
            "name": "string",
            "organization_id": "string"
          }
        ],
        "status": "active",
        "theme_preference": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "username": "string"
      },
      "user_agent": "string"
    }
  ],
  "count": 0,
  "count_cap": 0
}
```

### Properties

| Name         | Type                                            | Required | Restrictions | Description |
|--------------|-------------------------------------------------|----------|--------------|-------------|
| `audit_logs` | array of [codersdk.AuditLog](#codersdkauditlog) | false    |              |             |
| `count`      | integer                                         | false    |              |             |
| `count_cap`  | integer                                         | false    |              |             |

## codersdk.AuthMethod

```json
{
  "enabled": true
}
```

### Properties

| Name      | Type    | Required | Restrictions | Description |
|-----------|---------|----------|--------------|-------------|
| `enabled` | boolean | false    |              |             |

## codersdk.AuthMethods

```json
{
  "github": {
    "default_provider_configured": true,
    "enabled": true
  },
  "oidc": {
    "enabled": true,
    "iconUrl": "string",
    "signInText": "string"
  },
  "password": {
    "enabled": true
  },
  "terms_of_service_url": "string"
}
```

### Properties

| Name                   | Type                                                   | Required | Restrictions | Description |
|------------------------|--------------------------------------------------------|----------|--------------|-------------|
| `github`               | [codersdk.GithubAuthMethod](#codersdkgithubauthmethod) | false    |              |             |
| `oidc`                 | [codersdk.OIDCAuthMethod](#codersdkoidcauthmethod)     | false    |              |             |
| `password`             | [codersdk.AuthMethod](#codersdkauthmethod)             | false    |              |             |
| `terms_of_service_url` | string                                                 | false    |              |             |

## codersdk.AuthorizationCheck

```json
{
  "action": "create",
  "object": {
    "any_org": true,
    "organization_id": "string",
    "owner_id": "string",
    "resource_id": "string",
    "resource_type": "*"
  }
}
```

AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.

### Properties

| Name     | Type                                                         | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
|----------|--------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `action` | [codersdk.RBACAction](#codersdkrbacaction)                   | false    |              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `object` | [codersdk.AuthorizationObject](#codersdkauthorizationobject) | false    |              | Object can represent a "set" of objects, such as: all workspaces in an organization, all workspaces owned by me, and all workspaces across the entire product. When defining an object, use the most specific language when possible to produce the smallest set. Meaning to set as many fields on 'Object' as you can. Example, if you want to check if you can update all workspaces owned by 'me', try to also add an 'OrganizationID' to the settings. Omitting the 'OrganizationID' could produce the incorrect value, as workspaces have both `user` and `organization` owners. |

#### Enumerated Values

| Property | Value(s)                             |
|----------|--------------------------------------|
| `action` | `create`, `delete`, `read`, `update` |

## codersdk.AuthorizationObject

```json
{
  "any_org": true,
  "organization_id": "string",
  "owner_id": "string",
  "resource_id": "string",
  "resource_type": "*"
}
```

AuthorizationObject can represent a "set" of objects, such as: all workspaces in an organization, all workspaces owned by me, all workspaces across the entire product.

### Properties

| Name              | Type                                           | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                                                                          |
|-------------------|------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `any_org`         | boolean                                        | false    |              | Any org (optional) will disregard the org_owner when checking for permissions. This cannot be set to true if the OrganizationID is set.                                                                                                                                                                                                                              |
| `organization_id` | string                                         | false    |              | Organization ID (optional) adds the set constraint to all resources owned by a given organization.                                                                                                                                                                                                                                                                   |
| `owner_id`        | string                                         | false    |              | Owner ID (optional) adds the set constraint to all resources owned by a given user.                                                                                                                                                                                                                                                                                  |
| `resource_id`     | string                                         | false    |              | Resource ID (optional) reduces the set to a singular resource. This assigns a resource ID to the resource type, eg: a single workspace. The rbac library will not fetch the resource from the database, so if you are using this option, you should also set the owner ID and organization ID if possible. Be as specific as possible using all the fields relevant. |
| `resource_type`   | [codersdk.RBACResource](#codersdkrbacresource) | false    |              | Resource type is the name of the resource. `./coderd/rbac/object.go` has the list of valid resource types.                                                                                                                                                                                                                                                           |

## codersdk.AuthorizationRequest

```json
{
  "checks": {
    "property1": {
      "action": "create",
      "object": {
        "any_org": true,
        "organization_id": "string",
        "owner_id": "string",
        "resource_id": "string",
        "resource_type": "*"
      }
    },
    "property2": {
      "action": "create",
      "object": {
        "any_org": true,
        "organization_id": "string",
        "owner_id": "string",
        "resource_id": "string",
        "resource_type": "*"
      }
    }
  }
}
```

### Properties

| Name               | Type                                                       | Required | Restrictions | Description                                                                                                                                                                                                                                                                      |
|--------------------|------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `checks`           | object                                                     | false    |              | Checks is a map keyed with an arbitrary string to a permission check. The key can be any string that is helpful to the caller, and allows multiple permission checks to be run in a single request. The key ensures that each permission check has the same key in the response. |
| » `[any property]` | [codersdk.AuthorizationCheck](#codersdkauthorizationcheck) | false    |              | It is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.                                                                                                                                                 |

## codersdk.AuthorizationResponse

```json
{
  "property1": true,
  "property2": true
}
```

### Properties

| Name             | Type    | Required | Restrictions | Description |
|------------------|---------|----------|--------------|-------------|
| `[any property]` | boolean | false    |              |             |

## codersdk.AutomaticUpdates

```json
"always"
```

### Properties

#### Enumerated Values

| Value(s)          |
|-------------------|
| `always`, `never` |

## codersdk.BannerConfig

```json
{
  "background_color": "string",
  "enabled": true,
  "message": "string"
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description |
|--------------------|---------|----------|--------------|-------------|
| `background_color` | string  | false    |              |             |
| `enabled`          | boolean | false    |              |             |
| `message`          | string  | false    |              |             |

## codersdk.BuildInfoResponse

```json
{
  "agent_api_version": "string",
  "dashboard_url": "string",
  "deployment_id": "string",
  "external_url": "string",
  "provisioner_api_version": "string",
  "telemetry": true,
  "upgrade_message": "string",
  "version": "string",
  "webpush_public_key": "string",
  "workspace_proxy": true
}
```

### Properties

| Name                      | Type    | Required | Restrictions | Description                                                                                                                                                         |
|---------------------------|---------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `agent_api_version`       | string  | false    |              | Agent api version is the current version of the Agent API (back versions MAY still be supported).                                                                   |
| `dashboard_url`           | string  | false    |              | Dashboard URL is the URL to hit the deployment's dashboard. For external workspace proxies, this is the coderd they are connected to.                               |
| `deployment_id`           | string  | false    |              | Deployment ID is the unique identifier for this deployment.                                                                                                         |
| `external_url`            | string  | false    |              | External URL references the current Coder version. For production builds, this will link directly to a release. For development builds, this will link to a commit. |
| `provisioner_api_version` | string  | false    |              | Provisioner api version is the current version of the Provisioner API                                                                                               |
| `telemetry`               | boolean | false    |              | Telemetry is a boolean that indicates whether telemetry is enabled.                                                                                                 |
| `upgrade_message`         | string  | false    |              | Upgrade message is the message displayed to users when an outdated client is detected.                                                                              |
| `version`                 | string  | false    |              | Version returns the semantic version of the build.                                                                                                                  |
| `webpush_public_key`      | string  | false    |              | Webpush public key is the public key for push notifications via Web Push.                                                                                           |
| `workspace_proxy`         | boolean | false    |              |                                                                                                                                                                     |

## codersdk.BuildReason

```json
"initiator"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                                                                                   |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `autostart`, `autostop`, `cli`, `dashboard`, `dormancy`, `initiator`, `jetbrains_connection`, `ssh_connection`, `task_auto_pause`, `task_manual_pause`, `task_resume`, `vscode_connection` |

## codersdk.CORSBehavior

```json
"simple"
```

### Properties

#### Enumerated Values

| Value(s)             |
|----------------------|
| `passthru`, `simple` |

## codersdk.ChangePasswordWithOneTimePasscodeRequest

```json
{
  "email": "user@example.com",
  "one_time_passcode": "string",
  "password": "string"
}
```

### Properties

| Name                | Type   | Required | Restrictions | Description |
|---------------------|--------|----------|--------------|-------------|
| `email`             | string | true     |              |             |
| `one_time_passcode` | string | true     |              |             |
| `password`          | string | true     |              |             |

## codersdk.Chat

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "archived": true,
  "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
  "children": [
    {
      "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
      "archived": true,
      "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
      "children": [],
      "client_type": "ui",
      "created_at": "2019-08-24T14:15:22Z",
      "diff_status": {
        "additions": 0,
        "approved": true,
        "author_avatar_url": "string",
        "author_login": "string",
        "base_branch": "string",
        "changed_files": 0,
        "changes_requested": true,
        "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
        "commits": 0,
        "deletions": 0,
        "head_branch": "string",
        "pr_number": 0,
        "pull_request_draft": true,
        "pull_request_state": "string",
        "pull_request_title": "string",
        "refreshed_at": "2019-08-24T14:15:22Z",
        "reviewer_count": 0,
        "stale_at": "2019-08-24T14:15:22Z",
        "url": "string"
      },
      "files": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "mime_type": "string",
          "name": "string",
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
        }
      ],
      "has_unread": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "last_error": {
        "detail": "string",
        "kind": "generic",
        "message": "string",
        "provider": "string",
        "retryable": true,
        "status_code": 0
      },
      "last_injected_context": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
      "last_turn_summary": "string",
      "mcp_server_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
      "pin_order": 0,
      "plan_mode": "plan",
      "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
      "status": "waiting",
      "title": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "warnings": [
        "string"
      ],
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ],
  "client_type": "ui",
  "created_at": "2019-08-24T14:15:22Z",
  "diff_status": {
    "additions": 0,
    "approved": true,
    "author_avatar_url": "string",
    "author_login": "string",
    "base_branch": "string",
    "changed_files": 0,
    "changes_requested": true,
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "commits": 0,
    "deletions": 0,
    "head_branch": "string",
    "pr_number": 0,
    "pull_request_draft": true,
    "pull_request_state": "string",
    "pull_request_title": "string",
    "refreshed_at": "2019-08-24T14:15:22Z",
    "reviewer_count": 0,
    "stale_at": "2019-08-24T14:15:22Z",
    "url": "string"
  },
  "files": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "mime_type": "string",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
    }
  ],
  "has_unread": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "last_error": {
    "detail": "string",
    "kind": "generic",
    "message": "string",
    "provider": "string",
    "retryable": true,
    "status_code": 0
  },
  "last_injected_context": [
    {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    }
  ],
  "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
  "last_turn_summary": "string",
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
  "pin_order": 0,
  "plan_mode": "plan",
  "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
  "status": "waiting",
  "title": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "string"
  ],
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Properties

| Name                    | Type                                                            | Required | Restrictions | Description                                                                                                                                                                                                                                                                |
|-------------------------|-----------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `agent_id`              | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `archived`              | boolean                                                         | false    |              |                                                                                                                                                                                                                                                                            |
| `build_id`              | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `children`              | array of [codersdk.Chat](#codersdkchat)                         | false    |              | Children holds child (subagent) chats nested under this root chat. Always initialized to an empty slice so the JSON field is present as []. Child chats cannot create their own subagents, so nesting depth is capped at 1 and this slice is always empty for child chats. |
| `client_type`           | [codersdk.ChatClientType](#codersdkchatclienttype)              | false    |              |                                                                                                                                                                                                                                                                            |
| `created_at`            | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `diff_status`           | [codersdk.ChatDiffStatus](#codersdkchatdiffstatus)              | false    |              |                                                                                                                                                                                                                                                                            |
| `files`                 | array of [codersdk.ChatFileMetadata](#codersdkchatfilemetadata) | false    |              |                                                                                                                                                                                                                                                                            |
| `has_unread`            | boolean                                                         | false    |              | Has unread is true when assistant messages exist beyond the owner's read cursor, which updates on stream connect and disconnect.                                                                                                                                           |
| `id`                    | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `labels`                | object                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| » `[any property]`      | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `last_error`            | [codersdk.ChatError](#codersdkchaterror)                        | false    |              |                                                                                                                                                                                                                                                                            |
| `last_injected_context` | array of [codersdk.ChatMessagePart](#codersdkchatmessagepart)   | false    |              | Last injected context holds the most recently persisted injected context parts (AGENTS.md files and skills). It is updated only when context changes, on first workspace attach or agent change.                                                                           |
| `last_model_config_id`  | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `last_turn_summary`     | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `mcp_server_ids`        | array of string                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `organization_id`       | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `owner_id`              | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `parent_chat_id`        | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `pin_order`             | integer                                                         | false    |              |                                                                                                                                                                                                                                                                            |
| `plan_mode`             | [codersdk.ChatPlanMode](#codersdkchatplanmode)                  | false    |              |                                                                                                                                                                                                                                                                            |
| `root_chat_id`          | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `status`                | [codersdk.ChatStatus](#codersdkchatstatus)                      | false    |              |                                                                                                                                                                                                                                                                            |
| `title`                 | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `updated_at`            | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |
| `warnings`              | array of string                                                 | false    |              |                                                                                                                                                                                                                                                                            |
| `workspace_id`          | string                                                          | false    |              |                                                                                                                                                                                                                                                                            |

## codersdk.ChatBusyBehavior

```json
"queue"
```

### Properties

#### Enumerated Values

| Value(s)             |
|----------------------|
| `interrupt`, `queue` |

## codersdk.ChatClientType

```json
"ui"
```

### Properties

#### Enumerated Values

| Value(s)    |
|-------------|
| `api`, `ui` |

## codersdk.ChatConfig

```json
{
  "acquire_batch_size": 0,
  "debug_logging_enabled": true
}
```

### Properties

| Name                    | Type    | Required | Restrictions | Description |
|-------------------------|---------|----------|--------------|-------------|
| `acquire_batch_size`    | integer | false    |              |             |
| `debug_logging_enabled` | boolean | false    |              |             |

## codersdk.ChatDiffContents

```json
{
  "branch": "string",
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "diff": "string",
  "provider": "string",
  "pull_request_url": "string",
  "remote_origin": "string"
}
```

### Properties

| Name               | Type   | Required | Restrictions | Description |
|--------------------|--------|----------|--------------|-------------|
| `branch`           | string | false    |              |             |
| `chat_id`          | string | false    |              |             |
| `diff`             | string | false    |              |             |
| `provider`         | string | false    |              |             |
| `pull_request_url` | string | false    |              |             |
| `remote_origin`    | string | false    |              |             |

## codersdk.ChatDiffStatus

```json
{
  "additions": 0,
  "approved": true,
  "author_avatar_url": "string",
  "author_login": "string",
  "base_branch": "string",
  "changed_files": 0,
  "changes_requested": true,
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "commits": 0,
  "deletions": 0,
  "head_branch": "string",
  "pr_number": 0,
  "pull_request_draft": true,
  "pull_request_state": "string",
  "pull_request_title": "string",
  "refreshed_at": "2019-08-24T14:15:22Z",
  "reviewer_count": 0,
  "stale_at": "2019-08-24T14:15:22Z",
  "url": "string"
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `additions`          | integer | false    |              |             |
| `approved`           | boolean | false    |              |             |
| `author_avatar_url`  | string  | false    |              |             |
| `author_login`       | string  | false    |              |             |
| `base_branch`        | string  | false    |              |             |
| `changed_files`      | integer | false    |              |             |
| `changes_requested`  | boolean | false    |              |             |
| `chat_id`            | string  | false    |              |             |
| `commits`            | integer | false    |              |             |
| `deletions`          | integer | false    |              |             |
| `head_branch`        | string  | false    |              |             |
| `pr_number`          | integer | false    |              |             |
| `pull_request_draft` | boolean | false    |              |             |
| `pull_request_state` | string  | false    |              |             |
| `pull_request_title` | string  | false    |              |             |
| `refreshed_at`       | string  | false    |              |             |
| `reviewer_count`     | integer | false    |              |             |
| `stale_at`           | string  | false    |              |             |
| `url`                | string  | false    |              |             |

## codersdk.ChatError

```json
{
  "detail": "string",
  "kind": "generic",
  "message": "string",
  "provider": "string",
  "retryable": true,
  "status_code": 0
}
```

### Properties

| Name          | Type                                             | Required | Restrictions | Description                                                                                               |
|---------------|--------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------|
| `detail`      | string                                           | false    |              | Detail is optional provider-specific context shown alongside the normalized error message when available. |
| `kind`        | [codersdk.ChatErrorKind](#codersdkchaterrorkind) | false    |              | Kind classifies the error for consistent client rendering.                                                |
| `message`     | string                                           | false    |              | Message is the normalized, user-facing error message.                                                     |
| `provider`    | string                                           | false    |              | Provider identifies the upstream model provider when known.                                               |
| `retryable`   | boolean                                          | false    |              | Retryable reports whether the underlying error is transient.                                              |
| `status_code` | integer                                          | false    |              | Status code is the best-effort upstream HTTP status code.                                                 |

## codersdk.ChatErrorKind

```json
"generic"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                             |
|------------------------------------------------------------------------------------------------------|
| `auth`, `config`, `generic`, `overloaded`, `rate_limit`, `startup_timeout`, `timeout`, `usage_limit` |

## codersdk.ChatFileMetadata

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "mime_type": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
}
```

### Properties

| Name              | Type   | Required | Restrictions | Description |
|-------------------|--------|----------|--------------|-------------|
| `created_at`      | string | false    |              |             |
| `id`              | string | false    |              |             |
| `mime_type`       | string | false    |              |             |
| `name`            | string | false    |              |             |
| `organization_id` | string | false    |              |             |
| `owner_id`        | string | false    |              |             |

## codersdk.ChatInputPart

```json
{
  "content": "string",
  "end_line": 0,
  "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
  "file_name": "string",
  "start_line": 0,
  "text": "string",
  "type": "text"
}
```

### Properties

| Name         | Type                                                     | Required | Restrictions | Description                                                                    |
|--------------|----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------|
| `content`    | string                                                   | false    |              | The code content from the diff that was commented on.                          |
| `end_line`   | integer                                                  | false    |              |                                                                                |
| `file_id`    | string                                                   | false    |              |                                                                                |
| `file_name`  | string                                                   | false    |              | The following fields are only set when Type is ChatInputPartTypeFileReference. |
| `start_line` | integer                                                  | false    |              |                                                                                |
| `text`       | string                                                   | false    |              |                                                                                |
| `type`       | [codersdk.ChatInputPartType](#codersdkchatinputparttype) | false    |              |                                                                                |

## codersdk.ChatInputPartType

```json
"text"
```

### Properties

#### Enumerated Values

| Value(s)                         |
|----------------------------------|
| `file`, `file-reference`, `text` |

## codersdk.ChatMessage

```json
{
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "content": [
    {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    }
  ],
  "created_at": "2019-08-24T14:15:22Z",
  "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
  "id": 0,
  "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
  "role": "system",
  "usage": {
    "cache_creation_tokens": 0,
    "cache_read_tokens": 0,
    "context_limit": 0,
    "input_tokens": 0,
    "output_tokens": 0,
    "reasoning_tokens": 0,
    "total_tokens": 0
  }
}
```

### Properties

| Name              | Type                                                          | Required | Restrictions | Description |
|-------------------|---------------------------------------------------------------|----------|--------------|-------------|
| `chat_id`         | string                                                        | false    |              |             |
| `content`         | array of [codersdk.ChatMessagePart](#codersdkchatmessagepart) | false    |              |             |
| `created_at`      | string                                                        | false    |              |             |
| `created_by`      | string                                                        | false    |              |             |
| `id`              | integer                                                       | false    |              |             |
| `model_config_id` | string                                                        | false    |              |             |
| `role`            | [codersdk.ChatMessageRole](#codersdkchatmessagerole)          | false    |              |             |
| `usage`           | [codersdk.ChatMessageUsage](#codersdkchatmessageusage)        | false    |              |             |

## codersdk.ChatMessagePart

```json
{
  "args": [
    0
  ],
  "args_delta": "string",
  "content": "string",
  "context_file_agent_id": {
    "uuid": "string",
    "valid": true
  },
  "context_file_content": "string",
  "context_file_directory": "string",
  "context_file_os": "string",
  "context_file_path": "string",
  "context_file_skill_meta_file": "string",
  "context_file_truncated": true,
  "created_at": "2019-08-24T14:15:22Z",
  "data": [
    0
  ],
  "end_line": 0,
  "file_id": {
    "uuid": "string",
    "valid": true
  },
  "file_name": "string",
  "is_error": true,
  "is_media": true,
  "mcp_server_config_id": {
    "uuid": "string",
    "valid": true
  },
  "media_type": "string",
  "name": "string",
  "provider_executed": true,
  "provider_metadata": [
    0
  ],
  "result": [
    0
  ],
  "result_delta": "string",
  "signature": "string",
  "skill_description": "string",
  "skill_dir": "string",
  "skill_name": "string",
  "source_id": "string",
  "start_line": 0,
  "text": "string",
  "title": "string",
  "tool_call_id": "string",
  "tool_name": "string",
  "type": "text",
  "url": "string"
}
```

### Properties

| Name                           | Type                                                         | Required | Restrictions | Description                                                                                                                                                                                                                                                        |
|--------------------------------|--------------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `args`                         | array of integer                                             | false    |              |                                                                                                                                                                                                                                                                    |
| `args_delta`                   | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `content`                      | string                                                       | false    |              | The code content from the diff that was commented on.                                                                                                                                                                                                              |
| `context_file_agent_id`        | [uuid.NullUUID](#uuidnulluuid)                               | false    |              | Context file agent ID is the workspace agent that provided this context file. Used to detect when the agent changes (e.g. workspace rebuilt) so instruction files can be re-persisted with fresh content.                                                          |
| `context_file_content`         | string                                                       | false    |              | Context file content holds the file content sent to the LLM. Internal only: stripped before API responses to keep payloads small. The backend reads it when building the prompt via partsToMessageParts.                                                           |
| `context_file_directory`       | string                                                       | false    |              | Context file directory is the working directory of the workspace agent. Internal only: same purpose as ContextFileOS.                                                                                                                                              |
| `context_file_os`              | string                                                       | false    |              | Context file os is the operating system of the workspace agent. Internal only: used during prompt expansion so the LLM knows the OS even on turns where InsertSystem is not called.                                                                                |
| `context_file_path`            | string                                                       | false    |              | Context file path is the absolute path of a file loaded into the LLM context (e.g. an AGENTS.md instruction file).                                                                                                                                                 |
| `context_file_skill_meta_file` | string                                                       | false    |              | Context file skill meta file is the basename of the skill meta file (e.g. "SKILL.md") at the time of persistence. Internal only: restored on subsequent turns so the read_skill tool uses the correct filename even when the agent configured a non-default value. |
| `context_file_truncated`       | boolean                                                      | false    |              | Context file truncated indicates the file exceeded the 64KiB instruction file limit and was truncated.                                                                                                                                                             |
| `created_at`                   | string                                                       | false    |              | Created at records when this part was produced. Present on tool-call and tool-result parts so the frontend can compute tool execution duration.                                                                                                                    |
| `data`                         | array of integer                                             | false    |              |                                                                                                                                                                                                                                                                    |
| `end_line`                     | integer                                                      | false    |              |                                                                                                                                                                                                                                                                    |
| `file_id`                      | [uuid.NullUUID](#uuidnulluuid)                               | false    |              |                                                                                                                                                                                                                                                                    |
| `file_name`                    | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `is_error`                     | boolean                                                      | false    |              |                                                                                                                                                                                                                                                                    |
| `is_media`                     | boolean                                                      | false    |              |                                                                                                                                                                                                                                                                    |
| `mcp_server_config_id`         | [uuid.NullUUID](#uuidnulluuid)                               | false    |              |                                                                                                                                                                                                                                                                    |
| `media_type`                   | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `name`                         | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `provider_executed`            | boolean                                                      | false    |              | Provider executed indicates the tool call was executed by the provider (e.g. Anthropic computer use).                                                                                                                                                              |
| `provider_metadata`            | array of integer                                             | false    |              | Provider metadata holds provider-specific response metadata (e.g. Anthropic cache control hints) as raw JSON. Internal only: stripped by db2sdk before API responses.                                                                                              |
| `result`                       | array of integer                                             | false    |              |                                                                                                                                                                                                                                                                    |
| `result_delta`                 | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `signature`                    | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `skill_description`            | string                                                       | false    |              | Skill description is the short description from the skill's SKILL.md frontmatter.                                                                                                                                                                                  |
| `skill_dir`                    | string                                                       | false    |              | Skill dir is the absolute path to the skill directory inside the workspace filesystem. Internal only: used by read_skill/read_skill_file tools to locate skill files.                                                                                              |
| `skill_name`                   | string                                                       | false    |              | Skill name is the kebab-case name of a discovered skill from the workspace's .agents/skills/ directory.                                                                                                                                                            |
| `source_id`                    | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `start_line`                   | integer                                                      | false    |              |                                                                                                                                                                                                                                                                    |
| `text`                         | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `title`                        | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `tool_call_id`                 | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `tool_name`                    | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |
| `type`                         | [codersdk.ChatMessagePartType](#codersdkchatmessageparttype) | false    |              |                                                                                                                                                                                                                                                                    |
| `url`                          | string                                                       | false    |              |                                                                                                                                                                                                                                                                    |

## codersdk.ChatMessagePartType

```json
"text"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                     |
|--------------------------------------------------------------------------------------------------------------|
| `context-file`, `file`, `file-reference`, `reasoning`, `skill`, `source`, `text`, `tool-call`, `tool-result` |

## codersdk.ChatMessageRole

```json
"system"
```

### Properties

#### Enumerated Values

| Value(s)                              |
|---------------------------------------|
| `assistant`, `system`, `tool`, `user` |

## codersdk.ChatMessageUsage

```json
{
  "cache_creation_tokens": 0,
  "cache_read_tokens": 0,
  "context_limit": 0,
  "input_tokens": 0,
  "output_tokens": 0,
  "reasoning_tokens": 0,
  "total_tokens": 0
}
```

### Properties

| Name                    | Type    | Required | Restrictions | Description |
|-------------------------|---------|----------|--------------|-------------|
| `cache_creation_tokens` | integer | false    |              |             |
| `cache_read_tokens`     | integer | false    |              |             |
| `context_limit`         | integer | false    |              |             |
| `input_tokens`          | integer | false    |              |             |
| `output_tokens`         | integer | false    |              |             |
| `reasoning_tokens`      | integer | false    |              |             |
| `total_tokens`          | integer | false    |              |             |

## codersdk.ChatMessagesResponse

```json
{
  "has_more": true,
  "messages": [
    {
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "content": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
      "id": 0,
      "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
      "role": "system",
      "usage": {
        "cache_creation_tokens": 0,
        "cache_read_tokens": 0,
        "context_limit": 0,
        "input_tokens": 0,
        "output_tokens": 0,
        "reasoning_tokens": 0,
        "total_tokens": 0
      }
    }
  ],
  "queued_messages": [
    {
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "content": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "id": 0,
      "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205"
    }
  ]
}
```

### Properties

| Name              | Type                                                              | Required | Restrictions | Description |
|-------------------|-------------------------------------------------------------------|----------|--------------|-------------|
| `has_more`        | boolean                                                           | false    |              |             |
| `messages`        | array of [codersdk.ChatMessage](#codersdkchatmessage)             | false    |              |             |
| `queued_messages` | array of [codersdk.ChatQueuedMessage](#codersdkchatqueuedmessage) | false    |              |             |

## codersdk.ChatModel

```json
{
  "display_name": "string",
  "id": "string",
  "model": "string",
  "provider": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `display_name` | string | false    |              |             |
| `id`           | string | false    |              |             |
| `model`        | string | false    |              |             |
| `provider`     | string | false    |              |             |

## codersdk.ChatModelProvider

```json
{
  "available": true,
  "models": [
    {
      "display_name": "string",
      "id": "string",
      "model": "string",
      "provider": "string"
    }
  ],
  "provider": "string",
  "unavailable_reason": "missing_api_key"
}
```

### Properties

| Name                 | Type                                                                                       | Required | Restrictions | Description |
|----------------------|--------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `available`          | boolean                                                                                    | false    |              |             |
| `models`             | array of [codersdk.ChatModel](#codersdkchatmodel)                                          | false    |              |             |
| `provider`           | string                                                                                     | false    |              |             |
| `unavailable_reason` | [codersdk.ChatModelProviderUnavailableReason](#codersdkchatmodelproviderunavailablereason) | false    |              |             |

## codersdk.ChatModelProviderUnavailableReason

```json
"missing_api_key"
```

### Properties

#### Enumerated Values

| Value(s)                                                   |
|------------------------------------------------------------|
| `fetch_failed`, `missing_api_key`, `user_api_key_required` |

## codersdk.ChatModelsResponse

```json
{
  "providers": [
    {
      "available": true,
      "models": [
        {
          "display_name": "string",
          "id": "string",
          "model": "string",
          "provider": "string"
        }
      ],
      "provider": "string",
      "unavailable_reason": "missing_api_key"
    }
  ]
}
```

### Properties

| Name        | Type                                                              | Required | Restrictions | Description |
|-------------|-------------------------------------------------------------------|----------|--------------|-------------|
| `providers` | array of [codersdk.ChatModelProvider](#codersdkchatmodelprovider) | false    |              |             |

## codersdk.ChatPlanMode

```json
"plan"
```

### Properties

#### Enumerated Values

| Value(s) |
|----------|
| `plan`   |

## codersdk.ChatQueuedMessage

```json
{
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "content": [
    {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    }
  ],
  "created_at": "2019-08-24T14:15:22Z",
  "id": 0,
  "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205"
}
```

### Properties

| Name              | Type                                                          | Required | Restrictions | Description |
|-------------------|---------------------------------------------------------------|----------|--------------|-------------|
| `chat_id`         | string                                                        | false    |              |             |
| `content`         | array of [codersdk.ChatMessagePart](#codersdkchatmessagepart) | false    |              |             |
| `created_at`      | string                                                        | false    |              |             |
| `id`              | integer                                                       | false    |              |             |
| `model_config_id` | string                                                        | false    |              |             |

## codersdk.ChatRetentionDaysResponse

```json
{
  "retention_days": 0
}
```

### Properties

| Name             | Type    | Required | Restrictions | Description |
|------------------|---------|----------|--------------|-------------|
| `retention_days` | integer | false    |              |             |

## codersdk.ChatStatus

```json
"waiting"
```

### Properties

#### Enumerated Values

| Value(s)                                                                           |
|------------------------------------------------------------------------------------|
| `completed`, `error`, `paused`, `pending`, `requires_action`, `running`, `waiting` |

## codersdk.ChatStreamActionRequired

```json
{
  "tool_calls": [
    {
      "args": "string",
      "tool_call_id": "string",
      "tool_name": "string"
    }
  ]
}
```

### Properties

| Name         | Type                                                                | Required | Restrictions | Description |
|--------------|---------------------------------------------------------------------|----------|--------------|-------------|
| `tool_calls` | array of [codersdk.ChatStreamToolCall](#codersdkchatstreamtoolcall) | false    |              |             |

## codersdk.ChatStreamEvent

```json
{
  "action_required": {
    "tool_calls": [
      {
        "args": "string",
        "tool_call_id": "string",
        "tool_name": "string"
      }
    ]
  },
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "error": {
    "detail": "string",
    "kind": "generic",
    "message": "string",
    "provider": "string",
    "retryable": true,
    "status_code": 0
  },
  "message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
    "role": "system",
    "usage": {
      "cache_creation_tokens": 0,
      "cache_read_tokens": 0,
      "context_limit": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "reasoning_tokens": 0,
      "total_tokens": 0
    }
  },
  "message_part": {
    "part": {
      "args": [
        0
      ],
      "args_delta": "string",
      "content": "string",
      "context_file_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "context_file_content": "string",
      "context_file_directory": "string",
      "context_file_os": "string",
      "context_file_path": "string",
      "context_file_skill_meta_file": "string",
      "context_file_truncated": true,
      "created_at": "2019-08-24T14:15:22Z",
      "data": [
        0
      ],
      "end_line": 0,
      "file_id": {
        "uuid": "string",
        "valid": true
      },
      "file_name": "string",
      "is_error": true,
      "is_media": true,
      "mcp_server_config_id": {
        "uuid": "string",
        "valid": true
      },
      "media_type": "string",
      "name": "string",
      "provider_executed": true,
      "provider_metadata": [
        0
      ],
      "result": [
        0
      ],
      "result_delta": "string",
      "signature": "string",
      "skill_description": "string",
      "skill_dir": "string",
      "skill_name": "string",
      "source_id": "string",
      "start_line": 0,
      "text": "string",
      "title": "string",
      "tool_call_id": "string",
      "tool_name": "string",
      "type": "text",
      "url": "string"
    },
    "role": "system"
  },
  "queued_messages": [
    {
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "content": [
        {
          "args": [
            0
          ],
          "args_delta": "string",
          "content": "string",
          "context_file_agent_id": {
            "uuid": "string",
            "valid": true
          },
          "context_file_content": "string",
          "context_file_directory": "string",
          "context_file_os": "string",
          "context_file_path": "string",
          "context_file_skill_meta_file": "string",
          "context_file_truncated": true,
          "created_at": "2019-08-24T14:15:22Z",
          "data": [
            0
          ],
          "end_line": 0,
          "file_id": {
            "uuid": "string",
            "valid": true
          },
          "file_name": "string",
          "is_error": true,
          "is_media": true,
          "mcp_server_config_id": {
            "uuid": "string",
            "valid": true
          },
          "media_type": "string",
          "name": "string",
          "provider_executed": true,
          "provider_metadata": [
            0
          ],
          "result": [
            0
          ],
          "result_delta": "string",
          "signature": "string",
          "skill_description": "string",
          "skill_dir": "string",
          "skill_name": "string",
          "source_id": "string",
          "start_line": 0,
          "text": "string",
          "title": "string",
          "tool_call_id": "string",
          "tool_name": "string",
          "type": "text",
          "url": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "id": 0,
      "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205"
    }
  ],
  "retry": {
    "attempt": 0,
    "delay_ms": 0,
    "error": "string",
    "kind": "generic",
    "provider": "string",
    "retrying_at": "2019-08-24T14:15:22Z",
    "status_code": 0
  },
  "status": {
    "status": "waiting"
  },
  "type": "message_part"
}
```

### Properties

| Name              | Type                                                                   | Required | Restrictions | Description |
|-------------------|------------------------------------------------------------------------|----------|--------------|-------------|
| `action_required` | [codersdk.ChatStreamActionRequired](#codersdkchatstreamactionrequired) | false    |              |             |
| `chat_id`         | string                                                                 | false    |              |             |
| `error`           | [codersdk.ChatError](#codersdkchaterror)                               | false    |              |             |
| `message`         | [codersdk.ChatMessage](#codersdkchatmessage)                           | false    |              |             |
| `message_part`    | [codersdk.ChatStreamMessagePart](#codersdkchatstreammessagepart)       | false    |              |             |
| `queued_messages` | array of [codersdk.ChatQueuedMessage](#codersdkchatqueuedmessage)      | false    |              |             |
| `retry`           | [codersdk.ChatStreamRetry](#codersdkchatstreamretry)                   | false    |              |             |
| `status`          | [codersdk.ChatStreamStatus](#codersdkchatstreamstatus)                 | false    |              |             |
| `type`            | [codersdk.ChatStreamEventType](#codersdkchatstreameventtype)           | false    |              |             |

## codersdk.ChatStreamEventType

```json
"message_part"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                 |
|------------------------------------------------------------------------------------------|
| `action_required`, `error`, `message`, `message_part`, `queue_update`, `retry`, `status` |

## codersdk.ChatStreamMessagePart

```json
{
  "part": {
    "args": [
      0
    ],
    "args_delta": "string",
    "content": "string",
    "context_file_agent_id": {
      "uuid": "string",
      "valid": true
    },
    "context_file_content": "string",
    "context_file_directory": "string",
    "context_file_os": "string",
    "context_file_path": "string",
    "context_file_skill_meta_file": "string",
    "context_file_truncated": true,
    "created_at": "2019-08-24T14:15:22Z",
    "data": [
      0
    ],
    "end_line": 0,
    "file_id": {
      "uuid": "string",
      "valid": true
    },
    "file_name": "string",
    "is_error": true,
    "is_media": true,
    "mcp_server_config_id": {
      "uuid": "string",
      "valid": true
    },
    "media_type": "string",
    "name": "string",
    "provider_executed": true,
    "provider_metadata": [
      0
    ],
    "result": [
      0
    ],
    "result_delta": "string",
    "signature": "string",
    "skill_description": "string",
    "skill_dir": "string",
    "skill_name": "string",
    "source_id": "string",
    "start_line": 0,
    "text": "string",
    "title": "string",
    "tool_call_id": "string",
    "tool_name": "string",
    "type": "text",
    "url": "string"
  },
  "role": "system"
}
```

### Properties

| Name   | Type                                                 | Required | Restrictions | Description |
|--------|------------------------------------------------------|----------|--------------|-------------|
| `part` | [codersdk.ChatMessagePart](#codersdkchatmessagepart) | false    |              |             |
| `role` | [codersdk.ChatMessageRole](#codersdkchatmessagerole) | false    |              |             |

## codersdk.ChatStreamRetry

```json
{
  "attempt": 0,
  "delay_ms": 0,
  "error": "string",
  "kind": "generic",
  "provider": "string",
  "retrying_at": "2019-08-24T14:15:22Z",
  "status_code": 0
}
```

### Properties

| Name          | Type                                             | Required | Restrictions | Description                                                       |
|---------------|--------------------------------------------------|----------|--------------|-------------------------------------------------------------------|
| `attempt`     | integer                                          | false    |              | Attempt is the 1-indexed retry attempt number.                    |
| `delay_ms`    | integer                                          | false    |              | Delay ms is the backoff delay in milliseconds before the retry.   |
| `error`       | string                                           | false    |              | Error is the normalized error message from the failed attempt.    |
| `kind`        | [codersdk.ChatErrorKind](#codersdkchaterrorkind) | false    |              | Kind classifies the retry reason for consistent client rendering. |
| `provider`    | string                                           | false    |              | Provider identifies the upstream model provider when known.       |
| `retrying_at` | string                                           | false    |              | Retrying at is the timestamp when the retry will be attempted.    |
| `status_code` | integer                                          | false    |              | Status code is the best-effort upstream HTTP status code.         |

## codersdk.ChatStreamStatus

```json
{
  "status": "waiting"
}
```

### Properties

| Name     | Type                                       | Required | Restrictions | Description |
|----------|--------------------------------------------|----------|--------------|-------------|
| `status` | [codersdk.ChatStatus](#codersdkchatstatus) | false    |              |             |

## codersdk.ChatStreamToolCall

```json
{
  "args": "string",
  "tool_call_id": "string",
  "tool_name": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `args`         | string | false    |              |             |
| `tool_call_id` | string | false    |              |             |
| `tool_name`    | string | false    |              |             |

## codersdk.ChatWatchEvent

```json
{
  "chat": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "archived": true,
    "build_id": "bfb1f3fa-bf7b-43a5-9e0b-26cc050e44cb",
    "children": [
      {}
    ],
    "client_type": "ui",
    "created_at": "2019-08-24T14:15:22Z",
    "diff_status": {
      "additions": 0,
      "approved": true,
      "author_avatar_url": "string",
      "author_login": "string",
      "base_branch": "string",
      "changed_files": 0,
      "changes_requested": true,
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "commits": 0,
      "deletions": 0,
      "head_branch": "string",
      "pr_number": 0,
      "pull_request_draft": true,
      "pull_request_state": "string",
      "pull_request_title": "string",
      "refreshed_at": "2019-08-24T14:15:22Z",
      "reviewer_count": 0,
      "stale_at": "2019-08-24T14:15:22Z",
      "url": "string"
    },
    "files": [
      {
        "created_at": "2019-08-24T14:15:22Z",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "mime_type": "string",
        "name": "string",
        "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
        "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
      }
    ],
    "has_unread": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "labels": {
      "property1": "string",
      "property2": "string"
    },
    "last_error": {
      "detail": "string",
      "kind": "generic",
      "message": "string",
      "provider": "string",
      "retryable": true,
      "status_code": 0
    },
    "last_injected_context": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "last_model_config_id": "30ebb95f-c255-4759-9429-89aa4ec1554c",
    "last_turn_summary": "string",
    "mcp_server_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
    "parent_chat_id": "c3609ee6-3b11-4a93-b9ae-e4fabcc99359",
    "pin_order": 0,
    "plan_mode": "plan",
    "root_chat_id": "2898031c-fdce-4e3e-8c53-4481dd42fcd7",
    "status": "waiting",
    "title": "string",
    "updated_at": "2019-08-24T14:15:22Z",
    "warnings": [
      "string"
    ],
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "kind": "status_change",
  "tool_calls": [
    {
      "args": "string",
      "tool_call_id": "string",
      "tool_name": "string"
    }
  ]
}
```

### Properties

| Name         | Type                                                                | Required | Restrictions | Description |
|--------------|---------------------------------------------------------------------|----------|--------------|-------------|
| `chat`       | [codersdk.Chat](#codersdkchat)                                      | false    |              |             |
| `kind`       | [codersdk.ChatWatchEventKind](#codersdkchatwatcheventkind)          | false    |              |             |
| `tool_calls` | array of [codersdk.ChatStreamToolCall](#codersdkchatstreamtoolcall) | false    |              |             |

## codersdk.ChatWatchEventKind

```json
"status_change"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                         |
|------------------------------------------------------------------------------------------------------------------|
| `action_required`, `created`, `deleted`, `diff_status_change`, `status_change`, `summary_change`, `title_change` |

## codersdk.ConnectionLatency

```json
{
  "p50": 31.312,
  "p95": 119.832
}
```

### Properties

| Name  | Type   | Required | Restrictions | Description |
|-------|--------|----------|--------------|-------------|
| `p50` | number | false    |              |             |
| `p95` | number | false    |              |             |

## codersdk.ConnectionLog

```json
{
  "agent_name": "string",
  "connect_time": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "ip": "string",
  "organization": {
    "display_name": "string",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string"
  },
  "ssh_info": {
    "connection_id": "d3547de1-d1f2-4344-b4c2-17169b7526f9",
    "disconnect_reason": "string",
    "disconnect_time": "2019-08-24T14:15:22Z",
    "exit_code": 0
  },
  "type": "ssh",
  "web_info": {
    "slug_or_port": "string",
    "status_code": 0,
    "user": {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "has_ai_seat": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "organization_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "roles": [
        {
          "display_name": "string",
          "name": "string",
          "organization_id": "string"
        }
      ],
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    },
    "user_agent": "string"
  },
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
  "workspace_name": "string",
  "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
  "workspace_owner_username": "string"
}
```

### Properties

| Name                       | Type                                                           | Required | Restrictions | Description                                                                                                                                              |
|----------------------------|----------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| `agent_name`               | string                                                         | false    |              |                                                                                                                                                          |
| `connect_time`             | string                                                         | false    |              |                                                                                                                                                          |
| `id`                       | string                                                         | false    |              |                                                                                                                                                          |
| `ip`                       | string                                                         | false    |              |                                                                                                                                                          |
| `organization`             | [codersdk.MinimalOrganization](#codersdkminimalorganization)   | false    |              |                                                                                                                                                          |
| `ssh_info`                 | [codersdk.ConnectionLogSSHInfo](#codersdkconnectionlogsshinfo) | false    |              | Ssh info is only set when `type` is one of: - `ConnectionTypeSSH` - `ConnectionTypeReconnectingPTY` - `ConnectionTypeVSCode` - `ConnectionTypeJetBrains` |
| `type`                     | [codersdk.ConnectionType](#codersdkconnectiontype)             | false    |              |                                                                                                                                                          |
| `web_info`                 | [codersdk.ConnectionLogWebInfo](#codersdkconnectionlogwebinfo) | false    |              | Web info is only set when `type` is one of: - `ConnectionTypePortForwarding` - `ConnectionTypeWorkspaceApp`                                              |
| `workspace_id`             | string                                                         | false    |              |                                                                                                                                                          |
| `workspace_name`           | string                                                         | false    |              |                                                                                                                                                          |
| `workspace_owner_id`       | string                                                         | false    |              |                                                                                                                                                          |
| `workspace_owner_username` | string                                                         | false    |              |                                                                                                                                                          |

## codersdk.ConnectionLogResponse

```json
{
  "connection_logs": [
    {
      "agent_name": "string",
      "connect_time": "2019-08-24T14:15:22Z",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "ip": "string",
      "organization": {
        "display_name": "string",
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string"
      },
      "ssh_info": {
        "connection_id": "d3547de1-d1f2-4344-b4c2-17169b7526f9",
        "disconnect_reason": "string",
        "disconnect_time": "2019-08-24T14:15:22Z",
        "exit_code": 0
      },
      "type": "ssh",
      "web_info": {
        "slug_or_port": "string",
        "status_code": 0,
        "user": {
          "avatar_url": "http://example.com",
          "created_at": "2019-08-24T14:15:22Z",
          "email": "user@example.com",
          "has_ai_seat": true,
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "is_service_account": true,
          "last_seen_at": "2019-08-24T14:15:22Z",
          "login_type": "",
          "name": "string",
          "organization_ids": [
            "497f6eca-6276-4993-bfeb-53cbbbba6f08"
          ],
          "roles": [
            {
              "display_name": "string",
              "name": "string",
              "organization_id": "string"
            }
          ],
          "status": "active",
          "theme_preference": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "username": "string"
        },
        "user_agent": "string"
      },
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string",
      "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
      "workspace_owner_username": "string"
    }
  ],
  "count": 0,
  "count_cap": 0
}
```

### Properties

| Name              | Type                                                      | Required | Restrictions | Description |
|-------------------|-----------------------------------------------------------|----------|--------------|-------------|
| `connection_logs` | array of [codersdk.ConnectionLog](#codersdkconnectionlog) | false    |              |             |
| `count`           | integer                                                   | false    |              |             |
| `count_cap`       | integer                                                   | false    |              |             |

## codersdk.ConnectionLogSSHInfo

```json
{
  "connection_id": "d3547de1-d1f2-4344-b4c2-17169b7526f9",
  "disconnect_reason": "string",
  "disconnect_time": "2019-08-24T14:15:22Z",
  "exit_code": 0
}
```

### Properties

| Name                | Type    | Required | Restrictions | Description                                                                                                                           |
|---------------------|---------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------|
| `connection_id`     | string  | false    |              |                                                                                                                                       |
| `disconnect_reason` | string  | false    |              | Disconnect reason is omitted if a disconnect event with the same connection ID has not yet been seen.                                 |
| `disconnect_time`   | string  | false    |              | Disconnect time is omitted if a disconnect event with the same connection ID has not yet been seen.                                   |
| `exit_code`         | integer | false    |              | Exit code is the exit code of the SSH session. It is omitted if a disconnect event with the same connection ID has not yet been seen. |

## codersdk.ConnectionLogWebInfo

```json
{
  "slug_or_port": "string",
  "status_code": 0,
  "user": {
    "avatar_url": "http://example.com",
    "created_at": "2019-08-24T14:15:22Z",
    "email": "user@example.com",
    "has_ai_seat": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "is_service_account": true,
    "last_seen_at": "2019-08-24T14:15:22Z",
    "login_type": "",
    "name": "string",
    "organization_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "roles": [
      {
        "display_name": "string",
        "name": "string",
        "organization_id": "string"
      }
    ],
    "status": "active",
    "theme_preference": "string",
    "updated_at": "2019-08-24T14:15:22Z",
    "username": "string"
  },
  "user_agent": "string"
}
```

### Properties

| Name           | Type                           | Required | Restrictions | Description                                                               |
|----------------|--------------------------------|----------|--------------|---------------------------------------------------------------------------|
| `slug_or_port` | string                         | false    |              |                                                                           |
| `status_code`  | integer                        | false    |              | Status code is the HTTP status code of the request.                       |
| `user`         | [codersdk.User](#codersdkuser) | false    |              | User is omitted if the connection event was from an unauthenticated user. |
| `user_agent`   | string                         | false    |              |                                                                           |

## codersdk.ConnectionType

```json
"ssh"
```

### Properties

#### Enumerated Values

| Value(s)                                                                             |
|--------------------------------------------------------------------------------------|
| `jetbrains`, `port_forwarding`, `reconnecting_pty`, `ssh`, `vscode`, `workspace_app` |

## codersdk.ConvertLoginRequest

```json
{
  "password": "string",
  "to_type": ""
}
```

### Properties

| Name       | Type                                     | Required | Restrictions | Description                              |
|------------|------------------------------------------|----------|--------------|------------------------------------------|
| `password` | string                                   | true     |              |                                          |
| `to_type`  | [codersdk.LoginType](#codersdklogintype) | true     |              | To type is the login type to convert to. |

## codersdk.CreateChatMessageRequest

```json
{
  "busy_behavior": "queue",
  "content": [
    {
      "content": "string",
      "end_line": 0,
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "file_name": "string",
      "start_line": 0,
      "text": "string",
      "type": "text"
    }
  ],
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
  "plan_mode": "plan"
}
```

### Properties

| Name              | Type                                                      | Required | Restrictions | Description                                                                                                  |
|-------------------|-----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------|
| `busy_behavior`   | [codersdk.ChatBusyBehavior](#codersdkchatbusybehavior)    | false    |              |                                                                                                              |
| `content`         | array of [codersdk.ChatInputPart](#codersdkchatinputpart) | false    |              |                                                                                                              |
| `mcp_server_ids`  | array of string                                           | false    |              |                                                                                                              |
| `model_config_id` | string                                                    | false    |              |                                                                                                              |
| `plan_mode`       | [codersdk.ChatPlanMode](#codersdkchatplanmode)            | false    |              | Plan mode switches the chat's persistent plan mode. nil: no change, ptr to "plan": enable, ptr to "": clear. |

#### Enumerated Values

| Property        | Value(s)             |
|-----------------|----------------------|
| `busy_behavior` | `interrupt`, `queue` |

## codersdk.CreateChatMessageResponse

```json
{
  "message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
    "role": "system",
    "usage": {
      "cache_creation_tokens": 0,
      "cache_read_tokens": 0,
      "context_limit": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "reasoning_tokens": 0,
      "total_tokens": 0
    }
  },
  "queued": true,
  "queued_message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205"
  },
  "warnings": [
    "string"
  ]
}
```

### Properties

| Name             | Type                                                     | Required | Restrictions | Description |
|------------------|----------------------------------------------------------|----------|--------------|-------------|
| `message`        | [codersdk.ChatMessage](#codersdkchatmessage)             | false    |              |             |
| `queued`         | boolean                                                  | false    |              |             |
| `queued_message` | [codersdk.ChatQueuedMessage](#codersdkchatqueuedmessage) | false    |              |             |
| `warnings`       | array of string                                          | false    |              |             |

## codersdk.CreateChatRequest

```json
{
  "client_type": "ui",
  "content": [
    {
      "content": "string",
      "end_line": 0,
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "file_name": "string",
      "start_line": 0,
      "text": "string",
      "type": "text"
    }
  ],
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "mcp_server_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "plan_mode": "plan",
  "system_prompt": "string",
  "unsafe_dynamic_tools": [
    {
      "description": "string",
      "input_schema": [
        0
      ],
      "name": "string"
    }
  ],
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Properties

| Name                   | Type                                                      | Required | Restrictions | Description                                                                                                                                |
|------------------------|-----------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `client_type`          | [codersdk.ChatClientType](#codersdkchatclienttype)        | false    |              |                                                                                                                                            |
| `content`              | array of [codersdk.ChatInputPart](#codersdkchatinputpart) | false    |              |                                                                                                                                            |
| `labels`               | object                                                    | false    |              |                                                                                                                                            |
| » `[any property]`     | string                                                    | false    |              |                                                                                                                                            |
| `mcp_server_ids`       | array of string                                           | false    |              |                                                                                                                                            |
| `model_config_id`      | string                                                    | false    |              |                                                                                                                                            |
| `organization_id`      | string                                                    | false    |              |                                                                                                                                            |
| `plan_mode`            | [codersdk.ChatPlanMode](#codersdkchatplanmode)            | false    |              |                                                                                                                                            |
| `system_prompt`        | string                                                    | false    |              |                                                                                                                                            |
| `unsafe_dynamic_tools` | array of [codersdk.DynamicTool](#codersdkdynamictool)     | false    |              | Unsafe dynamic tools declares client-executed tools that the LLM can invoke. This API is highly experimental and highly subject to change. |
| `workspace_id`         | string                                                    | false    |              |                                                                                                                                            |

## codersdk.CreateFirstUserOnboardingInfo

```json
{
  "newsletter_marketing": true,
  "newsletter_releases": true
}
```

### Properties

| Name                   | Type    | Required | Restrictions | Description |
|------------------------|---------|----------|--------------|-------------|
| `newsletter_marketing` | boolean | false    |              |             |
| `newsletter_releases`  | boolean | false    |              |             |

## codersdk.CreateFirstUserRequest

```json
{
  "email": "string",
  "name": "string",
  "onboarding_info": {
    "newsletter_marketing": true,
    "newsletter_releases": true
  },
  "password": "string",
  "trial": true,
  "trial_info": {
    "company_name": "string",
    "country": "string",
    "developers": "string",
    "first_name": "string",
    "job_title": "string",
    "last_name": "string",
    "phone_number": "string"
  },
  "username": "string"
}
```

### Properties

| Name              | Type                                                                             | Required | Restrictions | Description |
|-------------------|----------------------------------------------------------------------------------|----------|--------------|-------------|
| `email`           | string                                                                           | true     |              |             |
| `name`            | string                                                                           | false    |              |             |
| `onboarding_info` | [codersdk.CreateFirstUserOnboardingInfo](#codersdkcreatefirstuseronboardinginfo) | false    |              |             |
| `password`        | string                                                                           | true     |              |             |
| `trial`           | boolean                                                                          | false    |              |             |
| `trial_info`      | [codersdk.CreateFirstUserTrialInfo](#codersdkcreatefirstusertrialinfo)           | false    |              |             |
| `username`        | string                                                                           | true     |              |             |

## codersdk.CreateFirstUserResponse

```json
{
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Properties

| Name              | Type   | Required | Restrictions | Description |
|-------------------|--------|----------|--------------|-------------|
| `organization_id` | string | false    |              |             |
| `user_id`         | string | false    |              |             |

## codersdk.CreateFirstUserTrialInfo

```json
{
  "company_name": "string",
  "country": "string",
  "developers": "string",
  "first_name": "string",
  "job_title": "string",
  "last_name": "string",
  "phone_number": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `company_name` | string | false    |              |             |
| `country`      | string | false    |              |             |
| `developers`   | string | false    |              |             |
| `first_name`   | string | false    |              |             |
| `job_title`    | string | false    |              |             |
| `last_name`    | string | false    |              |             |
| `phone_number` | string | false    |              |             |

## codersdk.CreateGroupRequest

```json
{
  "avatar_url": "string",
  "display_name": "string",
  "name": "string",
  "quota_allowance": 0
}
```

### Properties

| Name              | Type    | Required | Restrictions | Description |
|-------------------|---------|----------|--------------|-------------|
| `avatar_url`      | string  | false    |              |             |
| `display_name`    | string  | false    |              |             |
| `name`            | string  | true     |              |             |
| `quota_allowance` | integer | false    |              |             |

## codersdk.CreateOrganizationRequest

```json
{
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "name": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description                                                            |
|----------------|--------|----------|--------------|------------------------------------------------------------------------|
| `description`  | string | false    |              |                                                                        |
| `display_name` | string | false    |              | Display name will default to the same value as `Name` if not provided. |
| `icon`         | string | false    |              |                                                                        |
| `name`         | string | true     |              |                                                                        |

## codersdk.CreateProvisionerKeyResponse

```json
{
  "key": "string"
}
```

### Properties

| Name  | Type   | Required | Restrictions | Description |
|-------|--------|----------|--------------|-------------|
| `key` | string | false    |              |             |

## codersdk.CreateTaskRequest

```json
{
  "display_name": "string",
  "input": "string",
  "name": "string",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1"
}
```

### Properties

| Name                         | Type   | Required | Restrictions | Description |
|------------------------------|--------|----------|--------------|-------------|
| `display_name`               | string | false    |              |             |
| `input`                      | string | false    |              |             |
| `name`                       | string | false    |              |             |
| `template_version_id`        | string | false    |              |             |
| `template_version_preset_id` | string | false    |              |             |

## codersdk.CreateTemplateRequest

```json
{
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "cors_behavior": "simple",
  "default_ttl_ms": 0,
  "delete_ttl_ms": 0,
  "description": "string",
  "disable_everyone_group_access": true,
  "display_name": "string",
  "dormant_ttl_ms": 0,
  "failure_ttl_ms": 0,
  "icon": "string",
  "max_port_share_level": "owner",
  "name": "string",
  "require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1"
}
```

### Properties

| Name                                  | Type                                                                           | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                         |
|---------------------------------------|--------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `activity_bump_ms`                    | integer                                                                        | false    |              | Activity bump ms allows optionally specifying the activity bump duration for all workspaces created from this template. Defaults to 1h but can be set to 0 to disable activity bumping.                                                                                                                             |
| `allow_user_autostart`                | boolean                                                                        | false    |              | Allow user autostart allows users to set a schedule for autostarting their workspace. By default this is true. This can only be disabled when using an enterprise license.                                                                                                                                          |
| `allow_user_autostop`                 | boolean                                                                        | false    |              | Allow user autostop allows users to set a custom workspace TTL to use in place of the template's DefaultTTL field. By default this is true. If false, the DefaultTTL will always be used. This can only be disabled when using an enterprise license.                                                               |
| `allow_user_cancel_workspace_jobs`    | boolean                                                                        | false    |              | Allow users to cancel in-progress workspace jobs. *bool as the default value is "true".                                                                                                                                                                                                                             |
| `autostart_requirement`               | [codersdk.TemplateAutostartRequirement](#codersdktemplateautostartrequirement) | false    |              | Autostart requirement allows optionally specifying the autostart allowed days for workspaces created from this template. This is an enterprise feature.                                                                                                                                                             |
| `autostop_requirement`                | [codersdk.TemplateAutostopRequirement](#codersdktemplateautostoprequirement)   | false    |              | Autostop requirement allows optionally specifying the autostop requirement for workspaces created from this template. This is an enterprise feature.                                                                                                                                                                |
| `cors_behavior`                       | [codersdk.CORSBehavior](#codersdkcorsbehavior)                                 | false    |              | Cors behavior allows optionally specifying the CORS behavior for all shared ports.                                                                                                                                                                                                                                  |
| `default_ttl_ms`                      | integer                                                                        | false    |              | Default ttl ms allows optionally specifying the default TTL for all workspaces created from this template.                                                                                                                                                                                                          |
| `delete_ttl_ms`                       | integer                                                                        | false    |              | Delete ttl ms allows optionally specifying the max lifetime before Coder permanently deletes dormant workspaces created from this template.                                                                                                                                                                         |
| `description`                         | string                                                                         | false    |              | Description is a description of what the template contains. It must be less than 128 bytes.                                                                                                                                                                                                                         |
| `disable_everyone_group_access`       | boolean                                                                        | false    |              | Disable everyone group access allows optionally disabling the default behavior of granting the 'everyone' group access to use the template. If this is set to true, the template will not be available to all users, and must be explicitly granted to users or groups in the permissions settings of the template. |
| `display_name`                        | string                                                                         | false    |              | Display name is the displayed name of the template.                                                                                                                                                                                                                                                                 |
| `dormant_ttl_ms`                      | integer                                                                        | false    |              | Dormant ttl ms allows optionally specifying the max lifetime before Coder locks inactive workspaces created from this template.                                                                                                                                                                                     |
| `failure_ttl_ms`                      | integer                                                                        | false    |              | Failure ttl ms allows optionally specifying the max lifetime before Coder stops all resources for failed workspaces created from this template.                                                                                                                                                                     |
| `icon`                                | string                                                                         | false    |              | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard.                                                                                                                                                                                                                    |
| `max_port_share_level`                | [codersdk.WorkspaceAgentPortShareLevel](#codersdkworkspaceagentportsharelevel) | false    |              | Max port share level allows optionally specifying the maximum port share level for workspaces created from the template.                                                                                                                                                                                            |
| `name`                                | string                                                                         | true     |              | Name is the name of the template.                                                                                                                                                                                                                                                                                   |
| `require_active_version`              | boolean                                                                        | false    |              | Require active version mandates that workspaces are built with the active template version.                                                                                                                                                                                                                         |
| `template_use_classic_parameter_flow` | boolean                                                                        | false    |              | Template use classic parameter flow allows optionally specifying whether the template should use the classic parameter flow. The default if unset is true, and is why `*bool` is used here. When dynamic parameters becomes the default, this will default to false.                                                |
|`template_version_id`|string|true||Template version ID is an in-progress or completed job to use as an initial version of the template.
This is required on creation to enable a user-flow of validating a template works. There is no reason the data-model cannot support empty templates, but it doesn't make sense for users.|

## codersdk.CreateTemplateVersionDryRunRequest

```json
{
  "rich_parameter_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "user_variable_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "workspace_name": "string"
}
```

### Properties

| Name                    | Type                                                                          | Required | Restrictions | Description |
|-------------------------|-------------------------------------------------------------------------------|----------|--------------|-------------|
| `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false    |              |             |
| `user_variable_values`  | array of [codersdk.VariableValue](#codersdkvariablevalue)                     | false    |              |             |
| `workspace_name`        | string                                                                        | false    |              |             |

## codersdk.CreateTemplateVersionRequest

```json
{
  "example_id": "string",
  "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
  "message": "string",
  "name": "string",
  "provisioner": "terraform",
  "storage_method": "file",
  "tags": {
    "property1": "string",
    "property2": "string"
  },
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "user_variable_values": [
    {
      "name": "string",
      "value": "string"
    }
  ]
}
```

### Properties

| Name                   | Type                                                                   | Required | Restrictions | Description                                                  |
|------------------------|------------------------------------------------------------------------|----------|--------------|--------------------------------------------------------------|
| `example_id`           | string                                                                 | false    |              |                                                              |
| `file_id`              | string                                                                 | false    |              |                                                              |
| `message`              | string                                                                 | false    |              |                                                              |
| `name`                 | string                                                                 | false    |              |                                                              |
| `provisioner`          | string                                                                 | true     |              |                                                              |
| `storage_method`       | [codersdk.ProvisionerStorageMethod](#codersdkprovisionerstoragemethod) | true     |              |                                                              |
| `tags`                 | object                                                                 | false    |              |                                                              |
| » `[any property]`     | string                                                                 | false    |              |                                                              |
| `template_id`          | string                                                                 | false    |              | Template ID optionally associates a version with a template. |
| `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue)              | false    |              |                                                              |

#### Enumerated Values

| Property         | Value(s)            |
|------------------|---------------------|
| `provisioner`    | `echo`, `terraform` |
| `storage_method` | `file`              |

## codersdk.CreateTestAuditLogRequest

```json
{
  "action": "create",
  "additional_fields": [
    0
  ],
  "build_reason": "autostart",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "request_id": "266ea41d-adf5-480b-af50-15b940c2b846",
  "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  "resource_type": "template",
  "time": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name                | Type                                           | Required | Restrictions | Description |
|---------------------|------------------------------------------------|----------|--------------|-------------|
| `action`            | [codersdk.AuditAction](#codersdkauditaction)   | false    |              |             |
| `additional_fields` | array of integer                               | false    |              |             |
| `build_reason`      | [codersdk.BuildReason](#codersdkbuildreason)   | false    |              |             |
| `organization_id`   | string                                         | false    |              |             |
| `request_id`        | string                                         | false    |              |             |
| `resource_id`       | string                                         | false    |              |             |
| `resource_type`     | [codersdk.ResourceType](#codersdkresourcetype) | false    |              |             |
| `time`              | string                                         | false    |              |             |

#### Enumerated Values

| Property        | Value(s)                                                                                                 |
|-----------------|----------------------------------------------------------------------------------------------------------|
| `action`        | `create`, `delete`, `start`, `stop`, `write`                                                             |
| `build_reason`  | `autostart`, `autostop`, `initiator`                                                                     |
| `resource_type` | `auditable_group`, `git_ssh_key`, `template`, `template_version`, `user`, `workspace`, `workspace_build` |

## codersdk.CreateTokenRequest

```json
{
  "allow_list": [
    {
      "id": "string",
      "type": "*"
    }
  ],
  "lifetime": 0,
  "scope": "all",
  "scopes": [
    "all"
  ],
  "token_name": "string"
}
```

### Properties

| Name         | Type                                                                | Required | Restrictions | Description                     |
|--------------|---------------------------------------------------------------------|----------|--------------|---------------------------------|
| `allow_list` | array of [codersdk.APIAllowListTarget](#codersdkapiallowlisttarget) | false    |              |                                 |
| `lifetime`   | integer                                                             | false    |              |                                 |
| `scope`      | [codersdk.APIKeyScope](#codersdkapikeyscope)                        | false    |              | Deprecated: use Scopes instead. |
| `scopes`     | array of [codersdk.APIKeyScope](#codersdkapikeyscope)               | false    |              |                                 |
| `token_name` | string                                                              | false    |              |                                 |

## codersdk.CreateUserRequestWithOrgs

```json
{
  "email": "user@example.com",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "password": "string",
  "roles": [
    "string"
  ],
  "service_account": true,
  "user_status": "active",
  "username": "string"
}
```

### Properties

| Name               | Type                                       | Required | Restrictions | Description                                                                         |
|--------------------|--------------------------------------------|----------|--------------|-------------------------------------------------------------------------------------|
| `email`            | string                                     | false    |              |                                                                                     |
| `login_type`       | [codersdk.LoginType](#codersdklogintype)   | false    |              | Login type defaults to LoginTypePassword.                                           |
| `name`             | string                                     | false    |              |                                                                                     |
| `organization_ids` | array of string                            | false    |              | Organization ids is a list of organization IDs that the user should be a member of. |
| `password`         | string                                     | false    |              |                                                                                     |
| `roles`            | array of string                            | false    |              | Roles is an optional list of site-level roles to assign at creation.                |
| `service_account`  | boolean                                    | false    |              | Service accounts are admin-managed accounts that cannot login.                      |
| `user_status`      | [codersdk.UserStatus](#codersdkuserstatus) | false    |              | User status defaults to UserStatusDormant.                                          |
| `username`         | string                                     | true     |              |                                                                                     |

## codersdk.CreateUserSecretRequest

```json
{
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "name": "string",
  "value": "string"
}
```

### Properties

| Name          | Type   | Required | Restrictions | Description |
|---------------|--------|----------|--------------|-------------|
| `description` | string | false    |              |             |
| `env_name`    | string | false    |              |             |
| `file_path`   | string | false    |              |             |
| `name`        | string | false    |              |             |
| `value`       | string | false    |              |             |

## codersdk.CreateWorkspaceBuildReason

```json
"dashboard"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                              |
|-----------------------------------------------------------------------------------------------------------------------|
| `cli`, `dashboard`, `jetbrains_connection`, `ssh_connection`, `task_manual_pause`, `task_resume`, `vscode_connection` |

## codersdk.CreateWorkspaceBuildRequest

```json
{
  "dry_run": true,
  "log_level": "debug",
  "orphan": true,
  "reason": "dashboard",
  "rich_parameter_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "state": [
    0
  ],
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "transition": "start"
}
```

### Properties

| Name                         | Type                                                                          | Required | Restrictions | Description                                                                                                                                                                                                   |
|------------------------------|-------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `dry_run`                    | boolean                                                                       | false    |              |                                                                                                                                                                                                               |
| `log_level`                  | [codersdk.ProvisionerLogLevel](#codersdkprovisionerloglevel)                  | false    |              | Log level changes the default logging verbosity of a provider ("info" if empty).                                                                                                                              |
| `orphan`                     | boolean                                                                       | false    |              | Orphan may be set for the Destroy transition.                                                                                                                                                                 |
| `reason`                     | [codersdk.CreateWorkspaceBuildReason](#codersdkcreateworkspacebuildreason)    | false    |              | Reason sets the reason for the workspace build.                                                                                                                                                               |
| `rich_parameter_values`      | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false    |              | Rich parameter values are optional. It will write params to the 'workspace' scope. This will overwrite any existing parameters with the same name. This will not delete old params not included in this list. |
| `state`                      | array of integer                                                              | false    |              |                                                                                                                                                                                                               |
| `template_version_id`        | string                                                                        | false    |              |                                                                                                                                                                                                               |
| `template_version_preset_id` | string                                                                        | false    |              | Template version preset ID is the ID of the template version preset to use for the build.                                                                                                                     |
| `transition`                 | [codersdk.WorkspaceTransition](#codersdkworkspacetransition)                  | true     |              |                                                                                                                                                                                                               |

#### Enumerated Values

| Property     | Value(s)                                                                                               |
|--------------|--------------------------------------------------------------------------------------------------------|
| `log_level`  | `debug`                                                                                                |
| `reason`     | `cli`, `dashboard`, `jetbrains_connection`, `ssh_connection`, `task_manual_pause`, `vscode_connection` |
| `transition` | `delete`, `start`, `stop`                                                                              |

## codersdk.CreateWorkspaceProxyRequest

```json
{
  "display_name": "string",
  "icon": "string",
  "name": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `display_name` | string | false    |              |             |
| `icon`         | string | false    |              |             |
| `name`         | string | true     |              |             |

## codersdk.CreateWorkspaceRequest

```json
{
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "name": "string",
  "rich_parameter_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "ttl_ms": 0
}
```

CreateWorkspaceRequest provides options for creating a new workspace. Only one of TemplateID or TemplateVersionID can be specified, not both. If TemplateID is specified, the active version of the template will be used. Workspace names: - Must start with a letter or number - Can only contain letters, numbers, and hyphens - Cannot contain spaces or special characters - Cannot be named `new` or `create` - Must be unique within your workspaces - Maximum length of 32 characters

### Properties

| Name                         | Type                                                                          | Required | Restrictions | Description                                                                                             |
|------------------------------|-------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------|
| `automatic_updates`          | [codersdk.AutomaticUpdates](#codersdkautomaticupdates)                        | false    |              |                                                                                                         |
| `autostart_schedule`         | string                                                                        | false    |              |                                                                                                         |
| `name`                       | string                                                                        | true     |              |                                                                                                         |
| `rich_parameter_values`      | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false    |              | Rich parameter values allows for additional parameters to be provided during the initial provision.     |
| `template_id`                | string                                                                        | false    |              | Template ID specifies which template should be used for creating the workspace.                         |
| `template_version_id`        | string                                                                        | false    |              | Template version ID can be used to specify a specific version of a template for creating the workspace. |
| `template_version_preset_id` | string                                                                        | false    |              |                                                                                                         |
| `ttl_ms`                     | integer                                                                       | false    |              |                                                                                                         |

## codersdk.CryptoKey

```json
{
  "deletes_at": "2019-08-24T14:15:22Z",
  "feature": "workspace_apps_api_key",
  "secret": "string",
  "sequence": 0,
  "starts_at": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name         | Type                                                   | Required | Restrictions | Description |
|--------------|--------------------------------------------------------|----------|--------------|-------------|
| `deletes_at` | string                                                 | false    |              |             |
| `feature`    | [codersdk.CryptoKeyFeature](#codersdkcryptokeyfeature) | false    |              |             |
| `secret`     | string                                                 | false    |              |             |
| `sequence`   | integer                                                | false    |              |             |
| `starts_at`  | string                                                 | false    |              |             |

## codersdk.CryptoKeyFeature

```json
"workspace_apps_api_key"
```

### Properties

#### Enumerated Values

| Value(s)                                                                           |
|------------------------------------------------------------------------------------|
| `oidc_convert`, `tailnet_resume`, `workspace_apps_api_key`, `workspace_apps_token` |

## codersdk.CustomNotificationContent

```json
{
  "message": "string",
  "title": "string"
}
```

### Properties

| Name      | Type   | Required | Restrictions | Description |
|-----------|--------|----------|--------------|-------------|
| `message` | string | false    |              |             |
| `title`   | string | false    |              |             |

## codersdk.CustomNotificationRequest

```json
{
  "content": {
    "message": "string",
    "title": "string"
  }
}
```

### Properties

| Name      | Type                                                                     | Required | Restrictions | Description |
|-----------|--------------------------------------------------------------------------|----------|--------------|-------------|
| `content` | [codersdk.CustomNotificationContent](#codersdkcustomnotificationcontent) | false    |              |             |

## codersdk.CustomRoleRequest

```json
{
  "display_name": "string",
  "name": "string",
  "organization_member_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "organization_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "site_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "user_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ]
}
```

### Properties

| Name                              | Type                                                | Required | Restrictions | Description                                                                           |
|-----------------------------------|-----------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------|
| `display_name`                    | string                                              | false    |              |                                                                                       |
| `name`                            | string                                              | false    |              |                                                                                       |
| `organization_member_permissions` | array of [codersdk.Permission](#codersdkpermission) | false    |              | Organization member permissions are specific to the organization the role belongs to. |
| `organization_permissions`        | array of [codersdk.Permission](#codersdkpermission) | false    |              | Organization permissions are specific to the organization the role belongs to.        |
| `site_permissions`                | array of [codersdk.Permission](#codersdkpermission) | false    |              |                                                                                       |
| `user_permissions`                | array of [codersdk.Permission](#codersdkpermission) | false    |              |                                                                                       |

## codersdk.DAUEntry

```json
{
  "amount": 0,
  "date": "string"
}
```

### Properties

| Name     | Type    | Required | Restrictions | Description                                                                              |
|----------|---------|----------|--------------|------------------------------------------------------------------------------------------|
| `amount` | integer | false    |              |                                                                                          |
| `date`   | string  | false    |              | Date is a string formatted as 2024-01-31. Timezone and time information is not included. |

## codersdk.DAUsResponse

```json
{
  "entries": [
    {
      "amount": 0,
      "date": "string"
    }
  ],
  "tz_hour_offset": 0
}
```

### Properties

| Name             | Type                                            | Required | Restrictions | Description |
|------------------|-------------------------------------------------|----------|--------------|-------------|
| `entries`        | array of [codersdk.DAUEntry](#codersdkdauentry) | false    |              |             |
| `tz_hour_offset` | integer                                         | false    |              |             |

## codersdk.DERP

```json
{
  "config": {
    "block_direct": true,
    "force_websockets": true,
    "path": "string",
    "url": "string"
  },
  "server": {
    "enable": true,
    "region_code": "string",
    "region_id": 0,
    "region_name": "string",
    "relay_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "stun_addresses": [
      "string"
    ]
  }
}
```

### Properties

| Name     | Type                                                   | Required | Restrictions | Description |
|----------|--------------------------------------------------------|----------|--------------|-------------|
| `config` | [codersdk.DERPConfig](#codersdkderpconfig)             | false    |              |             |
| `server` | [codersdk.DERPServerConfig](#codersdkderpserverconfig) | false    |              |             |

## codersdk.DERPConfig

```json
{
  "block_direct": true,
  "force_websockets": true,
  "path": "string",
  "url": "string"
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description |
|--------------------|---------|----------|--------------|-------------|
| `block_direct`     | boolean | false    |              |             |
| `force_websockets` | boolean | false    |              |             |
| `path`             | string  | false    |              |             |
| `url`              | string  | false    |              |             |

## codersdk.DERPRegion

```json
{
  "latency_ms": 0,
  "preferred": true
}
```

### Properties

| Name         | Type    | Required | Restrictions | Description |
|--------------|---------|----------|--------------|-------------|
| `latency_ms` | number  | false    |              |             |
| `preferred`  | boolean | false    |              |             |

## codersdk.DERPServerConfig

```json
{
  "enable": true,
  "region_code": "string",
  "region_id": 0,
  "region_name": "string",
  "relay_url": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  },
  "stun_addresses": [
    "string"
  ]
}
```

### Properties

| Name             | Type                       | Required | Restrictions | Description |
|------------------|----------------------------|----------|--------------|-------------|
| `enable`         | boolean                    | false    |              |             |
| `region_code`    | string                     | false    |              |             |
| `region_id`      | integer                    | false    |              |             |
| `region_name`    | string                     | false    |              |             |
| `relay_url`      | [serpent.URL](#serpenturl) | false    |              |             |
| `stun_addresses` | array of string            | false    |              |             |

## codersdk.DangerousConfig

```json
{
  "allow_all_cors": true,
  "allow_path_app_sharing": true,
  "allow_path_app_site_owner_access": true
}
```

### Properties

| Name                               | Type    | Required | Restrictions | Description |
|------------------------------------|---------|----------|--------------|-------------|
| `allow_all_cors`                   | boolean | false    |              |             |
| `allow_path_app_sharing`           | boolean | false    |              |             |
| `allow_path_app_site_owner_access` | boolean | false    |              |             |

## codersdk.DeleteExternalAuthByIDResponse

```json
{
  "token_revocation_error": "string",
  "token_revoked": true
}
```

### Properties

| Name                     | Type    | Required | Restrictions | Description                                                                    |
|--------------------------|---------|----------|--------------|--------------------------------------------------------------------------------|
| `token_revocation_error` | string  | false    |              |                                                                                |
| `token_revoked`          | boolean | false    |              | Token revoked set to true if token revocation was attempted and was successful |

## codersdk.DeleteWebpushSubscription

```json
{
  "endpoint": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `endpoint` | string | false    |              |             |

## codersdk.DeleteWorkspaceAgentPortShareRequest

```json
{
  "agent_name": "string",
  "port": 0
}
```

### Properties

| Name         | Type    | Required | Restrictions | Description |
|--------------|---------|----------|--------------|-------------|
| `agent_name` | string  | false    |              |             |
| `port`       | integer | false    |              |             |

## codersdk.DeploymentConfig

```json
{
  "config": {
    "access_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "additional_csp_policy": [
      "string"
    ],
    "address": {
      "host": "string",
      "port": "string"
    },
    "agent_fallback_troubleshooting_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "agent_stat_refresh_interval": 0,
    "ai": {
      "aibridge_proxy": {
        "allowed_private_cidrs": [
          "string"
        ],
        "cert_file": "string",
        "domain_allowlist": [
          "string"
        ],
        "enabled": true,
        "key_file": "string",
        "listen_addr": "string",
        "tls_cert_file": "string",
        "tls_key_file": "string",
        "upstream_proxy": "string",
        "upstream_proxy_ca": "string"
      },
      "bridge": {
        "allow_byok": true,
        "anthropic": {
          "base_url": "string",
          "key": "string"
        },
        "bedrock": {
          "access_key": "string",
          "access_key_secret": "string",
          "base_url": "string",
          "model": "string",
          "region": "string",
          "small_fast_model": "string"
        },
        "circuit_breaker_enabled": true,
        "circuit_breaker_failure_threshold": 0,
        "circuit_breaker_interval": 0,
        "circuit_breaker_max_requests": 0,
        "circuit_breaker_timeout": 0,
        "enabled": true,
        "inject_coder_mcp_tools": true,
        "max_concurrency": 0,
        "openai": {
          "base_url": "string",
          "key": "string"
        },
        "providers": [
          {
            "base_url": "string",
            "bedrock_model": "string",
            "bedrock_region": "string",
            "bedrock_small_fast_model": "string",
            "dump_dir": "string",
            "name": "string",
            "type": "string"
          }
        ],
        "rate_limit": 0,
        "retention": 0,
        "send_actor_headers": true,
        "structured_logging": true
      },
      "chat": {
        "acquire_batch_size": 0,
        "debug_logging_enabled": true
      }
    },
    "allow_workspace_renames": true,
    "autobuild_poll_interval": 0,
    "browser_only": true,
    "cache_directory": "string",
    "cli_upgrade_message": "string",
    "config": "string",
    "config_ssh": {
      "deploymentName": "string",
      "sshconfigOptions": [
        "string"
      ]
    },
    "dangerous": {
      "allow_all_cors": true,
      "allow_path_app_sharing": true,
      "allow_path_app_site_owner_access": true
    },
    "derp": {
      "config": {
        "block_direct": true,
        "force_websockets": true,
        "path": "string",
        "url": "string"
      },
      "server": {
        "enable": true,
        "region_code": "string",
        "region_id": 0,
        "region_name": "string",
        "relay_url": {
          "forceQuery": true,
          "fragment": "string",
          "host": "string",
          "omitHost": true,
          "opaque": "string",
          "path": "string",
          "rawFragment": "string",
          "rawPath": "string",
          "rawQuery": "string",
          "scheme": "string",
          "user": {}
        },
        "stun_addresses": [
          "string"
        ]
      }
    },
    "disable_owner_workspace_exec": true,
    "disable_password_auth": true,
    "disable_path_apps": true,
    "disable_workspace_sharing": true,
    "docs_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "enable_authz_recording": true,
    "enable_terraform_debug_mode": true,
    "ephemeral_deployment": true,
    "experiments": [
      "string"
    ],
    "external_auth": {
      "value": [
        {
          "api_base_url": "string",
          "app_install_url": "string",
          "app_installations_url": "string",
          "auth_url": "string",
          "client_id": "string",
          "code_challenge_methods_supported": [
            "string"
          ],
          "device_code_url": "string",
          "device_flow": true,
          "display_icon": "string",
          "display_name": "string",
          "id": "string",
          "mcp_tool_allow_regex": "string",
          "mcp_tool_deny_regex": "string",
          "mcp_url": "string",
          "no_refresh": true,
          "regex": "string",
          "revoke_url": "string",
          "scopes": [
            "string"
          ],
          "token_url": "string",
          "type": "string",
          "validate_url": "string"
        }
      ]
    },
    "external_auth_github_default_provider_enable": true,
    "external_token_encryption_keys": [
      "string"
    ],
    "healthcheck": {
      "refresh": 0,
      "threshold_database": 0
    },
    "hide_ai_tasks": true,
    "http_address": "string",
    "http_cookies": {
      "host_prefix": true,
      "same_site": "string",
      "secure_auth_cookie": true
    },
    "job_hang_detector_interval": 0,
    "logging": {
      "human": "string",
      "json": "string",
      "log_filter": [
        "string"
      ],
      "stackdriver": "string"
    },
    "metrics_cache_refresh_interval": 0,
    "notifications": {
      "dispatch_timeout": 0,
      "email": {
        "auth": {
          "identity": "string",
          "password": "string",
          "password_file": "string",
          "username": "string"
        },
        "force_tls": true,
        "from": "string",
        "hello": "string",
        "smarthost": "string",
        "tls": {
          "ca_file": "string",
          "cert_file": "string",
          "insecure_skip_verify": true,
          "key_file": "string",
          "server_name": "string",
          "start_tls": true
        }
      },
      "fetch_interval": 0,
      "inbox": {
        "enabled": true
      },
      "lease_count": 0,
      "lease_period": 0,
      "max_send_attempts": 0,
      "method": "string",
      "retry_interval": 0,
      "sync_buffer_size": 0,
      "sync_interval": 0,
      "webhook": {
        "endpoint": {
          "forceQuery": true,
          "fragment": "string",
          "host": "string",
          "omitHost": true,
          "opaque": "string",
          "path": "string",
          "rawFragment": "string",
          "rawPath": "string",
          "rawQuery": "string",
          "scheme": "string",
          "user": {}
        }
      }
    },
    "oauth2": {
      "github": {
        "allow_everyone": true,
        "allow_signups": true,
        "allowed_orgs": [
          "string"
        ],
        "allowed_teams": [
          "string"
        ],
        "client_id": "string",
        "client_secret": "string",
        "default_provider_enable": true,
        "device_flow": true,
        "enterprise_base_url": "string"
      }
    },
    "oidc": {
      "allow_signups": true,
      "auth_url_params": {},
      "client_cert_file": "string",
      "client_id": "string",
      "client_key_file": "string",
      "client_secret": "string",
      "email_domain": [
        "string"
      ],
      "email_field": "string",
      "group_allow_list": [
        "string"
      ],
      "group_auto_create": true,
      "group_mapping": {},
      "group_regex_filter": {},
      "groups_field": "string",
      "icon_url": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      },
      "ignore_email_verified": true,
      "ignore_user_info": true,
      "issuer_url": "string",
      "name_field": "string",
      "organization_assign_default": true,
      "organization_field": "string",
      "organization_mapping": {},
      "redirect_url": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      },
      "scopes": [
        "string"
      ],
      "sign_in_text": "string",
      "signups_disabled_text": "string",
      "skip_issuer_checks": true,
      "source_user_info_from_access_token": true,
      "user_role_field": "string",
      "user_role_mapping": {},
      "user_roles_default": [
        "string"
      ],
      "username_field": "string"
    },
    "pg_auth": "string",
    "pg_conn_max_idle": "string",
    "pg_conn_max_open": 0,
    "pg_connection_url": "string",
    "pprof": {
      "address": {
        "host": "string",
        "port": "string"
      },
      "enable": true
    },
    "prometheus": {
      "address": {
        "host": "string",
        "port": "string"
      },
      "aggregate_agent_stats_by": [
        "string"
      ],
      "collect_agent_stats": true,
      "collect_db_metrics": true,
      "enable": true
    },
    "provisioner": {
      "daemon_poll_interval": 0,
      "daemon_poll_jitter": 0,
      "daemon_psk": "string",
      "daemon_types": [
        "string"
      ],
      "daemons": 0,
      "force_cancel_interval": 0
    },
    "proxy_health_status_interval": 0,
    "proxy_trusted_headers": [
      "string"
    ],
    "proxy_trusted_origins": [
      "string"
    ],
    "rate_limit": {
      "api": 0,
      "disable_all": true
    },
    "redirect_to_access_url": true,
    "retention": {
      "api_keys": 0,
      "audit_logs": 0,
      "connection_logs": 0,
      "workspace_agent_logs": 0
    },
    "scim_api_key": "string",
    "session_lifetime": {
      "default_duration": 0,
      "default_token_lifetime": 0,
      "disable_expiry_refresh": true,
      "max_admin_token_lifetime": 0,
      "max_token_lifetime": 0,
      "refresh_default_duration": 0
    },
    "ssh_keygen_algorithm": "string",
    "stats_collection": {
      "usage_stats": {
        "enable": true
      }
    },
    "strict_transport_security": 0,
    "strict_transport_security_options": [
      "string"
    ],
    "support": {
      "links": {
        "value": [
          {
            "icon": "bug",
            "location": "navbar",
            "name": "string",
            "target": "string"
          }
        ]
      }
    },
    "swagger": {
      "enable": true
    },
    "telemetry": {
      "enable": true,
      "trace": true,
      "url": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      }
    },
    "terms_of_service_url": "string",
    "tls": {
      "address": {
        "host": "string",
        "port": "string"
      },
      "allow_insecure_ciphers": true,
      "cert_file": [
        "string"
      ],
      "client_auth": "string",
      "client_ca_file": "string",
      "client_cert_file": "string",
      "client_key_file": "string",
      "enable": true,
      "key_file": [
        "string"
      ],
      "min_version": "string",
      "redirect_http": true,
      "supported_ciphers": [
        "string"
      ]
    },
    "trace": {
      "capture_logs": true,
      "data_dog": true,
      "enable": true,
      "honeycomb_api_key": "string"
    },
    "update_check": true,
    "user_quiet_hours_schedule": {
      "allow_user_custom": true,
      "default_schedule": "string"
    },
    "verbose": true,
    "web_terminal_renderer": "string",
    "wgtunnel_host": "string",
    "wildcard_access_url": "string",
    "workspace_hostname_suffix": "string",
    "workspace_prebuilds": {
      "failure_hard_limit": 0,
      "reconciliation_backoff_interval": 0,
      "reconciliation_backoff_lookback": 0,
      "reconciliation_interval": 0
    },
    "write_config": true
  },
  "options": [
    {
      "annotations": {
        "property1": "string",
        "property2": "string"
      },
      "default": "string",
      "description": "string",
      "env": "string",
      "flag": "string",
      "flag_shorthand": "string",
      "group": {
        "description": "string",
        "name": "string",
        "parent": {
          "description": "string",
          "name": "string",
          "parent": {},
          "yaml": "string"
        },
        "yaml": "string"
      },
      "hidden": true,
      "name": "string",
      "required": true,
      "use_instead": [
        {}
      ],
      "value": null,
      "value_source": "",
      "yaml": "string"
    }
  ]
}
```

### Properties

| Name      | Type                                                   | Required | Restrictions | Description |
|-----------|--------------------------------------------------------|----------|--------------|-------------|
| `config`  | [codersdk.DeploymentValues](#codersdkdeploymentvalues) | false    |              |             |
| `options` | array of [serpent.Option](#serpentoption)              | false    |              |             |

## codersdk.DeploymentStats

```json
{
  "aggregated_from": "2019-08-24T14:15:22Z",
  "collected_at": "2019-08-24T14:15:22Z",
  "next_update_at": "2019-08-24T14:15:22Z",
  "session_count": {
    "jetbrains": 0,
    "reconnecting_pty": 0,
    "ssh": 0,
    "vscode": 0
  },
  "workspaces": {
    "building": 0,
    "connection_latency_ms": {
      "p50": 0,
      "p95": 0
    },
    "failed": 0,
    "pending": 0,
    "running": 0,
    "rx_bytes": 0,
    "stopped": 0,
    "tx_bytes": 0
  }
}
```

### Properties

| Name              | Type                                                                         | Required | Restrictions | Description                                                                                                                 |
|-------------------|------------------------------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------|
| `aggregated_from` | string                                                                       | false    |              | Aggregated from is the time in which stats are aggregated from. This might be back in time a specific duration or interval. |
| `collected_at`    | string                                                                       | false    |              | Collected at is the time in which stats are collected at.                                                                   |
| `next_update_at`  | string                                                                       | false    |              | Next update at is the time when the next batch of stats will be updated.                                                    |
| `session_count`   | [codersdk.SessionCountDeploymentStats](#codersdksessioncountdeploymentstats) | false    |              |                                                                                                                             |
| `workspaces`      | [codersdk.WorkspaceDeploymentStats](#codersdkworkspacedeploymentstats)       | false    |              |                                                                                                                             |

## codersdk.DeploymentValues

```json
{
  "access_url": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  },
  "additional_csp_policy": [
    "string"
  ],
  "address": {
    "host": "string",
    "port": "string"
  },
  "agent_fallback_troubleshooting_url": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  },
  "agent_stat_refresh_interval": 0,
  "ai": {
    "aibridge_proxy": {
      "allowed_private_cidrs": [
        "string"
      ],
      "cert_file": "string",
      "domain_allowlist": [
        "string"
      ],
      "enabled": true,
      "key_file": "string",
      "listen_addr": "string",
      "tls_cert_file": "string",
      "tls_key_file": "string",
      "upstream_proxy": "string",
      "upstream_proxy_ca": "string"
    },
    "bridge": {
      "allow_byok": true,
      "anthropic": {
        "base_url": "string",
        "key": "string"
      },
      "bedrock": {
        "access_key": "string",
        "access_key_secret": "string",
        "base_url": "string",
        "model": "string",
        "region": "string",
        "small_fast_model": "string"
      },
      "circuit_breaker_enabled": true,
      "circuit_breaker_failure_threshold": 0,
      "circuit_breaker_interval": 0,
      "circuit_breaker_max_requests": 0,
      "circuit_breaker_timeout": 0,
      "enabled": true,
      "inject_coder_mcp_tools": true,
      "max_concurrency": 0,
      "openai": {
        "base_url": "string",
        "key": "string"
      },
      "providers": [
        {
          "base_url": "string",
          "bedrock_model": "string",
          "bedrock_region": "string",
          "bedrock_small_fast_model": "string",
          "dump_dir": "string",
          "name": "string",
          "type": "string"
        }
      ],
      "rate_limit": 0,
      "retention": 0,
      "send_actor_headers": true,
      "structured_logging": true
    },
    "chat": {
      "acquire_batch_size": 0,
      "debug_logging_enabled": true
    }
  },
  "allow_workspace_renames": true,
  "autobuild_poll_interval": 0,
  "browser_only": true,
  "cache_directory": "string",
  "cli_upgrade_message": "string",
  "config": "string",
  "config_ssh": {
    "deploymentName": "string",
    "sshconfigOptions": [
      "string"
    ]
  },
  "dangerous": {
    "allow_all_cors": true,
    "allow_path_app_sharing": true,
    "allow_path_app_site_owner_access": true
  },
  "derp": {
    "config": {
      "block_direct": true,
      "force_websockets": true,
      "path": "string",
      "url": "string"
    },
    "server": {
      "enable": true,
      "region_code": "string",
      "region_id": 0,
      "region_name": "string",
      "relay_url": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      },
      "stun_addresses": [
        "string"
      ]
    }
  },
  "disable_owner_workspace_exec": true,
  "disable_password_auth": true,
  "disable_path_apps": true,
  "disable_workspace_sharing": true,
  "docs_url": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  },
  "enable_authz_recording": true,
  "enable_terraform_debug_mode": true,
  "ephemeral_deployment": true,
  "experiments": [
    "string"
  ],
  "external_auth": {
    "value": [
      {
        "api_base_url": "string",
        "app_install_url": "string",
        "app_installations_url": "string",
        "auth_url": "string",
        "client_id": "string",
        "code_challenge_methods_supported": [
          "string"
        ],
        "device_code_url": "string",
        "device_flow": true,
        "display_icon": "string",
        "display_name": "string",
        "id": "string",
        "mcp_tool_allow_regex": "string",
        "mcp_tool_deny_regex": "string",
        "mcp_url": "string",
        "no_refresh": true,
        "regex": "string",
        "revoke_url": "string",
        "scopes": [
          "string"
        ],
        "token_url": "string",
        "type": "string",
        "validate_url": "string"
      }
    ]
  },
  "external_auth_github_default_provider_enable": true,
  "external_token_encryption_keys": [
    "string"
  ],
  "healthcheck": {
    "refresh": 0,
    "threshold_database": 0
  },
  "hide_ai_tasks": true,
  "http_address": "string",
  "http_cookies": {
    "host_prefix": true,
    "same_site": "string",
    "secure_auth_cookie": true
  },
  "job_hang_detector_interval": 0,
  "logging": {
    "human": "string",
    "json": "string",
    "log_filter": [
      "string"
    ],
    "stackdriver": "string"
  },
  "metrics_cache_refresh_interval": 0,
  "notifications": {
    "dispatch_timeout": 0,
    "email": {
      "auth": {
        "identity": "string",
        "password": "string",
        "password_file": "string",
        "username": "string"
      },
      "force_tls": true,
      "from": "string",
      "hello": "string",
      "smarthost": "string",
      "tls": {
        "ca_file": "string",
        "cert_file": "string",
        "insecure_skip_verify": true,
        "key_file": "string",
        "server_name": "string",
        "start_tls": true
      }
    },
    "fetch_interval": 0,
    "inbox": {
      "enabled": true
    },
    "lease_count": 0,
    "lease_period": 0,
    "max_send_attempts": 0,
    "method": "string",
    "retry_interval": 0,
    "sync_buffer_size": 0,
    "sync_interval": 0,
    "webhook": {
      "endpoint": {
        "forceQuery": true,
        "fragment": "string",
        "host": "string",
        "omitHost": true,
        "opaque": "string",
        "path": "string",
        "rawFragment": "string",
        "rawPath": "string",
        "rawQuery": "string",
        "scheme": "string",
        "user": {}
      }
    }
  },
  "oauth2": {
    "github": {
      "allow_everyone": true,
      "allow_signups": true,
      "allowed_orgs": [
        "string"
      ],
      "allowed_teams": [
        "string"
      ],
      "client_id": "string",
      "client_secret": "string",
      "default_provider_enable": true,
      "device_flow": true,
      "enterprise_base_url": "string"
    }
  },
  "oidc": {
    "allow_signups": true,
    "auth_url_params": {},
    "client_cert_file": "string",
    "client_id": "string",
    "client_key_file": "string",
    "client_secret": "string",
    "email_domain": [
      "string"
    ],
    "email_field": "string",
    "group_allow_list": [
      "string"
    ],
    "group_auto_create": true,
    "group_mapping": {},
    "group_regex_filter": {},
    "groups_field": "string",
    "icon_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "ignore_email_verified": true,
    "ignore_user_info": true,
    "issuer_url": "string",
    "name_field": "string",
    "organization_assign_default": true,
    "organization_field": "string",
    "organization_mapping": {},
    "redirect_url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    },
    "scopes": [
      "string"
    ],
    "sign_in_text": "string",
    "signups_disabled_text": "string",
    "skip_issuer_checks": true,
    "source_user_info_from_access_token": true,
    "user_role_field": "string",
    "user_role_mapping": {},
    "user_roles_default": [
      "string"
    ],
    "username_field": "string"
  },
  "pg_auth": "string",
  "pg_conn_max_idle": "string",
  "pg_conn_max_open": 0,
  "pg_connection_url": "string",
  "pprof": {
    "address": {
      "host": "string",
      "port": "string"
    },
    "enable": true
  },
  "prometheus": {
    "address": {
      "host": "string",
      "port": "string"
    },
    "aggregate_agent_stats_by": [
      "string"
    ],
    "collect_agent_stats": true,
    "collect_db_metrics": true,
    "enable": true
  },
  "provisioner": {
    "daemon_poll_interval": 0,
    "daemon_poll_jitter": 0,
    "daemon_psk": "string",
    "daemon_types": [
      "string"
    ],
    "daemons": 0,
    "force_cancel_interval": 0
  },
  "proxy_health_status_interval": 0,
  "proxy_trusted_headers": [
    "string"
  ],
  "proxy_trusted_origins": [
    "string"
  ],
  "rate_limit": {
    "api": 0,
    "disable_all": true
  },
  "redirect_to_access_url": true,
  "retention": {
    "api_keys": 0,
    "audit_logs": 0,
    "connection_logs": 0,
    "workspace_agent_logs": 0
  },
  "scim_api_key": "string",
  "session_lifetime": {
    "default_duration": 0,
    "default_token_lifetime": 0,
    "disable_expiry_refresh": true,
    "max_admin_token_lifetime": 0,
    "max_token_lifetime": 0,
    "refresh_default_duration": 0
  },
  "ssh_keygen_algorithm": "string",
  "stats_collection": {
    "usage_stats": {
      "enable": true
    }
  },
  "strict_transport_security": 0,
  "strict_transport_security_options": [
    "string"
  ],
  "support": {
    "links": {
      "value": [
        {
          "icon": "bug",
          "location": "navbar",
          "name": "string",
          "target": "string"
        }
      ]
    }
  },
  "swagger": {
    "enable": true
  },
  "telemetry": {
    "enable": true,
    "trace": true,
    "url": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    }
  },
  "terms_of_service_url": "string",
  "tls": {
    "address": {
      "host": "string",
      "port": "string"
    },
    "allow_insecure_ciphers": true,
    "cert_file": [
      "string"
    ],
    "client_auth": "string",
    "client_ca_file": "string",
    "client_cert_file": "string",
    "client_key_file": "string",
    "enable": true,
    "key_file": [
      "string"
    ],
    "min_version": "string",
    "redirect_http": true,
    "supported_ciphers": [
      "string"
    ]
  },
  "trace": {
    "capture_logs": true,
    "data_dog": true,
    "enable": true,
    "honeycomb_api_key": "string"
  },
  "update_check": true,
  "user_quiet_hours_schedule": {
    "allow_user_custom": true,
    "default_schedule": "string"
  },
  "verbose": true,
  "web_terminal_renderer": "string",
  "wgtunnel_host": "string",
  "wildcard_access_url": "string",
  "workspace_hostname_suffix": "string",
  "workspace_prebuilds": {
    "failure_hard_limit": 0,
    "reconciliation_backoff_interval": 0,
    "reconciliation_backoff_lookback": 0,
    "reconciliation_interval": 0
  },
  "write_config": true
}
```

### Properties

| Name                                           | Type                                                                                                 | Required | Restrictions | Description                                                        |
|------------------------------------------------|------------------------------------------------------------------------------------------------------|----------|--------------|--------------------------------------------------------------------|
| `access_url`                                   | [serpent.URL](#serpenturl)                                                                           | false    |              |                                                                    |
| `additional_csp_policy`                        | array of string                                                                                      | false    |              |                                                                    |
| `address`                                      | [serpent.HostPort](#serpenthostport)                                                                 | false    |              | Deprecated: Use HTTPAddress or TLS.Address instead.                |
| `agent_fallback_troubleshooting_url`           | [serpent.URL](#serpenturl)                                                                           | false    |              |                                                                    |
| `agent_stat_refresh_interval`                  | integer                                                                                              | false    |              |                                                                    |
| `ai`                                           | [codersdk.AIConfig](#codersdkaiconfig)                                                               | false    |              |                                                                    |
| `allow_workspace_renames`                      | boolean                                                                                              | false    |              |                                                                    |
| `autobuild_poll_interval`                      | integer                                                                                              | false    |              |                                                                    |
| `browser_only`                                 | boolean                                                                                              | false    |              |                                                                    |
| `cache_directory`                              | string                                                                                               | false    |              |                                                                    |
| `cli_upgrade_message`                          | string                                                                                               | false    |              |                                                                    |
| `config`                                       | string                                                                                               | false    |              |                                                                    |
| `config_ssh`                                   | [codersdk.SSHConfig](#codersdksshconfig)                                                             | false    |              |                                                                    |
| `dangerous`                                    | [codersdk.DangerousConfig](#codersdkdangerousconfig)                                                 | false    |              |                                                                    |
| `derp`                                         | [codersdk.DERP](#codersdkderp)                                                                       | false    |              |                                                                    |
| `disable_owner_workspace_exec`                 | boolean                                                                                              | false    |              |                                                                    |
| `disable_password_auth`                        | boolean                                                                                              | false    |              |                                                                    |
| `disable_path_apps`                            | boolean                                                                                              | false    |              |                                                                    |
| `disable_workspace_sharing`                    | boolean                                                                                              | false    |              |                                                                    |
| `docs_url`                                     | [serpent.URL](#serpenturl)                                                                           | false    |              |                                                                    |
| `enable_authz_recording`                       | boolean                                                                                              | false    |              |                                                                    |
| `enable_terraform_debug_mode`                  | boolean                                                                                              | false    |              |                                                                    |
| `ephemeral_deployment`                         | boolean                                                                                              | false    |              |                                                                    |
| `experiments`                                  | array of string                                                                                      | false    |              |                                                                    |
| `external_auth`                                | [serpent.Struct-array_codersdk_ExternalAuthConfig](#serpentstruct-array_codersdk_externalauthconfig) | false    |              |                                                                    |
| `external_auth_github_default_provider_enable` | boolean                                                                                              | false    |              |                                                                    |
| `external_token_encryption_keys`               | array of string                                                                                      | false    |              |                                                                    |
| `healthcheck`                                  | [codersdk.HealthcheckConfig](#codersdkhealthcheckconfig)                                             | false    |              |                                                                    |
| `hide_ai_tasks`                                | boolean                                                                                              | false    |              |                                                                    |
| `http_address`                                 | string                                                                                               | false    |              | Http address is a string because it may be set to zero to disable. |
| `http_cookies`                                 | [codersdk.HTTPCookieConfig](#codersdkhttpcookieconfig)                                               | false    |              |                                                                    |
| `job_hang_detector_interval`                   | integer                                                                                              | false    |              |                                                                    |
| `logging`                                      | [codersdk.LoggingConfig](#codersdkloggingconfig)                                                     | false    |              |                                                                    |
| `metrics_cache_refresh_interval`               | integer                                                                                              | false    |              |                                                                    |
| `notifications`                                | [codersdk.NotificationsConfig](#codersdknotificationsconfig)                                         | false    |              |                                                                    |
| `oauth2`                                       | [codersdk.OAuth2Config](#codersdkoauth2config)                                                       | false    |              |                                                                    |
| `oidc`                                         | [codersdk.OIDCConfig](#codersdkoidcconfig)                                                           | false    |              |                                                                    |
| `pg_auth`                                      | string                                                                                               | false    |              |                                                                    |
| `pg_conn_max_idle`                             | string                                                                                               | false    |              |                                                                    |
| `pg_conn_max_open`                             | integer                                                                                              | false    |              |                                                                    |
| `pg_connection_url`                            | string                                                                                               | false    |              |                                                                    |
| `pprof`                                        | [codersdk.PprofConfig](#codersdkpprofconfig)                                                         | false    |              |                                                                    |
| `prometheus`                                   | [codersdk.PrometheusConfig](#codersdkprometheusconfig)                                               | false    |              |                                                                    |
| `provisioner`                                  | [codersdk.ProvisionerConfig](#codersdkprovisionerconfig)                                             | false    |              |                                                                    |
| `proxy_health_status_interval`                 | integer                                                                                              | false    |              |                                                                    |
| `proxy_trusted_headers`                        | array of string                                                                                      | false    |              |                                                                    |
| `proxy_trusted_origins`                        | array of string                                                                                      | false    |              |                                                                    |
| `rate_limit`                                   | [codersdk.RateLimitConfig](#codersdkratelimitconfig)                                                 | false    |              |                                                                    |
| `redirect_to_access_url`                       | boolean                                                                                              | false    |              |                                                                    |
| `retention`                                    | [codersdk.RetentionConfig](#codersdkretentionconfig)                                                 | false    |              |                                                                    |
| `scim_api_key`                                 | string                                                                                               | false    |              |                                                                    |
| `session_lifetime`                             | [codersdk.SessionLifetime](#codersdksessionlifetime)                                                 | false    |              |                                                                    |
| `ssh_keygen_algorithm`                         | string                                                                                               | false    |              |                                                                    |
| `stats_collection`                             | [codersdk.StatsCollectionConfig](#codersdkstatscollectionconfig)                                     | false    |              |                                                                    |
| `strict_transport_security`                    | integer                                                                                              | false    |              |                                                                    |
| `strict_transport_security_options`            | array of string                                                                                      | false    |              |                                                                    |
| `support`                                      | [codersdk.SupportConfig](#codersdksupportconfig)                                                     | false    |              |                                                                    |
| `swagger`                                      | [codersdk.SwaggerConfig](#codersdkswaggerconfig)                                                     | false    |              |                                                                    |
| `telemetry`                                    | [codersdk.TelemetryConfig](#codersdktelemetryconfig)                                                 | false    |              |                                                                    |
| `terms_of_service_url`                         | string                                                                                               | false    |              |                                                                    |
| `tls`                                          | [codersdk.TLSConfig](#codersdktlsconfig)                                                             | false    |              |                                                                    |
| `trace`                                        | [codersdk.TraceConfig](#codersdktraceconfig)                                                         | false    |              |                                                                    |
| `update_check`                                 | boolean                                                                                              | false    |              |                                                                    |
| `user_quiet_hours_schedule`                    | [codersdk.UserQuietHoursScheduleConfig](#codersdkuserquiethoursscheduleconfig)                       | false    |              |                                                                    |
| `verbose`                                      | boolean                                                                                              | false    |              |                                                                    |
| `web_terminal_renderer`                        | string                                                                                               | false    |              |                                                                    |
| `wgtunnel_host`                                | string                                                                                               | false    |              |                                                                    |
| `wildcard_access_url`                          | string                                                                                               | false    |              |                                                                    |
| `workspace_hostname_suffix`                    | string                                                                                               | false    |              |                                                                    |
| `workspace_prebuilds`                          | [codersdk.PrebuildsConfig](#codersdkprebuildsconfig)                                                 | false    |              |                                                                    |
| `write_config`                                 | boolean                                                                                              | false    |              |                                                                    |

## codersdk.DiagnosticExtra

```json
{
  "code": "string"
}
```

### Properties

| Name   | Type   | Required | Restrictions | Description |
|--------|--------|----------|--------------|-------------|
| `code` | string | false    |              |             |

## codersdk.DiagnosticSeverityString

```json
"error"
```

### Properties

#### Enumerated Values

| Value(s)           |
|--------------------|
| `error`, `warning` |

## codersdk.DisplayApp

```json
"vscode"
```

### Properties

#### Enumerated Values

| Value(s)                                                                            |
|-------------------------------------------------------------------------------------|
| `port_forwarding_helper`, `ssh_helper`, `vscode`, `vscode_insiders`, `web_terminal` |

## codersdk.DynamicParametersRequest

```json
{
  "id": 0,
  "inputs": {
    "property1": "string",
    "property2": "string"
  },
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description                                                                                                                                                                            |
|--------------------|---------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id`               | integer | false    |              | ID identifies the request for response ordering. Websocket response IDs are monotonically increasing and may exceed the request ID when server-side events trigger additional renders. |
| `inputs`           | object  | false    |              |                                                                                                                                                                                        |
| » `[any property]` | string  | false    |              |                                                                                                                                                                                        |
| `owner_id`         | string  | false    |              | Owner ID if uuid.Nil, it defaults to `codersdk.Me`                                                                                                                                     |

## codersdk.DynamicParametersResponse

```json
{
  "diagnostics": [
    {
      "detail": "string",
      "extra": {
        "code": "string"
      },
      "severity": "error",
      "summary": "string"
    }
  ],
  "id": 0,
  "parameters": [
    {
      "default_value": {
        "valid": true,
        "value": "string"
      },
      "description": "string",
      "diagnostics": [
        {
          "detail": "string",
          "extra": {
            "code": "string"
          },
          "severity": "error",
          "summary": "string"
        }
      ],
      "display_name": "string",
      "ephemeral": true,
      "form_type": "",
      "icon": "string",
      "mutable": true,
      "name": "string",
      "options": [
        {
          "description": "string",
          "icon": "string",
          "name": "string",
          "value": {
            "valid": true,
            "value": "string"
          }
        }
      ],
      "order": 0,
      "required": true,
      "styling": {
        "disabled": true,
        "label": "string",
        "mask_input": true,
        "placeholder": "string"
      },
      "type": "string",
      "validations": [
        {
          "validation_error": "string",
          "validation_max": 0,
          "validation_min": 0,
          "validation_monotonic": "string",
          "validation_regex": "string"
        }
      ],
      "value": {
        "valid": true,
        "value": "string"
      }
    }
  ],
  "secret_requirements": [
    {
      "env": "string",
      "file": "string",
      "help_message": "string",
      "satisfied": true
    }
  ]
}
```

### Properties

| Name                  | Type                                                                          | Required | Restrictions | Description |
|-----------------------|-------------------------------------------------------------------------------|----------|--------------|-------------|
| `diagnostics`         | array of [codersdk.FriendlyDiagnostic](#codersdkfriendlydiagnostic)           | false    |              |             |
| `id`                  | integer                                                                       | false    |              |             |
| `parameters`          | array of [codersdk.PreviewParameter](#codersdkpreviewparameter)               | false    |              |             |
| `secret_requirements` | array of [codersdk.SecretRequirementStatus](#codersdksecretrequirementstatus) | false    |              |             |

## codersdk.DynamicTool

```json
{
  "description": "string",
  "input_schema": [
    0
  ],
  "name": "string"
}
```

### Properties

| Name           | Type             | Required | Restrictions | Description                                                                                                                                  |
|----------------|------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------|
| `description`  | string           | false    |              |                                                                                                                                              |
| `input_schema` | array of integer | false    |              | Input schema JSON key "input_schema" uses snake_case for SDK consistency, deviating from the camelCase "inputSchema" convention used by MCP. |
| `name`         | string           | false    |              |                                                                                                                                              |

## codersdk.EditChatMessageRequest

```json
{
  "content": [
    {
      "content": "string",
      "end_line": 0,
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "file_name": "string",
      "start_line": 0,
      "text": "string",
      "type": "text"
    }
  ]
}
```

### Properties

| Name      | Type                                                      | Required | Restrictions | Description |
|-----------|-----------------------------------------------------------|----------|--------------|-------------|
| `content` | array of [codersdk.ChatInputPart](#codersdkchatinputpart) | false    |              |             |

## codersdk.EditChatMessageResponse

```json
{
  "message": {
    "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
    "content": [
      {
        "args": [
          0
        ],
        "args_delta": "string",
        "content": "string",
        "context_file_agent_id": {
          "uuid": "string",
          "valid": true
        },
        "context_file_content": "string",
        "context_file_directory": "string",
        "context_file_os": "string",
        "context_file_path": "string",
        "context_file_skill_meta_file": "string",
        "context_file_truncated": true,
        "created_at": "2019-08-24T14:15:22Z",
        "data": [
          0
        ],
        "end_line": 0,
        "file_id": {
          "uuid": "string",
          "valid": true
        },
        "file_name": "string",
        "is_error": true,
        "is_media": true,
        "mcp_server_config_id": {
          "uuid": "string",
          "valid": true
        },
        "media_type": "string",
        "name": "string",
        "provider_executed": true,
        "provider_metadata": [
          0
        ],
        "result": [
          0
        ],
        "result_delta": "string",
        "signature": "string",
        "skill_description": "string",
        "skill_dir": "string",
        "skill_name": "string",
        "source_id": "string",
        "start_line": 0,
        "text": "string",
        "title": "string",
        "tool_call_id": "string",
        "tool_name": "string",
        "type": "text",
        "url": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
    "id": 0,
    "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
    "role": "system",
    "usage": {
      "cache_creation_tokens": 0,
      "cache_read_tokens": 0,
      "context_limit": 0,
      "input_tokens": 0,
      "output_tokens": 0,
      "reasoning_tokens": 0,
      "total_tokens": 0
    }
  },
  "warnings": [
    "string"
  ]
}
```

### Properties

| Name       | Type                                         | Required | Restrictions | Description |
|------------|----------------------------------------------|----------|--------------|-------------|
| `message`  | [codersdk.ChatMessage](#codersdkchatmessage) | false    |              |             |
| `warnings` | array of string                              | false    |              |             |

## codersdk.Entitlement

```json
"entitled"
```

### Properties

#### Enumerated Values

| Value(s)                                   |
|--------------------------------------------|
| `entitled`, `grace_period`, `not_entitled` |

## codersdk.Entitlements

```json
{
  "errors": [
    "string"
  ],
  "features": {
    "property1": {
      "actual": 0,
      "enabled": true,
      "entitlement": "entitled",
      "limit": 0,
      "usage_period": {
        "end": "2019-08-24T14:15:22Z",
        "issued_at": "2019-08-24T14:15:22Z",
        "start": "2019-08-24T14:15:22Z"
      }
    },
    "property2": {
      "actual": 0,
      "enabled": true,
      "entitlement": "entitled",
      "limit": 0,
      "usage_period": {
        "end": "2019-08-24T14:15:22Z",
        "issued_at": "2019-08-24T14:15:22Z",
        "start": "2019-08-24T14:15:22Z"
      }
    }
  },
  "has_license": true,
  "refreshed_at": "2019-08-24T14:15:22Z",
  "require_telemetry": true,
  "trial": true,
  "warnings": [
    "string"
  ]
}
```

### Properties

| Name                | Type                                 | Required | Restrictions | Description |
|---------------------|--------------------------------------|----------|--------------|-------------|
| `errors`            | array of string                      | false    |              |             |
| `features`          | object                               | false    |              |             |
| » `[any property]`  | [codersdk.Feature](#codersdkfeature) | false    |              |             |
| `has_license`       | boolean                              | false    |              |             |
| `refreshed_at`      | string                               | false    |              |             |
| `require_telemetry` | boolean                              | false    |              |             |
| `trial`             | boolean                              | false    |              |             |
| `warnings`          | array of string                      | false    |              |             |

## codersdk.Experiment

```json
"example"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                      |
|-------------------------------------------------------------------------------------------------------------------------------|
| `auto-fill-parameters`, `example`, `mcp-server-http`, `notifications`, `oauth2`, `workspace-build-updates`, `workspace-usage` |

## codersdk.ExternalAPIKeyScopes

```json
{
  "external": [
    "all"
  ]
}
```

### Properties

| Name       | Type                                                  | Required | Restrictions | Description |
|------------|-------------------------------------------------------|----------|--------------|-------------|
| `external` | array of [codersdk.APIKeyScope](#codersdkapikeyscope) | false    |              |             |

## codersdk.ExternalAgentCredentials

```json
{
  "agent_token": "string",
  "command": "string"
}
```

### Properties

| Name          | Type   | Required | Restrictions | Description |
|---------------|--------|----------|--------------|-------------|
| `agent_token` | string | false    |              |             |
| `command`     | string | false    |              |             |

## codersdk.ExternalAuth

```json
{
  "app_install_url": "string",
  "app_installable": true,
  "authenticated": true,
  "device": true,
  "display_name": "string",
  "installations": [
    {
      "account": {
        "avatar_url": "string",
        "id": 0,
        "login": "string",
        "name": "string",
        "profile_url": "string"
      },
      "configure_url": "string",
      "id": 0
    }
  ],
  "supports_revocation": true,
  "user": {
    "avatar_url": "string",
    "id": 0,
    "login": "string",
    "name": "string",
    "profile_url": "string"
  }
}
```

### Properties

| Name                  | Type                                                                                  | Required | Restrictions | Description                                                             |
|-----------------------|---------------------------------------------------------------------------------------|----------|--------------|-------------------------------------------------------------------------|
| `app_install_url`     | string                                                                                | false    |              | App install URL is the URL to install the app.                          |
| `app_installable`     | boolean                                                                               | false    |              | App installable is true if the request for app installs was successful. |
| `authenticated`       | boolean                                                                               | false    |              |                                                                         |
| `device`              | boolean                                                                               | false    |              |                                                                         |
| `display_name`        | string                                                                                | false    |              |                                                                         |
| `installations`       | array of [codersdk.ExternalAuthAppInstallation](#codersdkexternalauthappinstallation) | false    |              | Installations are the installations that the user has access to.        |
| `supports_revocation` | boolean                                                                               | false    |              |                                                                         |
| `user`                | [codersdk.ExternalAuthUser](#codersdkexternalauthuser)                                | false    |              | User is the user that authenticated with the provider.                  |

## codersdk.ExternalAuthAppInstallation

```json
{
  "account": {
    "avatar_url": "string",
    "id": 0,
    "login": "string",
    "name": "string",
    "profile_url": "string"
  },
  "configure_url": "string",
  "id": 0
}
```

### Properties

| Name            | Type                                                   | Required | Restrictions | Description |
|-----------------|--------------------------------------------------------|----------|--------------|-------------|
| `account`       | [codersdk.ExternalAuthUser](#codersdkexternalauthuser) | false    |              |             |
| `configure_url` | string                                                 | false    |              |             |
| `id`            | integer                                                | false    |              |             |

## codersdk.ExternalAuthConfig

```json
{
  "api_base_url": "string",
  "app_install_url": "string",
  "app_installations_url": "string",
  "auth_url": "string",
  "client_id": "string",
  "code_challenge_methods_supported": [
    "string"
  ],
  "device_code_url": "string",
  "device_flow": true,
  "display_icon": "string",
  "display_name": "string",
  "id": "string",
  "mcp_tool_allow_regex": "string",
  "mcp_tool_deny_regex": "string",
  "mcp_url": "string",
  "no_refresh": true,
  "regex": "string",
  "revoke_url": "string",
  "scopes": [
    "string"
  ],
  "token_url": "string",
  "type": "string",
  "validate_url": "string"
}
```

### Properties

| Name                               | Type            | Required | Restrictions | Description                                                                                                                                                 |
|------------------------------------|-----------------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `api_base_url`                     | string          | false    |              | Api base URL is the base URL for provider REST API calls (e.g., "https://api.github.com" for GitHub). Derived from defaults when not explicitly configured. |
| `app_install_url`                  | string          | false    |              |                                                                                                                                                             |
| `app_installations_url`            | string          | false    |              |                                                                                                                                                             |
| `auth_url`                         | string          | false    |              |                                                                                                                                                             |
| `client_id`                        | string          | false    |              |                                                                                                                                                             |
| `code_challenge_methods_supported` | array of string | false    |              | Code challenge methods supported lists the PKCE code challenge methods The only one supported by Coder is "S256".                                           |
| `device_code_url`                  | string          | false    |              |                                                                                                                                                             |
| `device_flow`                      | boolean         | false    |              |                                                                                                                                                             |
| `display_icon`                     | string          | false    |              | Display icon is a URL to an icon to display in the UI.                                                                                                      |
| `display_name`                     | string          | false    |              | Display name is shown in the UI to identify the auth config.                                                                                                |
| `id`                               | string          | false    |              | ID is a unique identifier for the auth config. It defaults to `type` when not provided.                                                                     |
| `mcp_tool_allow_regex`             | string          | false    |              | Deprecated: Injected MCP in AI Bridge is deprecated and will be removed in a future release.                                                                |
| `mcp_tool_deny_regex`              | string          | false    |              | Deprecated: Injected MCP in AI Bridge is deprecated and will be removed in a future release.                                                                |
| `mcp_url`                          | string          | false    |              | Deprecated: Injected MCP in AI Bridge is deprecated and will be removed in a future release.                                                                |
| `no_refresh`                       | boolean         | false    |              |                                                                                                                                                             |
|`regex`|string|false||Regex allows API requesters to match an auth config by a string (e.g. coder.com) instead of by it's type.
Git clone makes use of this by parsing the URL from: 'Username for "https://github.com":' And sending it to the Coder server to match against the Regex.|
|`revoke_url`|string|false|||
|`scopes`|array of string|false|||
|`token_url`|string|false|||
|`type`|string|false||Type is the type of external auth config.|
|`validate_url`|string|false|||

## codersdk.ExternalAuthDevice

```json
{
  "device_code": "string",
  "expires_in": 0,
  "interval": 0,
  "user_code": "string",
  "verification_uri": "string"
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description |
|--------------------|---------|----------|--------------|-------------|
| `device_code`      | string  | false    |              |             |
| `expires_in`       | integer | false    |              |             |
| `interval`         | integer | false    |              |             |
| `user_code`        | string  | false    |              |             |
| `verification_uri` | string  | false    |              |             |

## codersdk.ExternalAuthLink

```json
{
  "authenticated": true,
  "created_at": "2019-08-24T14:15:22Z",
  "expires": "2019-08-24T14:15:22Z",
  "has_refresh_token": true,
  "provider_id": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "validate_error": "string"
}
```

### Properties

| Name                | Type    | Required | Restrictions | Description |
|---------------------|---------|----------|--------------|-------------|
| `authenticated`     | boolean | false    |              |             |
| `created_at`        | string  | false    |              |             |
| `expires`           | string  | false    |              |             |
| `has_refresh_token` | boolean | false    |              |             |
| `provider_id`       | string  | false    |              |             |
| `updated_at`        | string  | false    |              |             |
| `validate_error`    | string  | false    |              |             |

## codersdk.ExternalAuthUser

```json
{
  "avatar_url": "string",
  "id": 0,
  "login": "string",
  "name": "string",
  "profile_url": "string"
}
```

### Properties

| Name          | Type    | Required | Restrictions | Description |
|---------------|---------|----------|--------------|-------------|
| `avatar_url`  | string  | false    |              |             |
| `id`          | integer | false    |              |             |
| `login`       | string  | false    |              |             |
| `name`        | string  | false    |              |             |
| `profile_url` | string  | false    |              |             |

## codersdk.Feature

```json
{
  "actual": 0,
  "enabled": true,
  "entitlement": "entitled",
  "limit": 0,
  "usage_period": {
    "end": "2019-08-24T14:15:22Z",
    "issued_at": "2019-08-24T14:15:22Z",
    "start": "2019-08-24T14:15:22Z"
  }
}
```

### Properties

| Name          | Type                                         | Required | Restrictions | Description |
|---------------|----------------------------------------------|----------|--------------|-------------|
| `actual`      | integer                                      | false    |              |             |
| `enabled`     | boolean                                      | false    |              |             |
| `entitlement` | [codersdk.Entitlement](#codersdkentitlement) | false    |              |             |
| `limit`       | integer                                      | false    |              |             |
|`usage_period`|[codersdk.UsagePeriod](#codersdkusageperiod)|false||Usage period denotes that the usage is a counter that accumulates over this period (and most likely resets with the issuance of the next license).
These dates are determined from the license that this entitlement comes from, see enterprise/coderd/license/license.go.
Only certain features set these fields: - FeatureManagedAgentLimit|

## codersdk.FriendlyDiagnostic

```json
{
  "detail": "string",
  "extra": {
    "code": "string"
  },
  "severity": "error",
  "summary": "string"
}
```

### Properties

| Name       | Type                                                                   | Required | Restrictions | Description |
|------------|------------------------------------------------------------------------|----------|--------------|-------------|
| `detail`   | string                                                                 | false    |              |             |
| `extra`    | [codersdk.DiagnosticExtra](#codersdkdiagnosticextra)                   | false    |              |             |
| `severity` | [codersdk.DiagnosticSeverityString](#codersdkdiagnosticseveritystring) | false    |              |             |
| `summary`  | string                                                                 | false    |              |             |

## codersdk.GenerateAPIKeyResponse

```json
{
  "key": "string"
}
```

### Properties

| Name  | Type   | Required | Restrictions | Description |
|-------|--------|----------|--------------|-------------|
| `key` | string | false    |              |             |

## codersdk.GetInboxNotificationResponse

```json
{
  "notification": {
    "actions": [
      {
        "label": "string",
        "url": "string"
      }
    ],
    "content": "string",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "read_at": "string",
    "targets": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "title": "string",
    "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
  },
  "unread_count": 0
}
```

### Properties

| Name           | Type                                                     | Required | Restrictions | Description |
|----------------|----------------------------------------------------------|----------|--------------|-------------|
| `notification` | [codersdk.InboxNotification](#codersdkinboxnotification) | false    |              |             |
| `unread_count` | integer                                                  | false    |              |             |

## codersdk.GetUserStatusCountsResponse

```json
{
  "status_counts": {
    "property1": [
      {
        "count": 10,
        "date": "2019-08-24T14:15:22Z"
      }
    ],
    "property2": [
      {
        "count": 10,
        "date": "2019-08-24T14:15:22Z"
      }
    ]
  }
}
```

### Properties

| Name               | Type                                                                      | Required | Restrictions | Description |
|--------------------|---------------------------------------------------------------------------|----------|--------------|-------------|
| `status_counts`    | object                                                                    | false    |              |             |
| » `[any property]` | array of [codersdk.UserStatusChangeCount](#codersdkuserstatuschangecount) | false    |              |             |

## codersdk.GetUsersResponse

```json
{
  "count": 0,
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "has_ai_seat": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "organization_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "roles": [
        {
          "display_name": "string",
          "name": "string",
          "organization_id": "string"
        }
      ],
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                    | Required | Restrictions | Description |
|---------|-----------------------------------------|----------|--------------|-------------|
| `count` | integer                                 | false    |              |             |
| `users` | array of [codersdk.User](#codersdkuser) | false    |              |             |

## codersdk.GitSSHKey

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "public_key": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Properties

| Name         | Type   | Required | Restrictions | Description                                                                                                                                                                                       |
|--------------|--------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `created_at` | string | false    |              |                                                                                                                                                                                                   |
| `public_key` | string | false    |              | Public key is the SSH public key in OpenSSH format. Example: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID3OmYJvT7q1cF1azbybYy0OZ9yrXfA+M6Lr4vzX5zlp\n" Note: The key includes a trailing newline (\n). |
| `updated_at` | string | false    |              |                                                                                                                                                                                                   |
| `user_id`    | string | false    |              |                                                                                                                                                                                                   |

## codersdk.GithubAuthMethod

```json
{
  "default_provider_configured": true,
  "enabled": true
}
```

### Properties

| Name                          | Type    | Required | Restrictions | Description |
|-------------------------------|---------|----------|--------------|-------------|
| `default_provider_configured` | boolean | false    |              |             |
| `enabled`                     | boolean | false    |              |             |

## codersdk.Group

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "source": "user",
  "total_member_count": 0
}
```

### Properties

| Name                        | Type                                                  | Required | Restrictions | Description                                                                                                                                                           |
|-----------------------------|-------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `avatar_url`                | string                                                | false    |              |                                                                                                                                                                       |
| `display_name`              | string                                                | false    |              |                                                                                                                                                                       |
| `id`                        | string                                                | false    |              |                                                                                                                                                                       |
| `members`                   | array of [codersdk.ReducedUser](#codersdkreduceduser) | false    |              |                                                                                                                                                                       |
| `name`                      | string                                                | false    |              |                                                                                                                                                                       |
| `organization_display_name` | string                                                | false    |              |                                                                                                                                                                       |
| `organization_id`           | string                                                | false    |              |                                                                                                                                                                       |
| `organization_name`         | string                                                | false    |              |                                                                                                                                                                       |
| `quota_allowance`           | integer                                               | false    |              |                                                                                                                                                                       |
| `source`                    | [codersdk.GroupSource](#codersdkgroupsource)          | false    |              |                                                                                                                                                                       |
| `total_member_count`        | integer                                               | false    |              | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |

## codersdk.GroupMembersResponse

```json
{
  "count": 0,
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                                  | Required | Restrictions | Description |
|---------|-------------------------------------------------------|----------|--------------|-------------|
| `count` | integer                                               | false    |              |             |
| `users` | array of [codersdk.ReducedUser](#codersdkreduceduser) | false    |              |             |

## codersdk.GroupSource

```json
"user"
```

### Properties

#### Enumerated Values

| Value(s)       |
|----------------|
| `oidc`, `user` |

## codersdk.GroupSyncSettings

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "legacy_group_name_mapping": {
    "property1": "string",
    "property2": "string"
  },
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "regex_filter": {}
}
```

### Properties

| Name                         | Type                           | Required | Restrictions | Description                                                                                                                                                                                                                                                                            |
|------------------------------|--------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `auto_create_missing_groups` | boolean                        | false    |              | Auto create missing groups controls whether groups returned by the OIDC provider are automatically created in Coder if they are missing.                                                                                                                                               |
| `field`                      | string                         | false    |              | Field is the name of the claim field that specifies what groups a user should be in. If empty, no groups will be synced.                                                                                                                                                               |
| `legacy_group_name_mapping`  | object                         | false    |              | Legacy group name mapping is deprecated. It remaps an IDP group name to a Coder group name. Since configuration is now done at runtime, group IDs are used to account for group renames. For legacy configurations, this config option has to remain. Deprecated: Use Mapping instead. |
| » `[any property]`           | string                         | false    |              |                                                                                                                                                                                                                                                                                        |
| `mapping`                    | object                         | false    |              | Mapping is a map from OIDC groups to Coder group IDs                                                                                                                                                                                                                                   |
| » `[any property]`           | array of string                | false    |              |                                                                                                                                                                                                                                                                                        |
| `regex_filter`               | [regexp.Regexp](#regexpregexp) | false    |              | Regex filter is a regular expression that filters the groups returned by the OIDC provider. Any group not matched by this regex will be ignored. If the group filter is nil, then no group filtering will occur.                                                                       |

## codersdk.HTTPCookieConfig

```json
{
  "host_prefix": true,
  "same_site": "string",
  "secure_auth_cookie": true
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `host_prefix`        | boolean | false    |              |             |
| `same_site`          | string  | false    |              |             |
| `secure_auth_cookie` | boolean | false    |              |             |

## codersdk.Healthcheck

```json
{
  "interval": 0,
  "threshold": 0,
  "url": "string"
}
```

### Properties

| Name        | Type    | Required | Restrictions | Description                                                                                      |
|-------------|---------|----------|--------------|--------------------------------------------------------------------------------------------------|
| `interval`  | integer | false    |              | Interval specifies the seconds between each health check.                                        |
| `threshold` | integer | false    |              | Threshold specifies the number of consecutive failed health checks before returning "unhealthy". |
| `url`       | string  | false    |              | URL specifies the endpoint to check for the app health.                                          |

## codersdk.HealthcheckConfig

```json
{
  "refresh": 0,
  "threshold_database": 0
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `refresh`            | integer | false    |              |             |
| `threshold_database` | integer | false    |              |             |

## codersdk.InboxNotification

```json
{
  "actions": [
    {
      "label": "string",
      "url": "string"
    }
  ],
  "content": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "read_at": "string",
  "targets": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "title": "string",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Properties

| Name          | Type                                                                          | Required | Restrictions | Description |
|---------------|-------------------------------------------------------------------------------|----------|--------------|-------------|
| `actions`     | array of [codersdk.InboxNotificationAction](#codersdkinboxnotificationaction) | false    |              |             |
| `content`     | string                                                                        | false    |              |             |
| `created_at`  | string                                                                        | false    |              |             |
| `icon`        | string                                                                        | false    |              |             |
| `id`          | string                                                                        | false    |              |             |
| `read_at`     | string                                                                        | false    |              |             |
| `targets`     | array of string                                                               | false    |              |             |
| `template_id` | string                                                                        | false    |              |             |
| `title`       | string                                                                        | false    |              |             |
| `user_id`     | string                                                                        | false    |              |             |

## codersdk.InboxNotificationAction

```json
{
  "label": "string",
  "url": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `label` | string | false    |              |             |
| `url`   | string | false    |              |             |

## codersdk.InsightsReportInterval

```json
"day"
```

### Properties

#### Enumerated Values

| Value(s)      |
|---------------|
| `day`, `week` |

## codersdk.InvalidatePresetsResponse

```json
{
  "invalidated": [
    {
      "preset_name": "string",
      "template_name": "string",
      "template_version_name": "string"
    }
  ]
}
```

### Properties

| Name          | Type                                                              | Required | Restrictions | Description |
|---------------|-------------------------------------------------------------------|----------|--------------|-------------|
| `invalidated` | array of [codersdk.InvalidatedPreset](#codersdkinvalidatedpreset) | false    |              |             |

## codersdk.InvalidatedPreset

```json
{
  "preset_name": "string",
  "template_name": "string",
  "template_version_name": "string"
}
```

### Properties

| Name                    | Type   | Required | Restrictions | Description |
|-------------------------|--------|----------|--------------|-------------|
| `preset_name`           | string | false    |              |             |
| `template_name`         | string | false    |              |             |
| `template_version_name` | string | false    |              |             |

## codersdk.IssueReconnectingPTYSignedTokenRequest

```json
{
  "agentID": "bc282582-04f9-45ce-b904-3e3bfab66958",
  "url": "string"
}
```

### Properties

| Name      | Type   | Required | Restrictions | Description                                                            |
|-----------|--------|----------|--------------|------------------------------------------------------------------------|
| `agentID` | string | true     |              |                                                                        |
| `url`     | string | true     |              | URL is the URL of the reconnecting-pty endpoint you are connecting to. |

## codersdk.IssueReconnectingPTYSignedTokenResponse

```json
{
  "signed_token": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `signed_token` | string | false    |              |             |

## codersdk.JobErrorCode

```json
"REQUIRED_TEMPLATE_VARIABLES"
```

### Properties

#### Enumerated Values

| Value(s)                                            |
|-----------------------------------------------------|
| `INSUFFICIENT_QUOTA`, `REQUIRED_TEMPLATE_VARIABLES` |

## codersdk.License

```json
{
  "claims": {},
  "id": 0,
  "uploaded_at": "2019-08-24T14:15:22Z",
  "uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f"
}
```

### Properties

| Name          | Type    | Required | Restrictions | Description                                                                                                                                                                                             |
|---------------|---------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `claims`      | object  | false    |              | Claims are the JWT claims asserted by the license.  Here we use a generic string map to ensure that all data from the server is parsed verbatim, not just the fields this version of Coder understands. |
| `id`          | integer | false    |              |                                                                                                                                                                                                         |
| `uploaded_at` | string  | false    |              |                                                                                                                                                                                                         |
| `uuid`        | string  | false    |              |                                                                                                                                                                                                         |

## codersdk.LinkConfig

```json
{
  "icon": "bug",
  "location": "navbar",
  "name": "string",
  "target": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `icon`     | string | false    |              |             |
| `location` | string | false    |              |             |
| `name`     | string | false    |              |             |
| `target`   | string | false    |              |             |

#### Enumerated Values

| Property   | Value(s)                      |
|------------|-------------------------------|
| `icon`     | `bug`, `chat`, `docs`, `star` |
| `location` | `dropdown`, `navbar`          |

## codersdk.ListInboxNotificationsResponse

```json
{
  "notifications": [
    {
      "actions": [
        {
          "label": "string",
          "url": "string"
        }
      ],
      "content": "string",
      "created_at": "2019-08-24T14:15:22Z",
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "read_at": "string",
      "targets": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "title": "string",
      "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
    }
  ],
  "unread_count": 0
}
```

### Properties

| Name            | Type                                                              | Required | Restrictions | Description |
|-----------------|-------------------------------------------------------------------|----------|--------------|-------------|
| `notifications` | array of [codersdk.InboxNotification](#codersdkinboxnotification) | false    |              |             |
| `unread_count`  | integer                                                           | false    |              |             |

## codersdk.LogLevel

```json
"trace"
```

### Properties

#### Enumerated Values

| Value(s)                                  |
|-------------------------------------------|
| `debug`, `error`, `info`, `trace`, `warn` |

## codersdk.LogSource

```json
"provisioner_daemon"
```

### Properties

#### Enumerated Values

| Value(s)                            |
|-------------------------------------|
| `provisioner`, `provisioner_daemon` |

## codersdk.LoggingConfig

```json
{
  "human": "string",
  "json": "string",
  "log_filter": [
    "string"
  ],
  "stackdriver": "string"
}
```

### Properties

| Name          | Type            | Required | Restrictions | Description |
|---------------|-----------------|----------|--------------|-------------|
| `human`       | string          | false    |              |             |
| `json`        | string          | false    |              |             |
| `log_filter`  | array of string | false    |              |             |
| `stackdriver` | string          | false    |              |             |

## codersdk.LoginType

```json
""
```

### Properties

#### Enumerated Values

| Value(s)                                          |
|---------------------------------------------------|
| ``, `github`, `none`, `oidc`, `password`, `token` |

## codersdk.LoginWithPasswordRequest

```json
{
  "email": "user@example.com",
  "password": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `email`    | string | true     |              |             |
| `password` | string | true     |              |             |

## codersdk.LoginWithPasswordResponse

```json
{
  "session_token": "string"
}
```

### Properties

| Name            | Type   | Required | Restrictions | Description |
|-----------------|--------|----------|--------------|-------------|
| `session_token` | string | true     |              |             |

## codersdk.MatchedProvisioners

```json
{
  "available": 0,
  "count": 0,
  "most_recently_seen": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description                                                                                                                                                         |
|----------------------|---------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `available`          | integer | false    |              | Available is the number of provisioner daemons that are available to take jobs. This may be less than the count if some provisioners are busy or have been stopped. |
| `count`              | integer | false    |              | Count is the number of provisioner daemons that matched the given tags. If the count is 0, it means no provisioner daemons matched the requested tags.              |
| `most_recently_seen` | string  | false    |              | Most recently seen is the most recently seen time of the set of matched provisioners. If no provisioners matched, this field will be null.                          |

## codersdk.MinimalOrganization

```json
{
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `display_name` | string | false    |              |             |
| `icon`         | string | false    |              |             |
| `id`           | string | true     |              |             |
| `name`         | string | false    |              |             |

## codersdk.MinimalUser

```json
{
  "avatar_url": "http://example.com",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "username": "string"
}
```

### Properties

| Name         | Type   | Required | Restrictions | Description |
|--------------|--------|----------|--------------|-------------|
| `avatar_url` | string | false    |              |             |
| `id`         | string | true     |              |             |
| `name`       | string | false    |              |             |
| `username`   | string | true     |              |             |

## codersdk.NotificationMethodsResponse

```json
{
  "available": [
    "string"
  ],
  "default": "string"
}
```

### Properties

| Name        | Type            | Required | Restrictions | Description |
|-------------|-----------------|----------|--------------|-------------|
| `available` | array of string | false    |              |             |
| `default`   | string          | false    |              |             |

## codersdk.NotificationPreference

```json
{
  "disabled": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name         | Type    | Required | Restrictions | Description |
|--------------|---------|----------|--------------|-------------|
| `disabled`   | boolean | false    |              |             |
| `id`         | string  | false    |              |             |
| `updated_at` | string  | false    |              |             |

## codersdk.NotificationTemplate

```json
{
  "actions": "string",
  "body_template": "string",
  "enabled_by_default": true,
  "group": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "kind": "string",
  "method": "string",
  "name": "string",
  "title_template": "string"
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `actions`            | string  | false    |              |             |
| `body_template`      | string  | false    |              |             |
| `enabled_by_default` | boolean | false    |              |             |
| `group`              | string  | false    |              |             |
| `id`                 | string  | false    |              |             |
| `kind`               | string  | false    |              |             |
| `method`             | string  | false    |              |             |
| `name`               | string  | false    |              |             |
| `title_template`     | string  | false    |              |             |

## codersdk.NotificationsConfig

```json
{
  "dispatch_timeout": 0,
  "email": {
    "auth": {
      "identity": "string",
      "password": "string",
      "password_file": "string",
      "username": "string"
    },
    "force_tls": true,
    "from": "string",
    "hello": "string",
    "smarthost": "string",
    "tls": {
      "ca_file": "string",
      "cert_file": "string",
      "insecure_skip_verify": true,
      "key_file": "string",
      "server_name": "string",
      "start_tls": true
    }
  },
  "fetch_interval": 0,
  "inbox": {
    "enabled": true
  },
  "lease_count": 0,
  "lease_period": 0,
  "max_send_attempts": 0,
  "method": "string",
  "retry_interval": 0,
  "sync_buffer_size": 0,
  "sync_interval": 0,
  "webhook": {
    "endpoint": {
      "forceQuery": true,
      "fragment": "string",
      "host": "string",
      "omitHost": true,
      "opaque": "string",
      "path": "string",
      "rawFragment": "string",
      "rawPath": "string",
      "rawQuery": "string",
      "scheme": "string",
      "user": {}
    }
  }
}
```

### Properties

| Name                | Type                                                                       | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|---------------------|----------------------------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `dispatch_timeout`  | integer                                                                    | false    |              | How long to wait while a notification is being sent before giving up.                                                                                                                                                                                                                                                                                                                                                                               |
| `email`             | [codersdk.NotificationsEmailConfig](#codersdknotificationsemailconfig)     | false    |              | Email settings.                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `fetch_interval`    | integer                                                                    | false    |              | How often to query the database for queued notifications.                                                                                                                                                                                                                                                                                                                                                                                           |
| `inbox`             | [codersdk.NotificationsInboxConfig](#codersdknotificationsinboxconfig)     | false    |              | Inbox settings.                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `lease_count`       | integer                                                                    | false    |              | How many notifications a notifier should lease per fetch interval.                                                                                                                                                                                                                                                                                                                                                                                  |
| `lease_period`      | integer                                                                    | false    |              | How long a notifier should lease a message. This is effectively how long a notification is 'owned' by a notifier, and once this period expires it will be available for lease by another notifier. Leasing is important in order for multiple running notifiers to not pick the same messages to deliver concurrently. This lease period will only expire if a notifier shuts down ungracefully; a dispatch of the notification releases the lease. |
| `max_send_attempts` | integer                                                                    | false    |              | The upper limit of attempts to send a notification.                                                                                                                                                                                                                                                                                                                                                                                                 |
| `method`            | string                                                                     | false    |              | Which delivery method to use (available options: 'smtp', 'webhook').                                                                                                                                                                                                                                                                                                                                                                                |
| `retry_interval`    | integer                                                                    | false    |              | The minimum time between retries.                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `sync_buffer_size`  | integer                                                                    | false    |              | The notifications system buffers message updates in memory to ease pressure on the database. This option controls how many updates are kept in memory. The lower this value the lower the change of state inconsistency in a non-graceful shutdown - but it also increases load on the database. It is recommended to keep this option at its default value.                                                                                        |
| `sync_interval`     | integer                                                                    | false    |              | The notifications system buffers message updates in memory to ease pressure on the database. This option controls how often it synchronizes its state with the database. The shorter this value the lower the change of state inconsistency in a non-graceful shutdown - but it also increases load on the database. It is recommended to keep this option at its default value.                                                                    |
| `webhook`           | [codersdk.NotificationsWebhookConfig](#codersdknotificationswebhookconfig) | false    |              | Webhook settings.                                                                                                                                                                                                                                                                                                                                                                                                                                   |

## codersdk.NotificationsEmailAuthConfig

```json
{
  "identity": "string",
  "password": "string",
  "password_file": "string",
  "username": "string"
}
```

### Properties

| Name            | Type   | Required | Restrictions | Description                                                |
|-----------------|--------|----------|--------------|------------------------------------------------------------|
| `identity`      | string | false    |              | Identity for PLAIN auth.                                   |
| `password`      | string | false    |              | Password for LOGIN/PLAIN auth.                             |
| `password_file` | string | false    |              | File from which to load the password for LOGIN/PLAIN auth. |
| `username`      | string | false    |              | Username for LOGIN/PLAIN auth.                             |

## codersdk.NotificationsEmailConfig

```json
{
  "auth": {
    "identity": "string",
    "password": "string",
    "password_file": "string",
    "username": "string"
  },
  "force_tls": true,
  "from": "string",
  "hello": "string",
  "smarthost": "string",
  "tls": {
    "ca_file": "string",
    "cert_file": "string",
    "insecure_skip_verify": true,
    "key_file": "string",
    "server_name": "string",
    "start_tls": true
  }
}
```

### Properties

| Name        | Type                                                                           | Required | Restrictions | Description                                                           |
|-------------|--------------------------------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------|
| `auth`      | [codersdk.NotificationsEmailAuthConfig](#codersdknotificationsemailauthconfig) | false    |              | Authentication details.                                               |
| `force_tls` | boolean                                                                        | false    |              | Force tls causes a TLS connection to be attempted.                    |
| `from`      | string                                                                         | false    |              | The sender's address.                                                 |
| `hello`     | string                                                                         | false    |              | The hostname identifying the SMTP server.                             |
| `smarthost` | string                                                                         | false    |              | The intermediary SMTP host through which emails are sent (host:port). |
| `tls`       | [codersdk.NotificationsEmailTLSConfig](#codersdknotificationsemailtlsconfig)   | false    |              | Tls details.                                                          |

## codersdk.NotificationsEmailTLSConfig

```json
{
  "ca_file": "string",
  "cert_file": "string",
  "insecure_skip_verify": true,
  "key_file": "string",
  "server_name": "string",
  "start_tls": true
}
```

### Properties

| Name                   | Type    | Required | Restrictions | Description                                                  |
|------------------------|---------|----------|--------------|--------------------------------------------------------------|
| `ca_file`              | string  | false    |              | Ca file specifies the location of the CA certificate to use. |
| `cert_file`            | string  | false    |              | Cert file specifies the location of the certificate to use.  |
| `insecure_skip_verify` | boolean | false    |              | Insecure skip verify skips target certificate validation.    |
| `key_file`             | string  | false    |              | Key file specifies the location of the key to use.           |
| `server_name`          | string  | false    |              | Server name to verify the hostname for the targets.          |
| `start_tls`            | boolean | false    |              | Start tls attempts to upgrade plain connections to TLS.      |

## codersdk.NotificationsInboxConfig

```json
{
  "enabled": true
}
```

### Properties

| Name      | Type    | Required | Restrictions | Description |
|-----------|---------|----------|--------------|-------------|
| `enabled` | boolean | false    |              |             |

## codersdk.NotificationsSettings

```json
{
  "notifier_paused": true
}
```

### Properties

| Name              | Type    | Required | Restrictions | Description |
|-------------------|---------|----------|--------------|-------------|
| `notifier_paused` | boolean | false    |              |             |

## codersdk.NotificationsWebhookConfig

```json
{
  "endpoint": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  }
}
```

### Properties

| Name       | Type                       | Required | Restrictions | Description                                                          |
|------------|----------------------------|----------|--------------|----------------------------------------------------------------------|
| `endpoint` | [serpent.URL](#serpenturl) | false    |              | The URL to which the payload will be sent with an HTTP POST request. |

## codersdk.NullHCLString

```json
{
  "valid": true,
  "value": "string"
}
```

### Properties

| Name    | Type    | Required | Restrictions | Description |
|---------|---------|----------|--------------|-------------|
| `valid` | boolean | false    |              |             |
| `value` | string  | false    |              |             |

## codersdk.OAuth2AppEndpoints

```json
{
  "authorization": "string",
  "device_authorization": "string",
  "token": "string",
  "token_revoke": "string"
}
```

### Properties

| Name                   | Type   | Required | Restrictions | Description                       |
|------------------------|--------|----------|--------------|-----------------------------------|
| `authorization`        | string | false    |              |                                   |
| `device_authorization` | string | false    |              | Device authorization is optional. |
| `token`                | string | false    |              |                                   |
| `token_revoke`         | string | false    |              |                                   |

## codersdk.OAuth2AuthorizationServerMetadata

```json
{
  "authorization_endpoint": "string",
  "code_challenge_methods_supported": [
    "S256"
  ],
  "grant_types_supported": [
    "authorization_code"
  ],
  "issuer": "string",
  "registration_endpoint": "string",
  "response_types_supported": [
    "code"
  ],
  "revocation_endpoint": "string",
  "scopes_supported": [
    "string"
  ],
  "token_endpoint": "string",
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic"
  ]
}
```

### Properties

| Name                                    | Type                                                                                      | Required | Restrictions | Description |
|-----------------------------------------|-------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `authorization_endpoint`                | string                                                                                    | false    |              |             |
| `code_challenge_methods_supported`      | array of [codersdk.OAuth2PKCECodeChallengeMethod](#codersdkoauth2pkcecodechallengemethod) | false    |              |             |
| `grant_types_supported`                 | array of [codersdk.OAuth2ProviderGrantType](#codersdkoauth2providergranttype)             | false    |              |             |
| `issuer`                                | string                                                                                    | false    |              |             |
| `registration_endpoint`                 | string                                                                                    | false    |              |             |
| `response_types_supported`              | array of [codersdk.OAuth2ProviderResponseType](#codersdkoauth2providerresponsetype)       | false    |              |             |
| `revocation_endpoint`                   | string                                                                                    | false    |              |             |
| `scopes_supported`                      | array of string                                                                           | false    |              |             |
| `token_endpoint`                        | string                                                                                    | false    |              |             |
| `token_endpoint_auth_methods_supported` | array of [codersdk.OAuth2TokenEndpointAuthMethod](#codersdkoauth2tokenendpointauthmethod) | false    |              |             |

## codersdk.OAuth2ClientConfiguration

```json
{
  "client_id": "string",
  "client_id_issued_at": 0,
  "client_name": "string",
  "client_secret_expires_at": 0,
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "registration_access_token": "string",
  "registration_client_uri": "string",
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Properties

| Name                         | Type                                                                                | Required | Restrictions | Description |
|------------------------------|-------------------------------------------------------------------------------------|----------|--------------|-------------|
| `client_id`                  | string                                                                              | false    |              |             |
| `client_id_issued_at`        | integer                                                                             | false    |              |             |
| `client_name`                | string                                                                              | false    |              |             |
| `client_secret_expires_at`   | integer                                                                             | false    |              |             |
| `client_uri`                 | string                                                                              | false    |              |             |
| `contacts`                   | array of string                                                                     | false    |              |             |
| `grant_types`                | array of [codersdk.OAuth2ProviderGrantType](#codersdkoauth2providergranttype)       | false    |              |             |
| `jwks`                       | object                                                                              | false    |              |             |
| `jwks_uri`                   | string                                                                              | false    |              |             |
| `logo_uri`                   | string                                                                              | false    |              |             |
| `policy_uri`                 | string                                                                              | false    |              |             |
| `redirect_uris`              | array of string                                                                     | false    |              |             |
| `registration_access_token`  | string                                                                              | false    |              |             |
| `registration_client_uri`    | string                                                                              | false    |              |             |
| `response_types`             | array of [codersdk.OAuth2ProviderResponseType](#codersdkoauth2providerresponsetype) | false    |              |             |
| `scope`                      | string                                                                              | false    |              |             |
| `software_id`                | string                                                                              | false    |              |             |
| `software_version`           | string                                                                              | false    |              |             |
| `token_endpoint_auth_method` | [codersdk.OAuth2TokenEndpointAuthMethod](#codersdkoauth2tokenendpointauthmethod)    | false    |              |             |
| `tos_uri`                    | string                                                                              | false    |              |             |

## codersdk.OAuth2ClientRegistrationRequest

```json
{
  "client_name": "string",
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_statement": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Properties

| Name                         | Type                                                                                | Required | Restrictions | Description |
|------------------------------|-------------------------------------------------------------------------------------|----------|--------------|-------------|
| `client_name`                | string                                                                              | false    |              |             |
| `client_uri`                 | string                                                                              | false    |              |             |
| `contacts`                   | array of string                                                                     | false    |              |             |
| `grant_types`                | array of [codersdk.OAuth2ProviderGrantType](#codersdkoauth2providergranttype)       | false    |              |             |
| `jwks`                       | object                                                                              | false    |              |             |
| `jwks_uri`                   | string                                                                              | false    |              |             |
| `logo_uri`                   | string                                                                              | false    |              |             |
| `policy_uri`                 | string                                                                              | false    |              |             |
| `redirect_uris`              | array of string                                                                     | false    |              |             |
| `response_types`             | array of [codersdk.OAuth2ProviderResponseType](#codersdkoauth2providerresponsetype) | false    |              |             |
| `scope`                      | string                                                                              | false    |              |             |
| `software_id`                | string                                                                              | false    |              |             |
| `software_statement`         | string                                                                              | false    |              |             |
| `software_version`           | string                                                                              | false    |              |             |
| `token_endpoint_auth_method` | [codersdk.OAuth2TokenEndpointAuthMethod](#codersdkoauth2tokenendpointauthmethod)    | false    |              |             |
| `tos_uri`                    | string                                                                              | false    |              |             |

## codersdk.OAuth2ClientRegistrationResponse

```json
{
  "client_id": "string",
  "client_id_issued_at": 0,
  "client_name": "string",
  "client_secret": "string",
  "client_secret_expires_at": 0,
  "client_uri": "string",
  "contacts": [
    "string"
  ],
  "grant_types": [
    "authorization_code"
  ],
  "jwks": {},
  "jwks_uri": "string",
  "logo_uri": "string",
  "policy_uri": "string",
  "redirect_uris": [
    "string"
  ],
  "registration_access_token": "string",
  "registration_client_uri": "string",
  "response_types": [
    "code"
  ],
  "scope": "string",
  "software_id": "string",
  "software_version": "string",
  "token_endpoint_auth_method": "client_secret_basic",
  "tos_uri": "string"
}
```

### Properties

| Name                         | Type                                                                                | Required | Restrictions | Description |
|------------------------------|-------------------------------------------------------------------------------------|----------|--------------|-------------|
| `client_id`                  | string                                                                              | false    |              |             |
| `client_id_issued_at`        | integer                                                                             | false    |              |             |
| `client_name`                | string                                                                              | false    |              |             |
| `client_secret`              | string                                                                              | false    |              |             |
| `client_secret_expires_at`   | integer                                                                             | false    |              |             |
| `client_uri`                 | string                                                                              | false    |              |             |
| `contacts`                   | array of string                                                                     | false    |              |             |
| `grant_types`                | array of [codersdk.OAuth2ProviderGrantType](#codersdkoauth2providergranttype)       | false    |              |             |
| `jwks`                       | object                                                                              | false    |              |             |
| `jwks_uri`                   | string                                                                              | false    |              |             |
| `logo_uri`                   | string                                                                              | false    |              |             |
| `policy_uri`                 | string                                                                              | false    |              |             |
| `redirect_uris`              | array of string                                                                     | false    |              |             |
| `registration_access_token`  | string                                                                              | false    |              |             |
| `registration_client_uri`    | string                                                                              | false    |              |             |
| `response_types`             | array of [codersdk.OAuth2ProviderResponseType](#codersdkoauth2providerresponsetype) | false    |              |             |
| `scope`                      | string                                                                              | false    |              |             |
| `software_id`                | string                                                                              | false    |              |             |
| `software_version`           | string                                                                              | false    |              |             |
| `token_endpoint_auth_method` | [codersdk.OAuth2TokenEndpointAuthMethod](#codersdkoauth2tokenendpointauthmethod)    | false    |              |             |
| `tos_uri`                    | string                                                                              | false    |              |             |

## codersdk.OAuth2Config

```json
{
  "github": {
    "allow_everyone": true,
    "allow_signups": true,
    "allowed_orgs": [
      "string"
    ],
    "allowed_teams": [
      "string"
    ],
    "client_id": "string",
    "client_secret": "string",
    "default_provider_enable": true,
    "device_flow": true,
    "enterprise_base_url": "string"
  }
}
```

### Properties

| Name     | Type                                                       | Required | Restrictions | Description |
|----------|------------------------------------------------------------|----------|--------------|-------------|
| `github` | [codersdk.OAuth2GithubConfig](#codersdkoauth2githubconfig) | false    |              |             |

## codersdk.OAuth2GithubConfig

```json
{
  "allow_everyone": true,
  "allow_signups": true,
  "allowed_orgs": [
    "string"
  ],
  "allowed_teams": [
    "string"
  ],
  "client_id": "string",
  "client_secret": "string",
  "default_provider_enable": true,
  "device_flow": true,
  "enterprise_base_url": "string"
}
```

### Properties

| Name                      | Type            | Required | Restrictions | Description |
|---------------------------|-----------------|----------|--------------|-------------|
| `allow_everyone`          | boolean         | false    |              |             |
| `allow_signups`           | boolean         | false    |              |             |
| `allowed_orgs`            | array of string | false    |              |             |
| `allowed_teams`           | array of string | false    |              |             |
| `client_id`               | string          | false    |              |             |
| `client_secret`           | string          | false    |              |             |
| `default_provider_enable` | boolean         | false    |              |             |
| `device_flow`             | boolean         | false    |              |             |
| `enterprise_base_url`     | string          | false    |              |             |

## codersdk.OAuth2PKCECodeChallengeMethod

```json
"S256"
```

### Properties

#### Enumerated Values

| Value(s)        |
|-----------------|
| `S256`, `plain` |

## codersdk.OAuth2ProtectedResourceMetadata

```json
{
  "authorization_servers": [
    "string"
  ],
  "bearer_methods_supported": [
    "string"
  ],
  "resource": "string",
  "scopes_supported": [
    "string"
  ]
}
```

### Properties

| Name                       | Type            | Required | Restrictions | Description |
|----------------------------|-----------------|----------|--------------|-------------|
| `authorization_servers`    | array of string | false    |              |             |
| `bearer_methods_supported` | array of string | false    |              |             |
| `resource`                 | string          | false    |              |             |
| `scopes_supported`         | array of string | false    |              |             |

## codersdk.OAuth2ProviderApp

```json
{
  "callback_url": "string",
  "endpoints": {
    "authorization": "string",
    "device_authorization": "string",
    "token": "string",
    "token_revoke": "string"
  },
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string"
}
```

### Properties

| Name           | Type                                                       | Required | Restrictions | Description                                                                                                                                                                                             |
|----------------|------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `callback_url` | string                                                     | false    |              |                                                                                                                                                                                                         |
| `endpoints`    | [codersdk.OAuth2AppEndpoints](#codersdkoauth2appendpoints) | false    |              | Endpoints are included in the app response for easier discovery. The OAuth2 spec does not have a defined place to find these (for comparison, OIDC has a '/.well-known/openid-configuration' endpoint). |
| `icon`         | string                                                     | false    |              |                                                                                                                                                                                                         |
| `id`           | string                                                     | false    |              |                                                                                                                                                                                                         |
| `name`         | string                                                     | false    |              |                                                                                                                                                                                                         |

## codersdk.OAuth2ProviderAppSecret

```json
{
  "client_secret_truncated": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "last_used_at": "string"
}
```

### Properties

| Name                      | Type   | Required | Restrictions | Description |
|---------------------------|--------|----------|--------------|-------------|
| `client_secret_truncated` | string | false    |              |             |
| `id`                      | string | false    |              |             |
| `last_used_at`            | string | false    |              |             |

## codersdk.OAuth2ProviderAppSecretFull

```json
{
  "client_secret_full": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}
```

### Properties

| Name                 | Type   | Required | Restrictions | Description |
|----------------------|--------|----------|--------------|-------------|
| `client_secret_full` | string | false    |              |             |
| `id`                 | string | false    |              |             |

## codersdk.OAuth2ProviderGrantType

```json
"authorization_code"
```

### Properties

#### Enumerated Values

| Value(s)                                                                            |
|-------------------------------------------------------------------------------------|
| `authorization_code`, `client_credentials`, `implicit`, `password`, `refresh_token` |

## codersdk.OAuth2ProviderResponseType

```json
"code"
```

### Properties

#### Enumerated Values

| Value(s)        |
|-----------------|
| `code`, `token` |

## codersdk.OAuth2TokenEndpointAuthMethod

```json
"client_secret_basic"
```

### Properties

#### Enumerated Values

| Value(s)                                            |
|-----------------------------------------------------|
| `client_secret_basic`, `client_secret_post`, `none` |

## codersdk.OAuthConversionResponse

```json
{
  "expires_at": "2019-08-24T14:15:22Z",
  "state_string": "string",
  "to_type": "",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Properties

| Name           | Type                                     | Required | Restrictions | Description |
|----------------|------------------------------------------|----------|--------------|-------------|
| `expires_at`   | string                                   | false    |              |             |
| `state_string` | string                                   | false    |              |             |
| `to_type`      | [codersdk.LoginType](#codersdklogintype) | false    |              |             |
| `user_id`      | string                                   | false    |              |             |

## codersdk.OIDCAuthMethod

```json
{
  "enabled": true,
  "iconUrl": "string",
  "signInText": "string"
}
```

### Properties

| Name         | Type    | Required | Restrictions | Description |
|--------------|---------|----------|--------------|-------------|
| `enabled`    | boolean | false    |              |             |
| `iconUrl`    | string  | false    |              |             |
| `signInText` | string  | false    |              |             |

## codersdk.OIDCClaimsResponse

```json
{
  "claims": {}
}
```

### Properties

| Name     | Type   | Required | Restrictions | Description                                                                                                                                                                 |
|----------|--------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `claims` | object | false    |              | Claims are the merged claims from the OIDC provider. These are the union of the ID token claims and the userinfo claims, where userinfo claims take precedence on conflict. |

## codersdk.OIDCConfig

```json
{
  "allow_signups": true,
  "auth_url_params": {},
  "client_cert_file": "string",
  "client_id": "string",
  "client_key_file": "string",
  "client_secret": "string",
  "email_domain": [
    "string"
  ],
  "email_field": "string",
  "group_allow_list": [
    "string"
  ],
  "group_auto_create": true,
  "group_mapping": {},
  "group_regex_filter": {},
  "groups_field": "string",
  "icon_url": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  },
  "ignore_email_verified": true,
  "ignore_user_info": true,
  "issuer_url": "string",
  "name_field": "string",
  "organization_assign_default": true,
  "organization_field": "string",
  "organization_mapping": {},
  "redirect_url": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  },
  "scopes": [
    "string"
  ],
  "sign_in_text": "string",
  "signups_disabled_text": "string",
  "skip_issuer_checks": true,
  "source_user_info_from_access_token": true,
  "user_role_field": "string",
  "user_role_mapping": {},
  "user_roles_default": [
    "string"
  ],
  "username_field": "string"
}
```

### Properties

| Name                                 | Type                             | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                                                                        |
|--------------------------------------|----------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `allow_signups`                      | boolean                          | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `auth_url_params`                    | object                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `client_cert_file`                   | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `client_id`                          | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `client_key_file`                    | string                           | false    |              | Client key file & ClientCertFile are used in place of ClientSecret for PKI auth.                                                                                                                                                                                                                                                                                   |
| `client_secret`                      | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `email_domain`                       | array of string                  | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `email_field`                        | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `group_allow_list`                   | array of string                  | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `group_auto_create`                  | boolean                          | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `group_mapping`                      | object                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `group_regex_filter`                 | [serpent.Regexp](#serpentregexp) | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `groups_field`                       | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `icon_url`                           | [serpent.URL](#serpenturl)       | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `ignore_email_verified`              | boolean                          | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `ignore_user_info`                   | boolean                          | false    |              | Ignore user info & UserInfoFromAccessToken are mutually exclusive. Only 1 can be set to true. Ideally this would be an enum with 3 states, ['none', 'userinfo', 'access_token']. However, for backward compatibility, `ignore_user_info` must remain. And `access_token` is a niche, non-spec compliant edge case. So it's use is rare, and should not be advised. |
| `issuer_url`                         | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `name_field`                         | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `organization_assign_default`        | boolean                          | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `organization_field`                 | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `organization_mapping`               | object                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `redirect_url`                       | [serpent.URL](#serpenturl)       | false    |              | Redirect URL is optional, defaulting to 'ACCESS_URL'. Only useful in niche situations where the OIDC callback domain is different from the ACCESS_URL domain.                                                                                                                                                                                                      |
| `scopes`                             | array of string                  | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `sign_in_text`                       | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `signups_disabled_text`              | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `skip_issuer_checks`                 | boolean                          | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `source_user_info_from_access_token` | boolean                          | false    |              | Source user info from access token as mentioned above is an edge case. This allows sourcing the user_info from the access token itself instead of a user_info endpoint. This assumes the access token is a valid JWT with a set of claims to be merged with the id_token.                                                                                          |
| `user_role_field`                    | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `user_role_mapping`                  | object                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `user_roles_default`                 | array of string                  | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |
| `username_field`                     | string                           | false    |              |                                                                                                                                                                                                                                                                                                                                                                    |

## codersdk.OptionType

```json
"string"
```

### Properties

#### Enumerated Values

| Value(s)                                   |
|--------------------------------------------|
| `bool`, `list(string)`, `number`, `string` |

## codersdk.Organization

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_default": true,
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name           | Type    | Required | Restrictions | Description |
|----------------|---------|----------|--------------|-------------|
| `created_at`   | string  | true     |              |             |
| `description`  | string  | false    |              |             |
| `display_name` | string  | false    |              |             |
| `icon`         | string  | false    |              |             |
| `id`           | string  | true     |              |             |
| `is_default`   | boolean | true     |              |             |
| `name`         | string  | false    |              |             |
| `updated_at`   | string  | true     |              |             |

## codersdk.OrganizationMember

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Properties

| Name              | Type                                            | Required | Restrictions | Description |
|-------------------|-------------------------------------------------|----------|--------------|-------------|
| `created_at`      | string                                          | false    |              |             |
| `organization_id` | string                                          | false    |              |             |
| `roles`           | array of [codersdk.SlimRole](#codersdkslimrole) | false    |              |             |
| `updated_at`      | string                                          | false    |              |             |
| `user_id`         | string                                          | false    |              |             |

## codersdk.OrganizationMemberWithUserData

```json
{
  "avatar_url": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "string",
  "global_roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "has_ai_seat": true,
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_created_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
  "user_updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Properties

| Name                 | Type                                            | Required | Restrictions | Description                                                                                      |
|----------------------|-------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------|
| `avatar_url`         | string                                          | false    |              |                                                                                                  |
| `created_at`         | string                                          | false    |              |                                                                                                  |
| `email`              | string                                          | false    |              |                                                                                                  |
| `global_roles`       | array of [codersdk.SlimRole](#codersdkslimrole) | false    |              |                                                                                                  |
| `has_ai_seat`        | boolean                                         | false    |              | Has ai seat intentionally omits omitempty so the API always includes the field, even when false. |
| `is_service_account` | boolean                                         | false    |              |                                                                                                  |
| `last_seen_at`       | string                                          | false    |              |                                                                                                  |
| `login_type`         | [codersdk.LoginType](#codersdklogintype)        | false    |              |                                                                                                  |
| `name`               | string                                          | false    |              |                                                                                                  |
| `organization_id`    | string                                          | false    |              |                                                                                                  |
| `roles`              | array of [codersdk.SlimRole](#codersdkslimrole) | false    |              |                                                                                                  |
| `status`             | [codersdk.UserStatus](#codersdkuserstatus)      | false    |              |                                                                                                  |
| `updated_at`         | string                                          | false    |              |                                                                                                  |
| `user_created_at`    | string                                          | false    |              |                                                                                                  |
| `user_id`            | string                                          | false    |              |                                                                                                  |
| `user_updated_at`    | string                                          | false    |              |                                                                                                  |
| `username`           | string                                          | false    |              |                                                                                                  |

#### Enumerated Values

| Property | Value(s)              |
|----------|-----------------------|
| `status` | `active`, `suspended` |

## codersdk.OrganizationSyncSettings

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  },
  "organization_assign_default": true
}
```

### Properties

| Name                          | Type            | Required | Restrictions | Description                                                                                                                                                                         |
|-------------------------------|-----------------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `field`                       | string          | false    |              | Field selects the claim field to be used as the created user's organizations. If the field is the empty string, then no organization updates will ever come from the OIDC provider. |
| `mapping`                     | object          | false    |              | Mapping maps from an OIDC claim --> Coder organization uuid                                                                                                                         |
| » `[any property]`            | array of string | false    |              |                                                                                                                                                                                     |
| `organization_assign_default` | boolean         | false    |              | Organization assign default will ensure the default org is always included for every user, regardless of their claims. This preserves legacy behavior.                              |

## codersdk.PRInsightsModelBreakdown

```json
{
  "cost_per_merged_pr_micros": 0,
  "display_name": "string",
  "merge_rate": 0,
  "merged_prs": 0,
  "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
  "provider": "string",
  "total_additions": 0,
  "total_cost_micros": 0,
  "total_deletions": 0,
  "total_prs": 0
}
```

### Properties

| Name                        | Type    | Required | Restrictions | Description |
|-----------------------------|---------|----------|--------------|-------------|
| `cost_per_merged_pr_micros` | integer | false    |              |             |
| `display_name`              | string  | false    |              |             |
| `merge_rate`                | number  | false    |              |             |
| `merged_prs`                | integer | false    |              |             |
| `model_config_id`           | string  | false    |              |             |
| `provider`                  | string  | false    |              |             |
| `total_additions`           | integer | false    |              |             |
| `total_cost_micros`         | integer | false    |              |             |
| `total_deletions`           | integer | false    |              |             |
| `total_prs`                 | integer | false    |              |             |

## codersdk.PRInsightsPullRequest

```json
{
  "additions": 0,
  "approved": true,
  "author_avatar_url": "string",
  "author_login": "string",
  "base_branch": "string",
  "changed_files": 0,
  "changes_requested": true,
  "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
  "commits": 0,
  "cost_micros": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "deletions": 0,
  "draft": true,
  "model_display_name": "string",
  "pr_number": 0,
  "pr_title": "string",
  "pr_url": "string",
  "reviewer_count": 0,
  "state": "string"
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `additions`          | integer | false    |              |             |
| `approved`           | boolean | false    |              |             |
| `author_avatar_url`  | string  | false    |              |             |
| `author_login`       | string  | false    |              |             |
| `base_branch`        | string  | false    |              |             |
| `changed_files`      | integer | false    |              |             |
| `changes_requested`  | boolean | false    |              |             |
| `chat_id`            | string  | false    |              |             |
| `commits`            | integer | false    |              |             |
| `cost_micros`        | integer | false    |              |             |
| `created_at`         | string  | false    |              |             |
| `deletions`          | integer | false    |              |             |
| `draft`              | boolean | false    |              |             |
| `model_display_name` | string  | false    |              |             |
| `pr_number`          | integer | false    |              |             |
| `pr_title`           | string  | false    |              |             |
| `pr_url`             | string  | false    |              |             |
| `reviewer_count`     | integer | false    |              |             |
| `state`              | string  | false    |              |             |

## codersdk.PRInsightsResponse

```json
{
  "by_model": [
    {
      "cost_per_merged_pr_micros": 0,
      "display_name": "string",
      "merge_rate": 0,
      "merged_prs": 0,
      "model_config_id": "f5fb4d91-62ca-4377-9ee6-5d43ba00d205",
      "provider": "string",
      "total_additions": 0,
      "total_cost_micros": 0,
      "total_deletions": 0,
      "total_prs": 0
    }
  ],
  "recent_prs": [
    {
      "additions": 0,
      "approved": true,
      "author_avatar_url": "string",
      "author_login": "string",
      "base_branch": "string",
      "changed_files": 0,
      "changes_requested": true,
      "chat_id": "efc9fe20-a1e5-4a8c-9c48-f1b30c1e4f86",
      "commits": 0,
      "cost_micros": 0,
      "created_at": "2019-08-24T14:15:22Z",
      "deletions": 0,
      "draft": true,
      "model_display_name": "string",
      "pr_number": 0,
      "pr_title": "string",
      "pr_url": "string",
      "reviewer_count": 0,
      "state": "string"
    }
  ],
  "summary": {
    "approval_rate": 0,
    "cost_per_merged_pr_micros": 0,
    "merge_rate": 0,
    "prev_cost_per_merged_pr_micros": 0,
    "prev_merge_rate": 0,
    "prev_total_prs_created": 0,
    "prev_total_prs_merged": 0,
    "total_additions": 0,
    "total_cost_micros": 0,
    "total_deletions": 0,
    "total_prs_created": 0,
    "total_prs_merged": 0
  },
  "time_series": [
    {
      "date": "2019-08-24T14:15:22Z",
      "prs_closed": 0,
      "prs_created": 0,
      "prs_merged": 0
    }
  ]
}
```

### Properties

| Name          | Type                                                                              | Required | Restrictions | Description |
|---------------|-----------------------------------------------------------------------------------|----------|--------------|-------------|
| `by_model`    | array of [codersdk.PRInsightsModelBreakdown](#codersdkprinsightsmodelbreakdown)   | false    |              |             |
| `recent_prs`  | array of [codersdk.PRInsightsPullRequest](#codersdkprinsightspullrequest)         | false    |              |             |
| `summary`     | [codersdk.PRInsightsSummary](#codersdkprinsightssummary)                          | false    |              |             |
| `time_series` | array of [codersdk.PRInsightsTimeSeriesEntry](#codersdkprinsightstimeseriesentry) | false    |              |             |

## codersdk.PRInsightsSummary

```json
{
  "approval_rate": 0,
  "cost_per_merged_pr_micros": 0,
  "merge_rate": 0,
  "prev_cost_per_merged_pr_micros": 0,
  "prev_merge_rate": 0,
  "prev_total_prs_created": 0,
  "prev_total_prs_merged": 0,
  "total_additions": 0,
  "total_cost_micros": 0,
  "total_deletions": 0,
  "total_prs_created": 0,
  "total_prs_merged": 0
}
```

### Properties

| Name                             | Type    | Required | Restrictions | Description |
|----------------------------------|---------|----------|--------------|-------------|
| `approval_rate`                  | number  | false    |              |             |
| `cost_per_merged_pr_micros`      | integer | false    |              |             |
| `merge_rate`                     | number  | false    |              |             |
| `prev_cost_per_merged_pr_micros` | integer | false    |              |             |
| `prev_merge_rate`                | number  | false    |              |             |
| `prev_total_prs_created`         | integer | false    |              |             |
| `prev_total_prs_merged`          | integer | false    |              |             |
| `total_additions`                | integer | false    |              |             |
| `total_cost_micros`              | integer | false    |              |             |
| `total_deletions`                | integer | false    |              |             |
| `total_prs_created`              | integer | false    |              |             |
| `total_prs_merged`               | integer | false    |              |             |

## codersdk.PRInsightsTimeSeriesEntry

```json
{
  "date": "2019-08-24T14:15:22Z",
  "prs_closed": 0,
  "prs_created": 0,
  "prs_merged": 0
}
```

### Properties

| Name          | Type    | Required | Restrictions | Description |
|---------------|---------|----------|--------------|-------------|
| `date`        | string  | false    |              |             |
| `prs_closed`  | integer | false    |              |             |
| `prs_created` | integer | false    |              |             |
| `prs_merged`  | integer | false    |              |             |

## codersdk.PaginatedMembersResponse

```json
{
  "count": 0,
  "members": [
    {
      "avatar_url": "string",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "string",
      "global_roles": [
        {
          "display_name": "string",
          "name": "string",
          "organization_id": "string"
        }
      ],
      "has_ai_seat": true,
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "roles": [
        {
          "display_name": "string",
          "name": "string",
          "organization_id": "string"
        }
      ],
      "status": "active",
      "updated_at": "2019-08-24T14:15:22Z",
      "user_created_at": "2019-08-24T14:15:22Z",
      "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
      "user_updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Properties

| Name      | Type                                                                                        | Required | Restrictions | Description |
|-----------|---------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `count`   | integer                                                                                     | false    |              |             |
| `members` | array of [codersdk.OrganizationMemberWithUserData](#codersdkorganizationmemberwithuserdata) | false    |              |             |

## codersdk.ParameterFormType

```json
""
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                            |
|---------------------------------------------------------------------------------------------------------------------|
| ``, `checkbox`, `dropdown`, `error`, `input`, `multi-select`, `radio`, `slider`, `switch`, `tag-select`, `textarea` |

## codersdk.PatchGroupIDPSyncConfigRequest

```json
{
  "auto_create_missing_groups": true,
  "field": "string",
  "regex_filter": {}
}
```

### Properties

| Name                         | Type                           | Required | Restrictions | Description |
|------------------------------|--------------------------------|----------|--------------|-------------|
| `auto_create_missing_groups` | boolean                        | false    |              |             |
| `field`                      | string                         | false    |              |             |
| `regex_filter`               | [regexp.Regexp](#regexpregexp) | false    |              |             |

## codersdk.PatchGroupIDPSyncMappingRequest

```json
{
  "add": [
    {
      "gets": "string",
      "given": "string"
    }
  ],
  "remove": [
    {
      "gets": "string",
      "given": "string"
    }
  ]
}
```

### Properties

| Name      | Type            | Required | Restrictions | Description                                              |
|-----------|-----------------|----------|--------------|----------------------------------------------------------|
| `add`     | array of object | false    |              |                                                          |
| `» gets`  | string          | false    |              | The ID of the Coder resource the user should be added to |
| `» given` | string          | false    |              | The IdP claim the user has                               |
| `remove`  | array of object | false    |              |                                                          |
| `» gets`  | string          | false    |              | The ID of the Coder resource the user should be added to |
| `» given` | string          | false    |              | The IdP claim the user has                               |

## codersdk.PatchGroupRequest

```json
{
  "add_users": [
    "string"
  ],
  "avatar_url": "string",
  "display_name": "string",
  "name": "string",
  "quota_allowance": 0,
  "remove_users": [
    "string"
  ]
}
```

### Properties

| Name              | Type            | Required | Restrictions | Description |
|-------------------|-----------------|----------|--------------|-------------|
| `add_users`       | array of string | false    |              |             |
| `avatar_url`      | string          | false    |              |             |
| `display_name`    | string          | false    |              |             |
| `name`            | string          | false    |              |             |
| `quota_allowance` | integer         | false    |              |             |
| `remove_users`    | array of string | false    |              |             |

## codersdk.PatchOrganizationIDPSyncConfigRequest

```json
{
  "assign_default": true,
  "field": "string"
}
```

### Properties

| Name             | Type    | Required | Restrictions | Description |
|------------------|---------|----------|--------------|-------------|
| `assign_default` | boolean | false    |              |             |
| `field`          | string  | false    |              |             |

## codersdk.PatchOrganizationIDPSyncMappingRequest

```json
{
  "add": [
    {
      "gets": "string",
      "given": "string"
    }
  ],
  "remove": [
    {
      "gets": "string",
      "given": "string"
    }
  ]
}
```

### Properties

| Name      | Type            | Required | Restrictions | Description                                              |
|-----------|-----------------|----------|--------------|----------------------------------------------------------|
| `add`     | array of object | false    |              |                                                          |
| `» gets`  | string          | false    |              | The ID of the Coder resource the user should be added to |
| `» given` | string          | false    |              | The IdP claim the user has                               |
| `remove`  | array of object | false    |              |                                                          |
| `» gets`  | string          | false    |              | The ID of the Coder resource the user should be added to |
| `» given` | string          | false    |              | The IdP claim the user has                               |

## codersdk.PatchRoleIDPSyncConfigRequest

```json
{
  "field": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `field` | string | false    |              |             |

## codersdk.PatchRoleIDPSyncMappingRequest

```json
{
  "add": [
    {
      "gets": "string",
      "given": "string"
    }
  ],
  "remove": [
    {
      "gets": "string",
      "given": "string"
    }
  ]
}
```

### Properties

| Name      | Type            | Required | Restrictions | Description                                              |
|-----------|-----------------|----------|--------------|----------------------------------------------------------|
| `add`     | array of object | false    |              |                                                          |
| `» gets`  | string          | false    |              | The ID of the Coder resource the user should be added to |
| `» given` | string          | false    |              | The IdP claim the user has                               |
| `remove`  | array of object | false    |              |                                                          |
| `» gets`  | string          | false    |              | The ID of the Coder resource the user should be added to |
| `» given` | string          | false    |              | The IdP claim the user has                               |

## codersdk.PatchTemplateVersionRequest

```json
{
  "message": "string",
  "name": "string"
}
```

### Properties

| Name      | Type   | Required | Restrictions | Description |
|-----------|--------|----------|--------------|-------------|
| `message` | string | false    |              |             |
| `name`    | string | false    |              |             |

## codersdk.PatchWorkspaceProxy

```json
{
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "regenerate_token": true
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description |
|--------------------|---------|----------|--------------|-------------|
| `display_name`     | string  | true     |              |             |
| `icon`             | string  | true     |              |             |
| `id`               | string  | true     |              |             |
| `name`             | string  | true     |              |             |
| `regenerate_token` | boolean | false    |              |             |

## codersdk.PauseTaskResponse

```json
{
  "workspace_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  }
}
```

### Properties

| Name              | Type                                               | Required | Restrictions | Description |
|-------------------|----------------------------------------------------|----------|--------------|-------------|
| `workspace_build` | [codersdk.WorkspaceBuild](#codersdkworkspacebuild) | false    |              |             |

## codersdk.Permission

```json
{
  "action": "application_connect",
  "negate": true,
  "resource_type": "*"
}
```

### Properties

| Name            | Type                                           | Required | Restrictions | Description                             |
|-----------------|------------------------------------------------|----------|--------------|-----------------------------------------|
| `action`        | [codersdk.RBACAction](#codersdkrbacaction)     | false    |              |                                         |
| `negate`        | boolean                                        | false    |              | Negate makes this a negative permission |
| `resource_type` | [codersdk.RBACResource](#codersdkrbacresource) | false    |              |                                         |

## codersdk.PostOAuth2ProviderAppRequest

```json
{
  "callback_url": "string",
  "icon": "string",
  "name": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `callback_url` | string | true     |              |             |
| `icon`         | string | false    |              |             |
| `name`         | string | true     |              |             |

## codersdk.PostWorkspaceUsageRequest

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "app_name": "vscode"
}
```

### Properties

| Name       | Type                                           | Required | Restrictions | Description |
|------------|------------------------------------------------|----------|--------------|-------------|
| `agent_id` | string                                         | false    |              |             |
| `app_name` | [codersdk.UsageAppName](#codersdkusageappname) | false    |              |             |

## codersdk.PprofConfig

```json
{
  "address": {
    "host": "string",
    "port": "string"
  },
  "enable": true
}
```

### Properties

| Name      | Type                                 | Required | Restrictions | Description |
|-----------|--------------------------------------|----------|--------------|-------------|
| `address` | [serpent.HostPort](#serpenthostport) | false    |              |             |
| `enable`  | boolean                              | false    |              |             |

## codersdk.PrebuildsConfig

```json
{
  "failure_hard_limit": 0,
  "reconciliation_backoff_interval": 0,
  "reconciliation_backoff_lookback": 0,
  "reconciliation_interval": 0
}
```

### Properties

| Name                              | Type    | Required | Restrictions | Description                                                                                                                                                                                                                                                                                       |
|-----------------------------------|---------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `failure_hard_limit`              | integer | false    |              | Failure hard limit defines the maximum number of consecutive failed prebuild attempts allowed before a preset is considered to be in a hard limit state. When a preset hits this limit, no new prebuilds will be created until the limit is reset. FailureHardLimit is disabled when set to zero. |
| `reconciliation_backoff_interval` | integer | false    |              | Reconciliation backoff interval specifies the amount of time to increase the backoff interval when errors occur during reconciliation.                                                                                                                                                            |
| `reconciliation_backoff_lookback` | integer | false    |              | Reconciliation backoff lookback determines the time window to look back when calculating the number of failed prebuilds, which influences the backoff strategy.                                                                                                                                   |
| `reconciliation_interval`         | integer | false    |              | Reconciliation interval defines how often the workspace prebuilds state should be reconciled.                                                                                                                                                                                                     |

## codersdk.PrebuildsSettings

```json
{
  "reconciliation_paused": true
}
```

### Properties

| Name                    | Type    | Required | Restrictions | Description |
|-------------------------|---------|----------|--------------|-------------|
| `reconciliation_paused` | boolean | false    |              |             |

## codersdk.Preset

```json
{
  "default": true,
  "description": "string",
  "desiredPrebuildInstances": 0,
  "icon": "string",
  "id": "string",
  "name": "string",
  "parameters": [
    {
      "name": "string",
      "value": "string"
    }
  ]
}
```

### Properties

| Name                       | Type                                                          | Required | Restrictions | Description |
|----------------------------|---------------------------------------------------------------|----------|--------------|-------------|
| `default`                  | boolean                                                       | false    |              |             |
| `description`              | string                                                        | false    |              |             |
| `desiredPrebuildInstances` | integer                                                       | false    |              |             |
| `icon`                     | string                                                        | false    |              |             |
| `id`                       | string                                                        | false    |              |             |
| `name`                     | string                                                        | false    |              |             |
| `parameters`               | array of [codersdk.PresetParameter](#codersdkpresetparameter) | false    |              |             |

## codersdk.PresetParameter

```json
{
  "name": "string",
  "value": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `name`  | string | false    |              |             |
| `value` | string | false    |              |             |

## codersdk.PreviewParameter

```json
{
  "default_value": {
    "valid": true,
    "value": "string"
  },
  "description": "string",
  "diagnostics": [
    {
      "detail": "string",
      "extra": {
        "code": "string"
      },
      "severity": "error",
      "summary": "string"
    }
  ],
  "display_name": "string",
  "ephemeral": true,
  "form_type": "",
  "icon": "string",
  "mutable": true,
  "name": "string",
  "options": [
    {
      "description": "string",
      "icon": "string",
      "name": "string",
      "value": {
        "valid": true,
        "value": "string"
      }
    }
  ],
  "order": 0,
  "required": true,
  "styling": {
    "disabled": true,
    "label": "string",
    "mask_input": true,
    "placeholder": "string"
  },
  "type": "string",
  "validations": [
    {
      "validation_error": "string",
      "validation_max": 0,
      "validation_min": 0,
      "validation_monotonic": "string",
      "validation_regex": "string"
    }
  ],
  "value": {
    "valid": true,
    "value": "string"
  }
}
```

### Properties

| Name            | Type                                                                                | Required | Restrictions | Description                             |
|-----------------|-------------------------------------------------------------------------------------|----------|--------------|-----------------------------------------|
| `default_value` | [codersdk.NullHCLString](#codersdknullhclstring)                                    | false    |              |                                         |
| `description`   | string                                                                              | false    |              |                                         |
| `diagnostics`   | array of [codersdk.FriendlyDiagnostic](#codersdkfriendlydiagnostic)                 | false    |              |                                         |
| `display_name`  | string                                                                              | false    |              |                                         |
| `ephemeral`     | boolean                                                                             | false    |              |                                         |
| `form_type`     | [codersdk.ParameterFormType](#codersdkparameterformtype)                            | false    |              |                                         |
| `icon`          | string                                                                              | false    |              |                                         |
| `mutable`       | boolean                                                                             | false    |              |                                         |
| `name`          | string                                                                              | false    |              |                                         |
| `options`       | array of [codersdk.PreviewParameterOption](#codersdkpreviewparameteroption)         | false    |              |                                         |
| `order`         | integer                                                                             | false    |              | legacy_variable_name was removed (= 14) |
| `required`      | boolean                                                                             | false    |              |                                         |
| `styling`       | [codersdk.PreviewParameterStyling](#codersdkpreviewparameterstyling)                | false    |              |                                         |
| `type`          | [codersdk.OptionType](#codersdkoptiontype)                                          | false    |              |                                         |
| `validations`   | array of [codersdk.PreviewParameterValidation](#codersdkpreviewparametervalidation) | false    |              |                                         |
| `value`         | [codersdk.NullHCLString](#codersdknullhclstring)                                    | false    |              |                                         |

## codersdk.PreviewParameterOption

```json
{
  "description": "string",
  "icon": "string",
  "name": "string",
  "value": {
    "valid": true,
    "value": "string"
  }
}
```

### Properties

| Name          | Type                                             | Required | Restrictions | Description |
|---------------|--------------------------------------------------|----------|--------------|-------------|
| `description` | string                                           | false    |              |             |
| `icon`        | string                                           | false    |              |             |
| `name`        | string                                           | false    |              |             |
| `value`       | [codersdk.NullHCLString](#codersdknullhclstring) | false    |              |             |

## codersdk.PreviewParameterStyling

```json
{
  "disabled": true,
  "label": "string",
  "mask_input": true,
  "placeholder": "string"
}
```

### Properties

| Name          | Type    | Required | Restrictions | Description |
|---------------|---------|----------|--------------|-------------|
| `disabled`    | boolean | false    |              |             |
| `label`       | string  | false    |              |             |
| `mask_input`  | boolean | false    |              |             |
| `placeholder` | string  | false    |              |             |

## codersdk.PreviewParameterValidation

```json
{
  "validation_error": "string",
  "validation_max": 0,
  "validation_min": 0,
  "validation_monotonic": "string",
  "validation_regex": "string"
}
```

### Properties

| Name                   | Type    | Required | Restrictions | Description                             |
|------------------------|---------|----------|--------------|-----------------------------------------|
| `validation_error`     | string  | false    |              |                                         |
| `validation_max`       | integer | false    |              |                                         |
| `validation_min`       | integer | false    |              |                                         |
| `validation_monotonic` | string  | false    |              |                                         |
| `validation_regex`     | string  | false    |              | All validation attributes are optional. |

## codersdk.PrometheusConfig

```json
{
  "address": {
    "host": "string",
    "port": "string"
  },
  "aggregate_agent_stats_by": [
    "string"
  ],
  "collect_agent_stats": true,
  "collect_db_metrics": true,
  "enable": true
}
```

### Properties

| Name                       | Type                                 | Required | Restrictions | Description |
|----------------------------|--------------------------------------|----------|--------------|-------------|
| `address`                  | [serpent.HostPort](#serpenthostport) | false    |              |             |
| `aggregate_agent_stats_by` | array of string                      | false    |              |             |
| `collect_agent_stats`      | boolean                              | false    |              |             |
| `collect_db_metrics`       | boolean                              | false    |              |             |
| `enable`                   | boolean                              | false    |              |             |

## codersdk.ProvisionerConfig

```json
{
  "daemon_poll_interval": 0,
  "daemon_poll_jitter": 0,
  "daemon_psk": "string",
  "daemon_types": [
    "string"
  ],
  "daemons": 0,
  "force_cancel_interval": 0
}
```

### Properties

| Name                    | Type            | Required | Restrictions | Description                                               |
|-------------------------|-----------------|----------|--------------|-----------------------------------------------------------|
| `daemon_poll_interval`  | integer         | false    |              |                                                           |
| `daemon_poll_jitter`    | integer         | false    |              |                                                           |
| `daemon_psk`            | string          | false    |              |                                                           |
| `daemon_types`          | array of string | false    |              |                                                           |
| `daemons`               | integer         | false    |              | Daemons is the number of built-in terraform provisioners. |
| `force_cancel_interval` | integer         | false    |              |                                                           |

## codersdk.ProvisionerDaemon

```json
{
  "api_version": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "current_job": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "status": "pending",
    "template_display_name": "string",
    "template_icon": "string",
    "template_name": "string"
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
  "key_name": "string",
  "last_seen_at": "2019-08-24T14:15:22Z",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "previous_job": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "status": "pending",
    "template_display_name": "string",
    "template_icon": "string",
    "template_name": "string"
  },
  "provisioners": [
    "string"
  ],
  "status": "offline",
  "tags": {
    "property1": "string",
    "property2": "string"
  },
  "version": "string"
}
```

### Properties

| Name               | Type                                                                 | Required | Restrictions | Description      |
|--------------------|----------------------------------------------------------------------|----------|--------------|------------------|
| `api_version`      | string                                                               | false    |              |                  |
| `created_at`       | string                                                               | false    |              |                  |
| `current_job`      | [codersdk.ProvisionerDaemonJob](#codersdkprovisionerdaemonjob)       | false    |              |                  |
| `id`               | string                                                               | false    |              |                  |
| `key_id`           | string                                                               | false    |              |                  |
| `key_name`         | string                                                               | false    |              | Optional fields. |
| `last_seen_at`     | string                                                               | false    |              |                  |
| `name`             | string                                                               | false    |              |                  |
| `organization_id`  | string                                                               | false    |              |                  |
| `previous_job`     | [codersdk.ProvisionerDaemonJob](#codersdkprovisionerdaemonjob)       | false    |              |                  |
| `provisioners`     | array of string                                                      | false    |              |                  |
| `status`           | [codersdk.ProvisionerDaemonStatus](#codersdkprovisionerdaemonstatus) | false    |              |                  |
| `tags`             | object                                                               | false    |              |                  |
| » `[any property]` | string                                                               | false    |              |                  |
| `version`          | string                                                               | false    |              |                  |

#### Enumerated Values

| Property | Value(s)                  |
|----------|---------------------------|
| `status` | `busy`, `idle`, `offline` |

## codersdk.ProvisionerDaemonJob

```json
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "status": "pending",
  "template_display_name": "string",
  "template_icon": "string",
  "template_name": "string"
}
```

### Properties

| Name                    | Type                                                           | Required | Restrictions | Description |
|-------------------------|----------------------------------------------------------------|----------|--------------|-------------|
| `id`                    | string                                                         | false    |              |             |
| `status`                | [codersdk.ProvisionerJobStatus](#codersdkprovisionerjobstatus) | false    |              |             |
| `template_display_name` | string                                                         | false    |              |             |
| `template_icon`         | string                                                         | false    |              |             |
| `template_name`         | string                                                         | false    |              |             |

#### Enumerated Values

| Property | Value(s)                                                             |
|----------|----------------------------------------------------------------------|
| `status` | `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded` |

## codersdk.ProvisionerDaemonStatus

```json
"offline"
```

### Properties

#### Enumerated Values

| Value(s)                  |
|---------------------------|
| `busy`, `idle`, `offline` |

## codersdk.ProvisionerJob

```json
{
  "available_workers": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "canceled_at": "2019-08-24T14:15:22Z",
  "completed_at": "2019-08-24T14:15:22Z",
  "created_at": "2019-08-24T14:15:22Z",
  "error": "string",
  "error_code": "REQUIRED_TEMPLATE_VARIABLES",
  "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "input": {
    "error": "string",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
  },
  "logs_overflowed": true,
  "metadata": {
    "template_display_name": "string",
    "template_icon": "string",
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "template_name": "string",
    "template_version_name": "string",
    "workspace_build_transition": "start",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string"
  },
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "queue_position": 0,
  "queue_size": 0,
  "started_at": "2019-08-24T14:15:22Z",
  "status": "pending",
  "tags": {
    "property1": "string",
    "property2": "string"
  },
  "type": "template_version_import",
  "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
  "worker_name": "string"
}
```

### Properties

| Name                | Type                                                               | Required | Restrictions | Description |
|---------------------|--------------------------------------------------------------------|----------|--------------|-------------|
| `available_workers` | array of string                                                    | false    |              |             |
| `canceled_at`       | string                                                             | false    |              |             |
| `completed_at`      | string                                                             | false    |              |             |
| `created_at`        | string                                                             | false    |              |             |
| `error`             | string                                                             | false    |              |             |
| `error_code`        | [codersdk.JobErrorCode](#codersdkjoberrorcode)                     | false    |              |             |
| `file_id`           | string                                                             | false    |              |             |
| `id`                | string                                                             | false    |              |             |
| `initiator_id`      | string                                                             | false    |              |             |
| `input`             | [codersdk.ProvisionerJobInput](#codersdkprovisionerjobinput)       | false    |              |             |
| `logs_overflowed`   | boolean                                                            | false    |              |             |
| `metadata`          | [codersdk.ProvisionerJobMetadata](#codersdkprovisionerjobmetadata) | false    |              |             |
| `organization_id`   | string                                                             | false    |              |             |
| `queue_position`    | integer                                                            | false    |              |             |
| `queue_size`        | integer                                                            | false    |              |             |
| `started_at`        | string                                                             | false    |              |             |
| `status`            | [codersdk.ProvisionerJobStatus](#codersdkprovisionerjobstatus)     | false    |              |             |
| `tags`              | object                                                             | false    |              |             |
| » `[any property]`  | string                                                             | false    |              |             |
| `type`              | [codersdk.ProvisionerJobType](#codersdkprovisionerjobtype)         | false    |              |             |
| `worker_id`         | string                                                             | false    |              |             |
| `worker_name`       | string                                                             | false    |              |             |

#### Enumerated Values

| Property     | Value(s)                                                             |
|--------------|----------------------------------------------------------------------|
| `error_code` | `INSUFFICIENT_QUOTA`, `REQUIRED_TEMPLATE_VARIABLES`                  |
| `status`     | `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded` |

## codersdk.ProvisionerJobInput

```json
{
  "error": "string",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
}
```

### Properties

| Name                  | Type   | Required | Restrictions | Description |
|-----------------------|--------|----------|--------------|-------------|
| `error`               | string | false    |              |             |
| `template_version_id` | string | false    |              |             |
| `workspace_build_id`  | string | false    |              |             |

## codersdk.ProvisionerJobLog

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": 0,
  "log_level": "trace",
  "log_source": "provisioner_daemon",
  "output": "string",
  "stage": "string"
}
```

### Properties

| Name         | Type                                     | Required | Restrictions | Description |
|--------------|------------------------------------------|----------|--------------|-------------|
| `created_at` | string                                   | false    |              |             |
| `id`         | integer                                  | false    |              |             |
| `log_level`  | [codersdk.LogLevel](#codersdkloglevel)   | false    |              |             |
| `log_source` | [codersdk.LogSource](#codersdklogsource) | false    |              |             |
| `output`     | string                                   | false    |              |             |
| `stage`      | string                                   | false    |              |             |

#### Enumerated Values

| Property    | Value(s)                                  |
|-------------|-------------------------------------------|
| `log_level` | `debug`, `error`, `info`, `trace`, `warn` |

## codersdk.ProvisionerJobMetadata

```json
{
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_version_name": "string",
  "workspace_build_transition": "start",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
  "workspace_name": "string"
}
```

### Properties

| Name                         | Type                                                         | Required | Restrictions | Description |
|------------------------------|--------------------------------------------------------------|----------|--------------|-------------|
| `template_display_name`      | string                                                       | false    |              |             |
| `template_icon`              | string                                                       | false    |              |             |
| `template_id`                | string                                                       | false    |              |             |
| `template_name`              | string                                                       | false    |              |             |
| `template_version_name`      | string                                                       | false    |              |             |
| `workspace_build_transition` | [codersdk.WorkspaceTransition](#codersdkworkspacetransition) | false    |              |             |
| `workspace_id`               | string                                                       | false    |              |             |
| `workspace_name`             | string                                                       | false    |              |             |

## codersdk.ProvisionerJobStatus

```json
"pending"
```

### Properties

#### Enumerated Values

| Value(s)                                                                        |
|---------------------------------------------------------------------------------|
| `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded`, `unknown` |

## codersdk.ProvisionerJobType

```json
"template_version_import"
```

### Properties

#### Enumerated Values

| Value(s)                                                                 |
|--------------------------------------------------------------------------|
| `template_version_dry_run`, `template_version_import`, `workspace_build` |

## codersdk.ProvisionerKey

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "organization": "452c1a86-a0af-475b-b03f-724878b0f387",
  "tags": {
    "property1": "string",
    "property2": "string"
  }
}
```

### Properties

| Name           | Type                                                       | Required | Restrictions | Description |
|----------------|------------------------------------------------------------|----------|--------------|-------------|
| `created_at`   | string                                                     | false    |              |             |
| `id`           | string                                                     | false    |              |             |
| `name`         | string                                                     | false    |              |             |
| `organization` | string                                                     | false    |              |             |
| `tags`         | [codersdk.ProvisionerKeyTags](#codersdkprovisionerkeytags) | false    |              |             |

## codersdk.ProvisionerKeyDaemons

```json
{
  "daemons": [
    {
      "api_version": "string",
      "created_at": "2019-08-24T14:15:22Z",
      "current_job": {
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "status": "pending",
        "template_display_name": "string",
        "template_icon": "string",
        "template_name": "string"
      },
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
      "key_name": "string",
      "last_seen_at": "2019-08-24T14:15:22Z",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "previous_job": {
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "status": "pending",
        "template_display_name": "string",
        "template_icon": "string",
        "template_name": "string"
      },
      "provisioners": [
        "string"
      ],
      "status": "offline",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "version": "string"
    }
  ],
  "key": {
    "created_at": "2019-08-24T14:15:22Z",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "organization": "452c1a86-a0af-475b-b03f-724878b0f387",
    "tags": {
      "property1": "string",
      "property2": "string"
    }
  }
}
```

### Properties

| Name      | Type                                                              | Required | Restrictions | Description |
|-----------|-------------------------------------------------------------------|----------|--------------|-------------|
| `daemons` | array of [codersdk.ProvisionerDaemon](#codersdkprovisionerdaemon) | false    |              |             |
| `key`     | [codersdk.ProvisionerKey](#codersdkprovisionerkey)                | false    |              |             |

## codersdk.ProvisionerKeyTags

```json
{
  "property1": "string",
  "property2": "string"
}
```

### Properties

| Name             | Type   | Required | Restrictions | Description |
|------------------|--------|----------|--------------|-------------|
| `[any property]` | string | false    |              |             |

## codersdk.ProvisionerLogLevel

```json
"debug"
```

### Properties

#### Enumerated Values

| Value(s) |
|----------|
| `debug`  |

## codersdk.ProvisionerStorageMethod

```json
"file"
```

### Properties

#### Enumerated Values

| Value(s) |
|----------|
| `file`   |

## codersdk.ProvisionerTiming

```json
{
  "action": "string",
  "ended_at": "2019-08-24T14:15:22Z",
  "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
  "resource": "string",
  "source": "string",
  "stage": "init",
  "started_at": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name         | Type                                         | Required | Restrictions | Description |
|--------------|----------------------------------------------|----------|--------------|-------------|
| `action`     | string                                       | false    |              |             |
| `ended_at`   | string                                       | false    |              |             |
| `job_id`     | string                                       | false    |              |             |
| `resource`   | string                                       | false    |              |             |
| `source`     | string                                       | false    |              |             |
| `stage`      | [codersdk.TimingStage](#codersdktimingstage) | false    |              |             |
| `started_at` | string                                       | false    |              |             |

## codersdk.ProxyHealthReport

```json
{
  "errors": [
    "string"
  ],
  "warnings": [
    "string"
  ]
}
```

### Properties

| Name       | Type            | Required | Restrictions | Description                                                                              |
|------------|-----------------|----------|--------------|------------------------------------------------------------------------------------------|
| `errors`   | array of string | false    |              | Errors are problems that prevent the workspace proxy from being healthy                  |
| `warnings` | array of string | false    |              | Warnings do not prevent the workspace proxy from being healthy, but should be addressed. |

## codersdk.ProxyHealthStatus

```json
"ok"
```

### Properties

#### Enumerated Values

| Value(s)                                         |
|--------------------------------------------------|
| `ok`, `unhealthy`, `unreachable`, `unregistered` |

## codersdk.PutExtendWorkspaceRequest

```json
{
  "deadline": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `deadline` | string | true     |              |             |

## codersdk.PutOAuth2ProviderAppRequest

```json
{
  "callback_url": "string",
  "icon": "string",
  "name": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `callback_url` | string | true     |              |             |
| `icon`         | string | false    |              |             |
| `name`         | string | true     |              |             |

## codersdk.RBACAction

```json
"application_connect"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                                                                                                                       |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `application_connect`, `assign`, `create`, `create_agent`, `delete`, `delete_agent`, `read`, `read_personal`, `share`, `ssh`, `start`, `stop`, `unassign`, `update`, `update_agent`, `update_personal`, `use`, `view_insights` |

## codersdk.RBACResource

```json
"*"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `*`, `ai_seat`, `aibridge_interception`, `api_key`, `assign_org_role`, `assign_role`, `audit_log`, `boundary_usage`, `chat`, `connection_log`, `crypto_key`, `debug_info`, `deployment_config`, `deployment_stats`, `file`, `group`, `group_member`, `idpsync_settings`, `inbox_notification`, `license`, `notification_message`, `notification_preference`, `notification_template`, `oauth2_app`, `oauth2_app_code_token`, `oauth2_app_secret`, `organization`, `organization_member`, `prebuilt_workspace`, `provisioner_daemon`, `provisioner_jobs`, `replicas`, `system`, `tailnet_coordinator`, `task`, `template`, `usage_event`, `user`, `user_secret`, `webpush_subscription`, `workspace`, `workspace_agent_devcontainers`, `workspace_agent_resource_monitor`, `workspace_dormant`, `workspace_proxy` |

## codersdk.RateLimitConfig

```json
{
  "api": 0,
  "disable_all": true
}
```

### Properties

| Name          | Type    | Required | Restrictions | Description |
|---------------|---------|----------|--------------|-------------|
| `api`         | integer | false    |              |             |
| `disable_all` | boolean | false    |              |             |

## codersdk.ReducedUser

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Properties

| Name                 | Type                                       | Required | Restrictions | Description                                                                                |
|----------------------|--------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------|
| `avatar_url`         | string                                     | false    |              |                                                                                            |
| `created_at`         | string                                     | true     |              |                                                                                            |
| `email`              | string                                     | true     |              |                                                                                            |
| `id`                 | string                                     | true     |              |                                                                                            |
| `is_service_account` | boolean                                    | false    |              |                                                                                            |
| `last_seen_at`       | string                                     | false    |              |                                                                                            |
| `login_type`         | [codersdk.LoginType](#codersdklogintype)   | false    |              |                                                                                            |
| `name`               | string                                     | false    |              |                                                                                            |
| `status`             | [codersdk.UserStatus](#codersdkuserstatus) | false    |              |                                                                                            |
| `theme_preference`   | string                                     | false    |              | Deprecated: this value should be retrieved from `codersdk.UserPreferenceSettings` instead. |
| `updated_at`         | string                                     | false    |              |                                                                                            |
| `username`           | string                                     | true     |              |                                                                                            |

#### Enumerated Values

| Property | Value(s)              |
|----------|-----------------------|
| `status` | `active`, `suspended` |

## codersdk.Region

```json
{
  "display_name": "string",
  "healthy": true,
  "icon_url": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "path_app_url": "string",
  "wildcard_hostname": "string"
}
```

### Properties

| Name                | Type    | Required | Restrictions | Description                                                                                                                                                                       |
|---------------------|---------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `display_name`      | string  | false    |              |                                                                                                                                                                                   |
| `healthy`           | boolean | false    |              |                                                                                                                                                                                   |
| `icon_url`          | string  | false    |              |                                                                                                                                                                                   |
| `id`                | string  | false    |              |                                                                                                                                                                                   |
| `name`              | string  | false    |              |                                                                                                                                                                                   |
| `path_app_url`      | string  | false    |              | Path app URL is the URL to the base path for path apps. Optional unless wildcard_hostname is set. E.g. https://us.example.com                                                     |
| `wildcard_hostname` | string  | false    |              | Wildcard hostname is the wildcard hostname for subdomain apps. E.g. *.us.example.com E.g.*--suffix.au.example.com Optional. Does not need to be on the same domain as PathAppURL. |

## codersdk.RegionsResponse-codersdk_Region

```json
{
  "regions": [
    {
      "display_name": "string",
      "healthy": true,
      "icon_url": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "path_app_url": "string",
      "wildcard_hostname": "string"
    }
  ]
}
```

### Properties

| Name      | Type                                        | Required | Restrictions | Description |
|-----------|---------------------------------------------|----------|--------------|-------------|
| `regions` | array of [codersdk.Region](#codersdkregion) | false    |              |             |

## codersdk.RegionsResponse-codersdk_WorkspaceProxy

```json
{
  "regions": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "deleted": true,
      "derp_enabled": true,
      "derp_only": true,
      "display_name": "string",
      "healthy": true,
      "icon_url": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "path_app_url": "string",
      "status": {
        "checked_at": "2019-08-24T14:15:22Z",
        "report": {
          "errors": [
            "string"
          ],
          "warnings": [
            "string"
          ]
        },
        "status": "ok"
      },
      "updated_at": "2019-08-24T14:15:22Z",
      "version": "string",
      "wildcard_hostname": "string"
    }
  ]
}
```

### Properties

| Name      | Type                                                        | Required | Restrictions | Description |
|-----------|-------------------------------------------------------------|----------|--------------|-------------|
| `regions` | array of [codersdk.WorkspaceProxy](#codersdkworkspaceproxy) | false    |              |             |

## codersdk.Replica

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "database_latency": 0,
  "error": "string",
  "hostname": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "region_id": 0,
  "relay_address": "string"
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description                                                        |
|--------------------|---------|----------|--------------|--------------------------------------------------------------------|
| `created_at`       | string  | false    |              | Created at is the timestamp when the replica was first seen.       |
| `database_latency` | integer | false    |              | Database latency is the latency in microseconds to the database.   |
| `error`            | string  | false    |              | Error is the replica error.                                        |
| `hostname`         | string  | false    |              | Hostname is the hostname of the replica.                           |
| `id`               | string  | false    |              | ID is the unique identifier for the replica.                       |
| `region_id`        | integer | false    |              | Region ID is the region of the replica.                            |
| `relay_address`    | string  | false    |              | Relay address is the accessible address to relay DERP connections. |

## codersdk.RequestOneTimePasscodeRequest

```json
{
  "email": "user@example.com"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `email` | string | true     |              |             |

## codersdk.ResolveAutostartResponse

```json
{
  "parameter_mismatch": true
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `parameter_mismatch` | boolean | false    |              |             |

## codersdk.ResourceType

```json
"template"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ai_seat`, `api_key`, `chat`, `convert_login`, `custom_role`, `git_ssh_key`, `group`, `health_settings`, `idp_sync_settings_group`, `idp_sync_settings_organization`, `idp_sync_settings_role`, `license`, `notification_template`, `notifications_settings`, `oauth2_provider_app`, `oauth2_provider_app_secret`, `organization`, `organization_member`, `prebuilds_settings`, `task`, `template`, `template_version`, `user`, `user_secret`, `workspace`, `workspace_agent`, `workspace_app`, `workspace_build`, `workspace_proxy` |

## codersdk.Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Properties

| Name          | Type                                                          | Required | Restrictions | Description                                                                                                                                                                                                                        |
|---------------|---------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `detail`      | string                                                        | false    |              | Detail is a debug message that provides further insight into why the action failed. This information can be technical and a regular golang err.Error() text. - "database: too many open connections" - "stat: too many open files" |
| `message`     | string                                                        | false    |              | Message is an actionable message that depicts actions the request took. These messages should be fully formed sentences with proper punctuation. Examples: - "A user has been created." - "Failed to create a user."               |
| `validations` | array of [codersdk.ValidationError](#codersdkvalidationerror) | false    |              | Validations are form field-specific friendly error messages. They will be shown on a form field in the UI. These can also be used to add additional context if there is a set of errors in the primary 'Message'.                  |

## codersdk.ResumeTaskResponse

```json
{
  "workspace_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  }
}
```

### Properties

| Name              | Type                                               | Required | Restrictions | Description |
|-------------------|----------------------------------------------------|----------|--------------|-------------|
| `workspace_build` | [codersdk.WorkspaceBuild](#codersdkworkspacebuild) | false    |              |             |

## codersdk.RetentionConfig

```json
{
  "api_keys": 0,
  "audit_logs": 0,
  "connection_logs": 0,
  "workspace_agent_logs": 0
}
```

### Properties

| Name                   | Type    | Required | Restrictions | Description                                                                                                                                                                                                                                                      |
|------------------------|---------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `api_keys`             | integer | false    |              | Api keys controls how long expired API keys are retained before being deleted. Keys are only deleted if they have been expired for at least this duration. Defaults to 7 days to preserve existing behavior.                                                     |
| `audit_logs`           | integer | false    |              | Audit logs controls how long audit log entries are retained. Set to 0 to disable (keep indefinitely).                                                                                                                                                            |
| `connection_logs`      | integer | false    |              | Connection logs controls how long connection log entries are retained. Set to 0 to disable (keep indefinitely).                                                                                                                                                  |
| `workspace_agent_logs` | integer | false    |              | Workspace agent logs controls how long workspace agent logs are retained. Logs are deleted if the agent hasn't connected within this period. Logs from the latest build are always retained regardless of age. Defaults to 7 days to preserve existing behavior. |

## codersdk.Role

```json
{
  "display_name": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_member_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "organization_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "site_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ],
  "user_permissions": [
    {
      "action": "application_connect",
      "negate": true,
      "resource_type": "*"
    }
  ]
}
```

### Properties

| Name                              | Type                                                | Required | Restrictions | Description                                                                                            |
|-----------------------------------|-----------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------|
| `display_name`                    | string                                              | false    |              |                                                                                                        |
| `name`                            | string                                              | false    |              |                                                                                                        |
| `organization_id`                 | string                                              | false    |              |                                                                                                        |
| `organization_member_permissions` | array of [codersdk.Permission](#codersdkpermission) | false    |              | Organization member permissions are specific for the organization in the field 'OrganizationID' above. |
| `organization_permissions`        | array of [codersdk.Permission](#codersdkpermission) | false    |              | Organization permissions are specific for the organization in the field 'OrganizationID' above.        |
| `site_permissions`                | array of [codersdk.Permission](#codersdkpermission) | false    |              |                                                                                                        |
| `user_permissions`                | array of [codersdk.Permission](#codersdkpermission) | false    |              |                                                                                                        |

## codersdk.RoleSyncSettings

```json
{
  "field": "string",
  "mapping": {
    "property1": [
      "string"
    ],
    "property2": [
      "string"
    ]
  }
}
```

### Properties

| Name               | Type            | Required | Restrictions | Description                                                                                                                            |
|--------------------|-----------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------|
| `field`            | string          | false    |              | Field is the name of the claim field that specifies what organization roles a user should be given. If empty, no roles will be synced. |
| `mapping`          | object          | false    |              | Mapping is a map from OIDC groups to Coder organization roles.                                                                         |
| » `[any property]` | array of string | false    |              |                                                                                                                                        |

## codersdk.SSHConfig

```json
{
  "deploymentName": "string",
  "sshconfigOptions": [
    "string"
  ]
}
```

### Properties

| Name               | Type            | Required | Restrictions | Description                                                                                         |
|--------------------|-----------------|----------|--------------|-----------------------------------------------------------------------------------------------------|
| `deploymentName`   | string          | false    |              | Deploymentname is the config-ssh Hostname prefix                                                    |
| `sshconfigOptions` | array of string | false    |              | Sshconfigoptions are additional options to add to the ssh config file. This will override defaults. |

## codersdk.SSHConfigResponse

```json
{
  "hostname_prefix": "string",
  "hostname_suffix": "string",
  "ssh_config_options": {
    "property1": "string",
    "property2": "string"
  }
}
```

### Properties

| Name                 | Type   | Required | Restrictions | Description                                                                                                           |
|----------------------|--------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------|
| `hostname_prefix`    | string | false    |              | Hostname prefix is the prefix we append to workspace names for SSH hostnames. Deprecated: use HostnameSuffix instead. |
| `hostname_suffix`    | string | false    |              | Hostname suffix is the suffix to append to workspace names for SSH hostnames.                                         |
| `ssh_config_options` | object | false    |              |                                                                                                                       |
| » `[any property]`   | string | false    |              |                                                                                                                       |

## codersdk.SecretRequirementStatus

```json
{
  "env": "string",
  "file": "string",
  "help_message": "string",
  "satisfied": true
}
```

### Properties

| Name           | Type    | Required | Restrictions | Description |
|----------------|---------|----------|--------------|-------------|
| `env`          | string  | false    |              |             |
| `file`         | string  | false    |              |             |
| `help_message` | string  | false    |              |             |
| `satisfied`    | boolean | false    |              |             |

## codersdk.ServerSentEvent

```json
{
  "data": null,
  "type": "ping"
}
```

### Properties

| Name   | Type                                                         | Required | Restrictions | Description |
|--------|--------------------------------------------------------------|----------|--------------|-------------|
| `data` | any                                                          | false    |              |             |
| `type` | [codersdk.ServerSentEventType](#codersdkserversenteventtype) | false    |              |             |

## codersdk.ServerSentEventType

```json
"ping"
```

### Properties

#### Enumerated Values

| Value(s)                |
|-------------------------|
| `data`, `error`, `ping` |

## codersdk.SessionCountDeploymentStats

```json
{
  "jetbrains": 0,
  "reconnecting_pty": 0,
  "ssh": 0,
  "vscode": 0
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description |
|--------------------|---------|----------|--------------|-------------|
| `jetbrains`        | integer | false    |              |             |
| `reconnecting_pty` | integer | false    |              |             |
| `ssh`              | integer | false    |              |             |
| `vscode`           | integer | false    |              |             |

## codersdk.SessionLifetime

```json
{
  "default_duration": 0,
  "default_token_lifetime": 0,
  "disable_expiry_refresh": true,
  "max_admin_token_lifetime": 0,
  "max_token_lifetime": 0,
  "refresh_default_duration": 0
}
```

### Properties

| Name                       | Type    | Required | Restrictions | Description                                                                                                                                                                            |
|----------------------------|---------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `default_duration`         | integer | false    |              | Default duration is only for browser, workspace app and oauth sessions.                                                                                                                |
| `default_token_lifetime`   | integer | false    |              |                                                                                                                                                                                        |
| `disable_expiry_refresh`   | boolean | false    |              | Disable expiry refresh will disable automatically refreshing api keys when they are used from the api. This means the api key lifetime at creation is the lifetime of the api key.     |
| `max_admin_token_lifetime` | integer | false    |              |                                                                                                                                                                                        |
| `max_token_lifetime`       | integer | false    |              |                                                                                                                                                                                        |
| `refresh_default_duration` | integer | false    |              | Refresh default duration is the default lifetime for OAuth2 refresh tokens. This should generally be longer than access token lifetimes to allow refreshing after access token expiry. |

## codersdk.ShareableWorkspaceOwners

```json
"none"
```

### Properties

#### Enumerated Values

| Value(s)                               |
|----------------------------------------|
| `everyone`, `none`, `service_accounts` |

## codersdk.SharedWorkspaceActor

```json
{
  "actor_type": "group",
  "avatar_url": "http://example.com",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "roles": [
    "admin"
  ]
}
```

### Properties

| Name         | Type                                                                   | Required | Restrictions | Description |
|--------------|------------------------------------------------------------------------|----------|--------------|-------------|
| `actor_type` | [codersdk.SharedWorkspaceActorType](#codersdksharedworkspaceactortype) | false    |              |             |
| `avatar_url` | string                                                                 | false    |              |             |
| `id`         | string                                                                 | false    |              |             |
| `name`       | string                                                                 | false    |              |             |
| `roles`      | array of [codersdk.WorkspaceRole](#codersdkworkspacerole)              | false    |              |             |

#### Enumerated Values

| Property     | Value(s)        |
|--------------|-----------------|
| `actor_type` | `group`, `user` |

## codersdk.SharedWorkspaceActorType

```json
"group"
```

### Properties

#### Enumerated Values

| Value(s)        |
|-----------------|
| `group`, `user` |

## codersdk.SlimRole

```json
{
  "display_name": "string",
  "name": "string",
  "organization_id": "string"
}
```

### Properties

| Name              | Type   | Required | Restrictions | Description |
|-------------------|--------|----------|--------------|-------------|
| `display_name`    | string | false    |              |             |
| `name`            | string | false    |              |             |
| `organization_id` | string | false    |              |             |

## codersdk.StatsCollectionConfig

```json
{
  "usage_stats": {
    "enable": true
  }
}
```

### Properties

| Name          | Type                                                   | Required | Restrictions | Description |
|---------------|--------------------------------------------------------|----------|--------------|-------------|
| `usage_stats` | [codersdk.UsageStatsConfig](#codersdkusagestatsconfig) | false    |              |             |

## codersdk.SupportConfig

```json
{
  "links": {
    "value": [
      {
        "icon": "bug",
        "location": "navbar",
        "name": "string",
        "target": "string"
      }
    ]
  }
}
```

### Properties

| Name    | Type                                                                                 | Required | Restrictions | Description |
|---------|--------------------------------------------------------------------------------------|----------|--------------|-------------|
| `links` | [serpent.Struct-array_codersdk_LinkConfig](#serpentstruct-array_codersdk_linkconfig) | false    |              |             |

## codersdk.SwaggerConfig

```json
{
  "enable": true
}
```

### Properties

| Name     | Type    | Required | Restrictions | Description |
|----------|---------|----------|--------------|-------------|
| `enable` | boolean | false    |              |             |

## codersdk.TLSConfig

```json
{
  "address": {
    "host": "string",
    "port": "string"
  },
  "allow_insecure_ciphers": true,
  "cert_file": [
    "string"
  ],
  "client_auth": "string",
  "client_ca_file": "string",
  "client_cert_file": "string",
  "client_key_file": "string",
  "enable": true,
  "key_file": [
    "string"
  ],
  "min_version": "string",
  "redirect_http": true,
  "supported_ciphers": [
    "string"
  ]
}
```

### Properties

| Name                     | Type                                 | Required | Restrictions | Description |
|--------------------------|--------------------------------------|----------|--------------|-------------|
| `address`                | [serpent.HostPort](#serpenthostport) | false    |              |             |
| `allow_insecure_ciphers` | boolean                              | false    |              |             |
| `cert_file`              | array of string                      | false    |              |             |
| `client_auth`            | string                               | false    |              |             |
| `client_ca_file`         | string                               | false    |              |             |
| `client_cert_file`       | string                               | false    |              |             |
| `client_key_file`        | string                               | false    |              |             |
| `enable`                 | boolean                              | false    |              |             |
| `key_file`               | array of string                      | false    |              |             |
| `min_version`            | string                               | false    |              |             |
| `redirect_http`          | boolean                              | false    |              |             |
| `supported_ciphers`      | array of string                      | false    |              |             |

## codersdk.Task

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "current_state": {
    "message": "string",
    "state": "working",
    "timestamp": "2019-08-24T14:15:22Z",
    "uri": "string"
  },
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initial_prompt": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "status": "pending",
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_agent_health": {
    "healthy": false,
    "reason": "agent has lost connection"
  },
  "workspace_agent_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_agent_lifecycle": "created",
  "workspace_app_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_build_number": 0,
  "workspace_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_name": "string",
  "workspace_status": "pending"
}
```

### Properties

| Name                        | Type                                                                 | Required | Restrictions | Description |
|-----------------------------|----------------------------------------------------------------------|----------|--------------|-------------|
| `created_at`                | string                                                               | false    |              |             |
| `current_state`             | [codersdk.TaskStateEntry](#codersdktaskstateentry)                   | false    |              |             |
| `display_name`              | string                                                               | false    |              |             |
| `id`                        | string                                                               | false    |              |             |
| `initial_prompt`            | string                                                               | false    |              |             |
| `name`                      | string                                                               | false    |              |             |
| `organization_id`           | string                                                               | false    |              |             |
| `owner_avatar_url`          | string                                                               | false    |              |             |
| `owner_id`                  | string                                                               | false    |              |             |
| `owner_name`                | string                                                               | false    |              |             |
| `status`                    | [codersdk.TaskStatus](#codersdktaskstatus)                           | false    |              |             |
| `template_display_name`     | string                                                               | false    |              |             |
| `template_icon`             | string                                                               | false    |              |             |
| `template_id`               | string                                                               | false    |              |             |
| `template_name`             | string                                                               | false    |              |             |
| `template_version_id`       | string                                                               | false    |              |             |
| `updated_at`                | string                                                               | false    |              |             |
| `workspace_agent_health`    | [codersdk.WorkspaceAgentHealth](#codersdkworkspaceagenthealth)       | false    |              |             |
| `workspace_agent_id`        | [uuid.NullUUID](#uuidnulluuid)                                       | false    |              |             |
| `workspace_agent_lifecycle` | [codersdk.WorkspaceAgentLifecycle](#codersdkworkspaceagentlifecycle) | false    |              |             |
| `workspace_app_id`          | [uuid.NullUUID](#uuidnulluuid)                                       | false    |              |             |
| `workspace_build_number`    | integer                                                              | false    |              |             |
| `workspace_id`              | [uuid.NullUUID](#uuidnulluuid)                                       | false    |              |             |
| `workspace_name`            | string                                                               | false    |              |             |
| `workspace_status`          | [codersdk.WorkspaceStatus](#codersdkworkspacestatus)                 | false    |              |             |

#### Enumerated Values

| Property           | Value(s)                                                                                                          |
|--------------------|-------------------------------------------------------------------------------------------------------------------|
| `status`           | `active`, `error`, `initializing`, `paused`, `pending`, `unknown`                                                 |
| `workspace_status` | `canceled`, `canceling`, `deleted`, `deleting`, `failed`, `pending`, `running`, `starting`, `stopped`, `stopping` |

## codersdk.TaskLogEntry

```json
{
  "content": "string",
  "id": 0,
  "time": "2019-08-24T14:15:22Z",
  "type": "input"
}
```

### Properties

| Name      | Type                                         | Required | Restrictions | Description |
|-----------|----------------------------------------------|----------|--------------|-------------|
| `content` | string                                       | false    |              |             |
| `id`      | integer                                      | false    |              |             |
| `time`    | string                                       | false    |              |             |
| `type`    | [codersdk.TaskLogType](#codersdktasklogtype) | false    |              |             |

## codersdk.TaskLogType

```json
"input"
```

### Properties

#### Enumerated Values

| Value(s)          |
|-------------------|
| `input`, `output` |

## codersdk.TaskLogsResponse

```json
{
  "logs": [
    {
      "content": "string",
      "id": 0,
      "time": "2019-08-24T14:15:22Z",
      "type": "input"
    }
  ],
  "snapshot": true,
  "snapshot_at": "string"
}
```

### Properties

| Name          | Type                                                    | Required | Restrictions | Description |
|---------------|---------------------------------------------------------|----------|--------------|-------------|
| `logs`        | array of [codersdk.TaskLogEntry](#codersdktasklogentry) | false    |              |             |
| `snapshot`    | boolean                                                 | false    |              |             |
| `snapshot_at` | string                                                  | false    |              |             |

## codersdk.TaskSendRequest

```json
{
  "input": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `input` | string | false    |              |             |

## codersdk.TaskState

```json
"working"
```

### Properties

#### Enumerated Values

| Value(s)                                |
|-----------------------------------------|
| `complete`, `failed`, `idle`, `working` |

## codersdk.TaskStateEntry

```json
{
  "message": "string",
  "state": "working",
  "timestamp": "2019-08-24T14:15:22Z",
  "uri": "string"
}
```

### Properties

| Name        | Type                                     | Required | Restrictions | Description |
|-------------|------------------------------------------|----------|--------------|-------------|
| `message`   | string                                   | false    |              |             |
| `state`     | [codersdk.TaskState](#codersdktaskstate) | false    |              |             |
| `timestamp` | string                                   | false    |              |             |
| `uri`       | string                                   | false    |              |             |

## codersdk.TaskStatus

```json
"pending"
```

### Properties

#### Enumerated Values

| Value(s)                                                          |
|-------------------------------------------------------------------|
| `active`, `error`, `initializing`, `paused`, `pending`, `unknown` |

## codersdk.TasksListResponse

```json
{
  "count": 0,
  "tasks": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "current_state": {
        "message": "string",
        "state": "working",
        "timestamp": "2019-08-24T14:15:22Z",
        "uri": "string"
      },
      "display_name": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initial_prompt": "string",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_avatar_url": "string",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "owner_name": "string",
      "status": "pending",
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "updated_at": "2019-08-24T14:15:22Z",
      "workspace_agent_health": {
        "healthy": false,
        "reason": "agent has lost connection"
      },
      "workspace_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_agent_lifecycle": "created",
      "workspace_app_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_build_number": 0,
      "workspace_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_name": "string",
      "workspace_status": "pending"
    }
  ]
}
```

### Properties

| Name    | Type                                    | Required | Restrictions | Description |
|---------|-----------------------------------------|----------|--------------|-------------|
| `count` | integer                                 | false    |              |             |
| `tasks` | array of [codersdk.Task](#codersdktask) | false    |              |             |

## codersdk.TelemetryConfig

```json
{
  "enable": true,
  "trace": true,
  "url": {
    "forceQuery": true,
    "fragment": "string",
    "host": "string",
    "omitHost": true,
    "opaque": "string",
    "path": "string",
    "rawFragment": "string",
    "rawPath": "string",
    "rawQuery": "string",
    "scheme": "string",
    "user": {}
  }
}
```

### Properties

| Name     | Type                       | Required | Restrictions | Description |
|----------|----------------------------|----------|--------------|-------------|
| `enable` | boolean                    | false    |              |             |
| `trace`  | boolean                    | false    |              |             |
| `url`    | [serpent.URL](#serpenturl) | false    |              |             |

## codersdk.Template

```json
{
  "active_user_count": 0,
  "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc",
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "build_time_stats": {
    "property1": {
      "p50": 123,
      "p95": 146
    },
    "property2": {
      "p50": 123,
      "p95": 146
    }
  },
  "cors_behavior": "simple",
  "created_at": "2019-08-24T14:15:22Z",
  "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f",
  "created_by_name": "string",
  "default_ttl_ms": 0,
  "deleted": true,
  "deprecated": true,
  "deprecation_message": "string",
  "description": "string",
  "disable_module_cache": true,
  "display_name": "string",
  "failure_ttl_ms": 0,
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "max_port_share_level": "owner",
  "name": "string",
  "organization_display_name": "string",
  "organization_icon": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "provisioner": "terraform",
  "require_active_version": true,
  "time_til_dormant_autodelete_ms": 0,
  "time_til_dormant_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z",
  "use_classic_parameter_flow": true
}
```

### Properties

| Name                               | Type                                                                           | Required | Restrictions | Description                                                                                                                                                                                     |
|------------------------------------|--------------------------------------------------------------------------------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `active_user_count`                | integer                                                                        | false    |              | Active user count is set to -1 when loading.                                                                                                                                                    |
| `active_version_id`                | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `activity_bump_ms`                 | integer                                                                        | false    |              |                                                                                                                                                                                                 |
| `allow_user_autostart`             | boolean                                                                        | false    |              | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature.                         |
| `allow_user_autostop`              | boolean                                                                        | false    |              |                                                                                                                                                                                                 |
| `allow_user_cancel_workspace_jobs` | boolean                                                                        | false    |              |                                                                                                                                                                                                 |
| `autostart_requirement`            | [codersdk.TemplateAutostartRequirement](#codersdktemplateautostartrequirement) | false    |              |                                                                                                                                                                                                 |
| `autostop_requirement`             | [codersdk.TemplateAutostopRequirement](#codersdktemplateautostoprequirement)   | false    |              | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature.                      |
| `build_time_stats`                 | [codersdk.TemplateBuildTimeStats](#codersdktemplatebuildtimestats)             | false    |              |                                                                                                                                                                                                 |
| `cors_behavior`                    | [codersdk.CORSBehavior](#codersdkcorsbehavior)                                 | false    |              |                                                                                                                                                                                                 |
| `created_at`                       | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `created_by_id`                    | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `created_by_name`                  | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `default_ttl_ms`                   | integer                                                                        | false    |              |                                                                                                                                                                                                 |
| `deleted`                          | boolean                                                                        | false    |              |                                                                                                                                                                                                 |
| `deprecated`                       | boolean                                                                        | false    |              |                                                                                                                                                                                                 |
| `deprecation_message`              | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `description`                      | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `disable_module_cache`             | boolean                                                                        | false    |              | Disable module cache disables the use of cached Terraform modules during provisioning.                                                                                                          |
| `display_name`                     | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `failure_ttl_ms`                   | integer                                                                        | false    |              | Failure ttl ms TimeTilDormantMillis, and TimeTilDormantAutoDeleteMillis are enterprise-only. Their values are used if your license is entitled to use the advanced template scheduling feature. |
| `icon`                             | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `id`                               | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `max_port_share_level`             | [codersdk.WorkspaceAgentPortShareLevel](#codersdkworkspaceagentportsharelevel) | false    |              |                                                                                                                                                                                                 |
| `name`                             | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `organization_display_name`        | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `organization_icon`                | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `organization_id`                  | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `organization_name`                | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `provisioner`                      | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `require_active_version`           | boolean                                                                        | false    |              | Require active version mandates that workspaces are built with the active template version.                                                                                                     |
| `time_til_dormant_autodelete_ms`   | integer                                                                        | false    |              |                                                                                                                                                                                                 |
| `time_til_dormant_ms`              | integer                                                                        | false    |              |                                                                                                                                                                                                 |
| `updated_at`                       | string                                                                         | false    |              |                                                                                                                                                                                                 |
| `use_classic_parameter_flow`       | boolean                                                                        | false    |              |                                                                                                                                                                                                 |

#### Enumerated Values

| Property      | Value(s)    |
|---------------|-------------|
| `provisioner` | `terraform` |

## codersdk.TemplateACL

```json
{
  "group": [
    {
      "avatar_url": "http://example.com",
      "display_name": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "members": [
        {
          "avatar_url": "http://example.com",
          "created_at": "2019-08-24T14:15:22Z",
          "email": "user@example.com",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "is_service_account": true,
          "last_seen_at": "2019-08-24T14:15:22Z",
          "login_type": "",
          "name": "string",
          "status": "active",
          "theme_preference": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "username": "string"
        }
      ],
      "name": "string",
      "organization_display_name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "organization_name": "string",
      "quota_allowance": 0,
      "role": "admin",
      "source": "user",
      "total_member_count": 0
    }
  ],
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "has_ai_seat": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "organization_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "role": "admin",
      "roles": [
        {
          "display_name": "string",
          "name": "string",
          "organization_id": "string"
        }
      ],
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                                      | Required | Restrictions | Description |
|---------|-----------------------------------------------------------|----------|--------------|-------------|
| `group` | array of [codersdk.TemplateGroup](#codersdktemplategroup) | false    |              |             |
| `users` | array of [codersdk.TemplateUser](#codersdktemplateuser)   | false    |              |             |

## codersdk.TemplateAppUsage

```json
{
  "display_name": "Visual Studio Code",
  "icon": "string",
  "seconds": 80500,
  "slug": "vscode",
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "times_used": 2,
  "type": "builtin"
}
```

### Properties

| Name           | Type                                                   | Required | Restrictions | Description |
|----------------|--------------------------------------------------------|----------|--------------|-------------|
| `display_name` | string                                                 | false    |              |             |
| `icon`         | string                                                 | false    |              |             |
| `seconds`      | integer                                                | false    |              |             |
| `slug`         | string                                                 | false    |              |             |
| `template_ids` | array of string                                        | false    |              |             |
| `times_used`   | integer                                                | false    |              |             |
| `type`         | [codersdk.TemplateAppsType](#codersdktemplateappstype) | false    |              |             |

## codersdk.TemplateAppsType

```json
"builtin"
```

### Properties

#### Enumerated Values

| Value(s)         |
|------------------|
| `app`, `builtin` |

## codersdk.TemplateAutostartRequirement

```json
{
  "days_of_week": [
    "monday"
  ]
}
```

### Properties

| Name           | Type            | Required | Restrictions | Description                                                                                                                             |
|----------------|-----------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------|
| `days_of_week` | array of string | false    |              | Days of week is a list of days of the week in which autostart is allowed to happen. If no days are specified, autostart is not allowed. |

## codersdk.TemplateAutostopRequirement

```json
{
  "days_of_week": [
    "monday"
  ],
  "weeks": 0
}
```

### Properties

|Name|Type|Required|Restrictions|Description|
|---|---|---|---|---|
|`days_of_week`|array of string|false||Days of week is a list of days of the week on which restarts are required. Restarts happen within the user's quiet hours (in their configured timezone). If no days are specified, restarts are not required. Weekdays cannot be specified twice.
Restarts will only happen on weekdays in this list on weeks which line up with Weeks.|
|`weeks`|integer|false||Weeks is the number of weeks between required restarts. Weeks are synced across all workspaces (and Coder deployments) using modulo math on a hardcoded epoch week of January 2nd, 2023 (the first Monday of 2023). Values of 0 or 1 indicate weekly restarts. Values of 2 indicate fortnightly restarts, etc.|

## codersdk.TemplateBuildTimeStats

```json
{
  "property1": {
    "p50": 123,
    "p95": 146
  },
  "property2": {
    "p50": 123,
    "p95": 146
  }
}
```

### Properties

| Name             | Type                                                 | Required | Restrictions | Description |
|------------------|------------------------------------------------------|----------|--------------|-------------|
| `[any property]` | [codersdk.TransitionStats](#codersdktransitionstats) | false    |              |             |

## codersdk.TemplateExample

```json
{
  "description": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "markdown": "string",
  "name": "string",
  "tags": [
    "string"
  ],
  "url": "string"
}
```

### Properties

| Name          | Type            | Required | Restrictions | Description |
|---------------|-----------------|----------|--------------|-------------|
| `description` | string          | false    |              |             |
| `icon`        | string          | false    |              |             |
| `id`          | string          | false    |              |             |
| `markdown`    | string          | false    |              |             |
| `name`        | string          | false    |              |             |
| `tags`        | array of string | false    |              |             |
| `url`         | string          | false    |              |             |

## codersdk.TemplateGroup

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "role": "admin",
  "source": "user",
  "total_member_count": 0
}
```

### Properties

| Name                        | Type                                                  | Required | Restrictions | Description                                                                                                                                                           |
|-----------------------------|-------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `avatar_url`                | string                                                | false    |              |                                                                                                                                                                       |
| `display_name`              | string                                                | false    |              |                                                                                                                                                                       |
| `id`                        | string                                                | false    |              |                                                                                                                                                                       |
| `members`                   | array of [codersdk.ReducedUser](#codersdkreduceduser) | false    |              |                                                                                                                                                                       |
| `name`                      | string                                                | false    |              |                                                                                                                                                                       |
| `organization_display_name` | string                                                | false    |              |                                                                                                                                                                       |
| `organization_id`           | string                                                | false    |              |                                                                                                                                                                       |
| `organization_name`         | string                                                | false    |              |                                                                                                                                                                       |
| `quota_allowance`           | integer                                               | false    |              |                                                                                                                                                                       |
| `role`                      | [codersdk.TemplateRole](#codersdktemplaterole)        | false    |              |                                                                                                                                                                       |
| `source`                    | [codersdk.GroupSource](#codersdkgroupsource)          | false    |              |                                                                                                                                                                       |
| `total_member_count`        | integer                                               | false    |              | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |

#### Enumerated Values

| Property | Value(s)       |
|----------|----------------|
| `role`   | `admin`, `use` |

## codersdk.TemplateInsightsIntervalReport

```json
{
  "active_users": 14,
  "end_time": "2019-08-24T14:15:22Z",
  "interval": "week",
  "start_time": "2019-08-24T14:15:22Z",
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ]
}
```

### Properties

| Name           | Type                                                               | Required | Restrictions | Description |
|----------------|--------------------------------------------------------------------|----------|--------------|-------------|
| `active_users` | integer                                                            | false    |              |             |
| `end_time`     | string                                                             | false    |              |             |
| `interval`     | [codersdk.InsightsReportInterval](#codersdkinsightsreportinterval) | false    |              |             |
| `start_time`   | string                                                             | false    |              |             |
| `template_ids` | array of string                                                    | false    |              |             |

## codersdk.TemplateInsightsReport

```json
{
  "active_users": 22,
  "apps_usage": [
    {
      "display_name": "Visual Studio Code",
      "icon": "string",
      "seconds": 80500,
      "slug": "vscode",
      "template_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "times_used": 2,
      "type": "builtin"
    }
  ],
  "end_time": "2019-08-24T14:15:22Z",
  "parameters_usage": [
    {
      "description": "string",
      "display_name": "string",
      "name": "string",
      "options": [
        {
          "description": "string",
          "icon": "string",
          "name": "string",
          "value": "string"
        }
      ],
      "template_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "type": "string",
      "values": [
        {
          "count": 0,
          "value": "string"
        }
      ]
    }
  ],
  "start_time": "2019-08-24T14:15:22Z",
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ]
}
```

### Properties

| Name               | Type                                                                        | Required | Restrictions | Description |
|--------------------|-----------------------------------------------------------------------------|----------|--------------|-------------|
| `active_users`     | integer                                                                     | false    |              |             |
| `apps_usage`       | array of [codersdk.TemplateAppUsage](#codersdktemplateappusage)             | false    |              |             |
| `end_time`         | string                                                                      | false    |              |             |
| `parameters_usage` | array of [codersdk.TemplateParameterUsage](#codersdktemplateparameterusage) | false    |              |             |
| `start_time`       | string                                                                      | false    |              |             |
| `template_ids`     | array of string                                                             | false    |              |             |

## codersdk.TemplateInsightsResponse

```json
{
  "interval_reports": [
    {
      "active_users": 14,
      "end_time": "2019-08-24T14:15:22Z",
      "interval": "week",
      "start_time": "2019-08-24T14:15:22Z",
      "template_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ]
    }
  ],
  "report": {
    "active_users": 22,
    "apps_usage": [
      {
        "display_name": "Visual Studio Code",
        "icon": "string",
        "seconds": 80500,
        "slug": "vscode",
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "times_used": 2,
        "type": "builtin"
      }
    ],
    "end_time": "2019-08-24T14:15:22Z",
    "parameters_usage": [
      {
        "description": "string",
        "display_name": "string",
        "name": "string",
        "options": [
          {
            "description": "string",
            "icon": "string",
            "name": "string",
            "value": "string"
          }
        ],
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "type": "string",
        "values": [
          {
            "count": 0,
            "value": "string"
          }
        ]
      }
    ],
    "start_time": "2019-08-24T14:15:22Z",
    "template_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ]
  }
}
```

### Properties

| Name               | Type                                                                                        | Required | Restrictions | Description |
|--------------------|---------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `interval_reports` | array of [codersdk.TemplateInsightsIntervalReport](#codersdktemplateinsightsintervalreport) | false    |              |             |
| `report`           | [codersdk.TemplateInsightsReport](#codersdktemplateinsightsreport)                          | false    |              |             |

## codersdk.TemplateParameterUsage

```json
{
  "description": "string",
  "display_name": "string",
  "name": "string",
  "options": [
    {
      "description": "string",
      "icon": "string",
      "name": "string",
      "value": "string"
    }
  ],
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "type": "string",
  "values": [
    {
      "count": 0,
      "value": "string"
    }
  ]
}
```

### Properties

| Name           | Type                                                                                        | Required | Restrictions | Description |
|----------------|---------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `description`  | string                                                                                      | false    |              |             |
| `display_name` | string                                                                                      | false    |              |             |
| `name`         | string                                                                                      | false    |              |             |
| `options`      | array of [codersdk.TemplateVersionParameterOption](#codersdktemplateversionparameteroption) | false    |              |             |
| `template_ids` | array of string                                                                             | false    |              |             |
| `type`         | string                                                                                      | false    |              |             |
| `values`       | array of [codersdk.TemplateParameterValue](#codersdktemplateparametervalue)                 | false    |              |             |

## codersdk.TemplateParameterValue

```json
{
  "count": 0,
  "value": "string"
}
```

### Properties

| Name    | Type    | Required | Restrictions | Description |
|---------|---------|----------|--------------|-------------|
| `count` | integer | false    |              |             |
| `value` | string  | false    |              |             |

## codersdk.TemplateRole

```json
"admin"
```

### Properties

#### Enumerated Values

| Value(s)           |
|--------------------|
| ``, `admin`, `use` |

## codersdk.TemplateUser

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "role": "admin",
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Properties

| Name                 | Type                                            | Required | Restrictions | Description                                                                                      |
|----------------------|-------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------|
| `avatar_url`         | string                                          | false    |              |                                                                                                  |
| `created_at`         | string                                          | true     |              |                                                                                                  |
| `email`              | string                                          | true     |              |                                                                                                  |
| `has_ai_seat`        | boolean                                         | false    |              | Has ai seat intentionally omits omitempty so the API always includes the field, even when false. |
| `id`                 | string                                          | true     |              |                                                                                                  |
| `is_service_account` | boolean                                         | false    |              |                                                                                                  |
| `last_seen_at`       | string                                          | false    |              |                                                                                                  |
| `login_type`         | [codersdk.LoginType](#codersdklogintype)        | false    |              |                                                                                                  |
| `name`               | string                                          | false    |              |                                                                                                  |
| `organization_ids`   | array of string                                 | false    |              |                                                                                                  |
| `role`               | [codersdk.TemplateRole](#codersdktemplaterole)  | false    |              |                                                                                                  |
| `roles`              | array of [codersdk.SlimRole](#codersdkslimrole) | false    |              |                                                                                                  |
| `status`             | [codersdk.UserStatus](#codersdkuserstatus)      | false    |              |                                                                                                  |
| `theme_preference`   | string                                          | false    |              | Deprecated: this value should be retrieved from `codersdk.UserPreferenceSettings` instead.       |
| `updated_at`         | string                                          | false    |              |                                                                                                  |
| `username`           | string                                          | true     |              |                                                                                                  |

#### Enumerated Values

| Property | Value(s)              |
|----------|-----------------------|
| `role`   | `admin`, `use`        |
| `status` | `active`, `suspended` |

## codersdk.TemplateVersion

```json
{
  "archived": true,
  "created_at": "2019-08-24T14:15:22Z",
  "created_by": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "message": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "readme": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "UNSUPPORTED_WORKSPACES"
  ]
}
```

### Properties

| Name                   | Type                                                                        | Required | Restrictions | Description |
|------------------------|-----------------------------------------------------------------------------|----------|--------------|-------------|
| `archived`             | boolean                                                                     | false    |              |             |
| `created_at`           | string                                                                      | false    |              |             |
| `created_by`           | [codersdk.MinimalUser](#codersdkminimaluser)                                | false    |              |             |
| `has_external_agent`   | boolean                                                                     | false    |              |             |
| `id`                   | string                                                                      | false    |              |             |
| `job`                  | [codersdk.ProvisionerJob](#codersdkprovisionerjob)                          | false    |              |             |
| `matched_provisioners` | [codersdk.MatchedProvisioners](#codersdkmatchedprovisioners)                | false    |              |             |
| `message`              | string                                                                      | false    |              |             |
| `name`                 | string                                                                      | false    |              |             |
| `organization_id`      | string                                                                      | false    |              |             |
| `readme`               | string                                                                      | false    |              |             |
| `template_id`          | string                                                                      | false    |              |             |
| `updated_at`           | string                                                                      | false    |              |             |
| `warnings`             | array of [codersdk.TemplateVersionWarning](#codersdktemplateversionwarning) | false    |              |             |

## codersdk.TemplateVersionExternalAuth

```json
{
  "authenticate_url": "string",
  "authenticated": true,
  "display_icon": "string",
  "display_name": "string",
  "id": "string",
  "optional": true,
  "type": "string"
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description |
|--------------------|---------|----------|--------------|-------------|
| `authenticate_url` | string  | false    |              |             |
| `authenticated`    | boolean | false    |              |             |
| `display_icon`     | string  | false    |              |             |
| `display_name`     | string  | false    |              |             |
| `id`               | string  | false    |              |             |
| `optional`         | boolean | false    |              |             |
| `type`             | string  | false    |              |             |

## codersdk.TemplateVersionParameter

```json
{
  "default_value": "string",
  "description": "string",
  "description_plaintext": "string",
  "display_name": "string",
  "ephemeral": true,
  "form_type": "",
  "icon": "string",
  "mutable": true,
  "name": "string",
  "options": [
    {
      "description": "string",
      "icon": "string",
      "name": "string",
      "value": "string"
    }
  ],
  "required": true,
  "type": "string",
  "validation_error": "string",
  "validation_max": 0,
  "validation_min": 0,
  "validation_monotonic": "increasing",
  "validation_regex": "string"
}
```

### Properties

| Name                    | Type                                                                                        | Required | Restrictions | Description                                                                                        |
|-------------------------|---------------------------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------|
| `default_value`         | string                                                                                      | false    |              |                                                                                                    |
| `description`           | string                                                                                      | false    |              |                                                                                                    |
| `description_plaintext` | string                                                                                      | false    |              |                                                                                                    |
| `display_name`          | string                                                                                      | false    |              |                                                                                                    |
| `ephemeral`             | boolean                                                                                     | false    |              |                                                                                                    |
| `form_type`             | string                                                                                      | false    |              | Form type has an enum value of empty string, `""`. Keep the leading comma in the enums struct tag. |
| `icon`                  | string                                                                                      | false    |              |                                                                                                    |
| `mutable`               | boolean                                                                                     | false    |              |                                                                                                    |
| `name`                  | string                                                                                      | false    |              |                                                                                                    |
| `options`               | array of [codersdk.TemplateVersionParameterOption](#codersdktemplateversionparameteroption) | false    |              |                                                                                                    |
| `required`              | boolean                                                                                     | false    |              |                                                                                                    |
| `type`                  | string                                                                                      | false    |              |                                                                                                    |
| `validation_error`      | string                                                                                      | false    |              |                                                                                                    |
| `validation_max`        | integer                                                                                     | false    |              |                                                                                                    |
| `validation_min`        | integer                                                                                     | false    |              |                                                                                                    |
| `validation_monotonic`  | [codersdk.ValidationMonotonicOrder](#codersdkvalidationmonotonicorder)                      | false    |              |                                                                                                    |
| `validation_regex`      | string                                                                                      | false    |              |                                                                                                    |

#### Enumerated Values

| Property               | Value(s)                                                                                                            |
|------------------------|---------------------------------------------------------------------------------------------------------------------|
| `form_type`            | ``, `checkbox`, `dropdown`, `error`, `input`, `multi-select`, `radio`, `slider`, `switch`, `tag-select`, `textarea` |
| `type`                 | `bool`, `list(string)`, `number`, `string`                                                                          |
| `validation_monotonic` | `decreasing`, `increasing`                                                                                          |

## codersdk.TemplateVersionParameterOption

```json
{
  "description": "string",
  "icon": "string",
  "name": "string",
  "value": "string"
}
```

### Properties

| Name          | Type   | Required | Restrictions | Description |
|---------------|--------|----------|--------------|-------------|
| `description` | string | false    |              |             |
| `icon`        | string | false    |              |             |
| `name`        | string | false    |              |             |
| `value`       | string | false    |              |             |

## codersdk.TemplateVersionVariable

```json
{
  "default_value": "string",
  "description": "string",
  "name": "string",
  "required": true,
  "sensitive": true,
  "type": "string",
  "value": "string"
}
```

### Properties

| Name            | Type    | Required | Restrictions | Description |
|-----------------|---------|----------|--------------|-------------|
| `default_value` | string  | false    |              |             |
| `description`   | string  | false    |              |             |
| `name`          | string  | false    |              |             |
| `required`      | boolean | false    |              |             |
| `sensitive`     | boolean | false    |              |             |
| `type`          | string  | false    |              |             |
| `value`         | string  | false    |              |             |

#### Enumerated Values

| Property | Value(s)                   |
|----------|----------------------------|
| `type`   | `bool`, `number`, `string` |

## codersdk.TemplateVersionWarning

```json
"UNSUPPORTED_WORKSPACES"
```

### Properties

#### Enumerated Values

| Value(s)                 |
|--------------------------|
| `UNSUPPORTED_WORKSPACES` |

## codersdk.TerminalFontName

```json
""
```

### Properties

#### Enumerated Values

| Value(s)                                                                            |
|-------------------------------------------------------------------------------------|
| ``, `fira-code`, `geist-mono`, `ibm-plex-mono`, `jetbrains-mono`, `source-code-pro` |

## codersdk.ThinkingDisplayMode

```json
"auto"
```

### Properties

#### Enumerated Values

| Value(s)                                                 |
|----------------------------------------------------------|
| `always_collapsed`, `always_expanded`, `auto`, `preview` |

## codersdk.TimingStage

```json
"init"
```

### Properties

#### Enumerated Values

| Value(s)                                                             |
|----------------------------------------------------------------------|
| `apply`, `connect`, `cron`, `graph`, `init`, `plan`, `start`, `stop` |

## codersdk.TokenConfig

```json
{
  "max_token_lifetime": 0
}
```

### Properties

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `max_token_lifetime` | integer | false    |              |             |

## codersdk.TraceConfig

```json
{
  "capture_logs": true,
  "data_dog": true,
  "enable": true,
  "honeycomb_api_key": "string"
}
```

### Properties

| Name                | Type    | Required | Restrictions | Description |
|---------------------|---------|----------|--------------|-------------|
| `capture_logs`      | boolean | false    |              |             |
| `data_dog`          | boolean | false    |              |             |
| `enable`            | boolean | false    |              |             |
| `honeycomb_api_key` | string  | false    |              |             |

## codersdk.TransitionStats

```json
{
  "p50": 123,
  "p95": 146
}
```

### Properties

| Name  | Type    | Required | Restrictions | Description |
|-------|---------|----------|--------------|-------------|
| `p50` | integer | false    |              |             |
| `p95` | integer | false    |              |             |

## codersdk.UpdateActiveTemplateVersion

```json
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}
```

### Properties

| Name | Type   | Required | Restrictions | Description |
|------|--------|----------|--------------|-------------|
| `id` | string | true     |              |             |

## codersdk.UpdateAppearanceConfig

```json
{
  "announcement_banners": [
    {
      "background_color": "string",
      "enabled": true,
      "message": "string"
    }
  ],
  "application_name": "string",
  "logo_url": "string",
  "service_banner": {
    "background_color": "string",
    "enabled": true,
    "message": "string"
  }
}
```

### Properties

| Name                   | Type                                                    | Required | Restrictions | Description                                                         |
|------------------------|---------------------------------------------------------|----------|--------------|---------------------------------------------------------------------|
| `announcement_banners` | array of [codersdk.BannerConfig](#codersdkbannerconfig) | false    |              |                                                                     |
| `application_name`     | string                                                  | false    |              |                                                                     |
| `logo_url`             | string                                                  | false    |              |                                                                     |
| `service_banner`       | [codersdk.BannerConfig](#codersdkbannerconfig)          | false    |              | Deprecated: ServiceBanner has been replaced by AnnouncementBanners. |

## codersdk.UpdateChatRequest

```json
{
  "archived": true,
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "pin_order": 0,
  "plan_mode": "plan",
  "title": "string",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Properties

| Name               | Type                                           | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                                                                                                                                             |
|--------------------|------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `archived`         | boolean                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `labels`           | object                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| » `[any property]` | string                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `pin_order`        | integer                                        | false    |              | Pin order controls the chat's pinned state and position. - nil: no change to pin state. - 0: unpin the chat. - >0 (chat is unpinned): pin the chat, appending it to   the end of the pinned list. The specific value is   ignored; the server assigns the next available position. - >0 (chat is already pinned): move the chat to the   requested position, shifting neighbors as needed. The   value is clamped to [1, pinned_count]. |
| `plan_mode`        | [codersdk.ChatPlanMode](#codersdkchatplanmode) | false    |              | Plan mode switches the chat's persistent plan mode. nil: no change, ptr to "plan": enable, ptr to "": clear.                                                                                                                                                                                                                                                                                                                            |
| `title`            | string                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `workspace_id`     | string                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                                                                         |

## codersdk.UpdateChatRetentionDaysRequest

```json
{
  "retention_days": 0
}
```

### Properties

| Name             | Type    | Required | Restrictions | Description |
|------------------|---------|----------|--------------|-------------|
| `retention_days` | integer | false    |              |             |

## codersdk.UpdateCheckResponse

```json
{
  "current": true,
  "url": "string",
  "version": "string"
}
```

### Properties

| Name      | Type    | Required | Restrictions | Description                                                             |
|-----------|---------|----------|--------------|-------------------------------------------------------------------------|
| `current` | boolean | false    |              | Current indicates whether the server version is the same as the latest. |
| `url`     | string  | false    |              | URL to download the latest release of Coder.                            |
| `version` | string  | false    |              | Version is the semantic version for the latest release of Coder.        |

## codersdk.UpdateOrganizationRequest

```json
{
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "name": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `description`  | string | false    |              |             |
| `display_name` | string | false    |              |             |
| `icon`         | string | false    |              |             |
| `name`         | string | false    |              |             |

## codersdk.UpdateRoles

```json
{
  "roles": [
    "string"
  ]
}
```

### Properties

| Name    | Type            | Required | Restrictions | Description |
|---------|-----------------|----------|--------------|-------------|
| `roles` | array of string | false    |              |             |

## codersdk.UpdateTaskInputRequest

```json
{
  "input": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `input` | string | false    |              |             |

## codersdk.UpdateTemplateACL

```json
{
  "group_perms": {
    "8bd26b20-f3e8-48be-a903-46bb920cf671": "use",
    "<group_id>": "admin"
  },
  "user_perms": {
    "4df59e74-c027-470b-ab4d-cbba8963a5e9": "use",
    "<user_id>": "admin"
  }
}
```

### Properties

| Name               | Type                                           | Required | Restrictions | Description                                                                                                                                                                                                       |
|--------------------|------------------------------------------------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `group_perms`      | object                                         | false    |              | Group perms is a mapping from valid group UUIDs to the template role they should be granted. To remove a group from the template, use "" as the role (available as a constant named codersdk.TemplateRoleDeleted) |
| » `[any property]` | [codersdk.TemplateRole](#codersdktemplaterole) | false    |              |                                                                                                                                                                                                                   |
| `user_perms`       | object                                         | false    |              | User perms is a mapping from valid user UUIDs to the template role they should be granted. To remove a user from the template, use "" as the role (available as a constant named codersdk.TemplateRoleDeleted)    |
| » `[any property]` | [codersdk.TemplateRole](#codersdktemplaterole) | false    |              |                                                                                                                                                                                                                   |

## codersdk.UpdateTemplateMeta

```json
{
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "cors_behavior": "simple",
  "default_ttl_ms": 0,
  "deprecation_message": "string",
  "description": "string",
  "disable_everyone_group_access": true,
  "disable_module_cache": true,
  "display_name": "string",
  "failure_ttl_ms": 0,
  "icon": "string",
  "max_port_share_level": "owner",
  "name": "string",
  "require_active_version": true,
  "time_til_dormant_autodelete_ms": 0,
  "time_til_dormant_ms": 0,
  "update_workspace_dormant_at": true,
  "update_workspace_last_used_at": true,
  "use_classic_parameter_flow": true
}
```

### Properties

| Name                               | Type                                                                           | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                                                                                        |
|------------------------------------|--------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `activity_bump_ms`                 | integer                                                                        | false    |              | Activity bump ms allows optionally specifying the activity bump duration for all workspaces created from this template. Defaults to 1h but can be set to 0 to disable activity bumping.                                                                                                                                                                                            |
| `allow_user_autostart`             | boolean                                                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `allow_user_autostop`              | boolean                                                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `allow_user_cancel_workspace_jobs` | boolean                                                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `autostart_requirement`            | [codersdk.TemplateAutostartRequirement](#codersdktemplateautostartrequirement) | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `autostop_requirement`             | [codersdk.TemplateAutostopRequirement](#codersdktemplateautostoprequirement)   | false    |              | Autostop requirement and AutostartRequirement can only be set if your license includes the advanced template scheduling feature. If you attempt to set this value while unlicensed, it will be ignored.                                                                                                                                                                            |
| `cors_behavior`                    | [codersdk.CORSBehavior](#codersdkcorsbehavior)                                 | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `default_ttl_ms`                   | integer                                                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `deprecation_message`              | string                                                                         | false    |              | Deprecation message if set, will mark the template as deprecated and block any new workspaces from using this template. If passed an empty string, will remove the deprecated message, making the template usable for new workspaces again.                                                                                                                                        |
| `description`                      | string                                                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `disable_everyone_group_access`    | boolean                                                                        | false    |              | Disable everyone group access allows optionally disabling the default behavior of granting the 'everyone' group access to use the template. If this is set to true, the template will not be available to all users, and must be explicitly granted to users or groups in the permissions settings of the template.                                                                |
| `disable_module_cache`             | boolean                                                                        | false    |              | Disable module cache disables the using of cached Terraform modules during provisioning. It is recommended not to disable this.                                                                                                                                                                                                                                                    |
| `display_name`                     | string                                                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `failure_ttl_ms`                   | integer                                                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `icon`                             | string                                                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `max_port_share_level`             | [codersdk.WorkspaceAgentPortShareLevel](#codersdkworkspaceagentportsharelevel) | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `name`                             | string                                                                         | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `require_active_version`           | boolean                                                                        | false    |              | Require active version mandates workspaces built using this template use the active version of the template. This option has no effect on template admins.                                                                                                                                                                                                                         |
| `time_til_dormant_autodelete_ms`   | integer                                                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `time_til_dormant_ms`              | integer                                                                        | false    |              |                                                                                                                                                                                                                                                                                                                                                                                    |
| `update_workspace_dormant_at`      | boolean                                                                        | false    |              | Update workspace dormant at updates the dormant_at field of workspaces spawned from the template. This is useful for preventing dormant workspaces being immediately deleted when updating the dormant_ttl field to a new, shorter value.                                                                                                                                          |
| `update_workspace_last_used_at`    | boolean                                                                        | false    |              | Update workspace last used at updates the last_used_at field of workspaces spawned from the template. This is useful for preventing workspaces being immediately locked when updating the inactivity_ttl field to a new, shorter value.                                                                                                                                            |
| `use_classic_parameter_flow`       | boolean                                                                        | false    |              | Use classic parameter flow is a flag that switches the default behavior to use the classic parameter flow when creating a workspace. This only affects deployments with the experiment "dynamic-parameters" enabled. This setting will live for a period after the experiment is made the default. An "opt-out" is present in case the new feature breaks some existing templates. |

## codersdk.UpdateUserAppearanceSettingsRequest

```json
{
  "terminal_font": "",
  "theme_preference": "string"
}
```

### Properties

| Name               | Type                                                   | Required | Restrictions | Description |
|--------------------|--------------------------------------------------------|----------|--------------|-------------|
| `terminal_font`    | [codersdk.TerminalFontName](#codersdkterminalfontname) | true     |              |             |
| `theme_preference` | string                                                 | true     |              |             |

## codersdk.UpdateUserNotificationPreferences

```json
{
  "template_disabled_map": {
    "property1": true,
    "property2": true
  }
}
```

### Properties

| Name                    | Type    | Required | Restrictions | Description |
|-------------------------|---------|----------|--------------|-------------|
| `template_disabled_map` | object  | false    |              |             |
| » `[any property]`      | boolean | false    |              |             |

## codersdk.UpdateUserPasswordRequest

```json
{
  "old_password": "string",
  "password": "string"
}
```

### Properties

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `old_password` | string | false    |              |             |
| `password`     | string | true     |              |             |

## codersdk.UpdateUserPreferenceSettingsRequest

```json
{
  "code_diff_display_mode": "auto",
  "task_notification_alert_dismissed": true,
  "thinking_display_mode": "auto"
}
```

### Properties

| Name                                | Type                                                         | Required | Restrictions | Description |
|-------------------------------------|--------------------------------------------------------------|----------|--------------|-------------|
| `code_diff_display_mode`            | [codersdk.AgentDisplayMode](#codersdkagentdisplaymode)       | false    |              |             |
| `task_notification_alert_dismissed` | boolean                                                      | false    |              |             |
| `thinking_display_mode`             | [codersdk.ThinkingDisplayMode](#codersdkthinkingdisplaymode) | false    |              |             |

## codersdk.UpdateUserProfileRequest

```json
{
  "name": "string",
  "username": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `name`     | string | false    |              |             |
| `username` | string | true     |              |             |

## codersdk.UpdateUserQuietHoursScheduleRequest

```json
{
  "schedule": "string"
}
```

### Properties

|Name|Type|Required|Restrictions|Description|
|---|---|---|---|---|
|`schedule`|string|true||Schedule is a cron expression that defines when the user's quiet hours window is. Schedule must not be empty. For new users, the schedule is set to 2am in their browser or computer's timezone. The schedule denotes the beginning of a 4 hour window where the workspace is allowed to automatically stop or restart due to maintenance or template schedule.
The schedule must be daily with a single time, and should have a timezone specified via a CRON_TZ prefix (otherwise UTC will be used).
If the schedule is empty, the user will be updated to use the default schedule.|

## codersdk.UpdateUserSecretRequest

```json
{
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "value": "string"
}
```

### Properties

| Name          | Type   | Required | Restrictions | Description |
|---------------|--------|----------|--------------|-------------|
| `description` | string | false    |              |             |
| `env_name`    | string | false    |              |             |
| `file_path`   | string | false    |              |             |
| `value`       | string | false    |              |             |

## codersdk.UpdateWorkspaceACL

```json
{
  "group_roles": {
    "property1": "admin",
    "property2": "admin"
  },
  "user_roles": {
    "property1": "admin",
    "property2": "admin"
  }
}
```

### Properties

| Name               | Type                                             | Required | Restrictions | Description                                                                                                                                                                                                          |
|--------------------|--------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `group_roles`      | object                                           | false    |              | Group roles is a mapping from valid group UUIDs to the workspace role they should be granted. To remove a group from the workspace, use "" as the role (available as a constant named codersdk.WorkspaceRoleDeleted) |
| » `[any property]` | [codersdk.WorkspaceRole](#codersdkworkspacerole) | false    |              |                                                                                                                                                                                                                      |
| `user_roles`       | object                                           | false    |              | User roles is a mapping from valid user UUIDs to the workspace role they should be granted. To remove a user from the workspace, use "" as the role (available as a constant named codersdk.WorkspaceRoleDeleted)    |
| » `[any property]` | [codersdk.WorkspaceRole](#codersdkworkspacerole) | false    |              |                                                                                                                                                                                                                      |

## codersdk.UpdateWorkspaceAutomaticUpdatesRequest

```json
{
  "automatic_updates": "always"
}
```

### Properties

| Name                | Type                                                   | Required | Restrictions | Description |
|---------------------|--------------------------------------------------------|----------|--------------|-------------|
| `automatic_updates` | [codersdk.AutomaticUpdates](#codersdkautomaticupdates) | false    |              |             |

## codersdk.UpdateWorkspaceAutostartRequest

```json
{
  "schedule": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description                                                                                                                                                                                                                                    |
|------------|--------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `schedule` | string | false    |              | Schedule is expected to be of the form `CRON_TZ=<IANA Timezone> <min> <hour> * * <dow>` Example: `CRON_TZ=US/Central 30 9 * * 1-5` represents 0930 in the timezone US/Central on weekdays (Mon-Fri). `CRON_TZ` defaults to UTC if not present. |

## codersdk.UpdateWorkspaceBuildStateRequest

```json
{
  "state": [
    0
  ]
}
```

### Properties

| Name    | Type             | Required | Restrictions | Description |
|---------|------------------|----------|--------------|-------------|
| `state` | array of integer | false    |              |             |

## codersdk.UpdateWorkspaceDormancy

```json
{
  "dormant": true
}
```

### Properties

| Name      | Type    | Required | Restrictions | Description |
|-----------|---------|----------|--------------|-------------|
| `dormant` | boolean | false    |              |             |

## codersdk.UpdateWorkspaceRequest

```json
{
  "name": "string"
}
```

### Properties

| Name   | Type   | Required | Restrictions | Description |
|--------|--------|----------|--------------|-------------|
| `name` | string | false    |              |             |

## codersdk.UpdateWorkspaceSharingSettingsRequest

```json
{
  "shareable_workspace_owners": "none",
  "sharing_disabled": true
}
```

### Properties

| Name                         | Type                                                                   | Required | Restrictions | Description                                                                                                                     |
|------------------------------|------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------|
| `shareable_workspace_owners` | [codersdk.ShareableWorkspaceOwners](#codersdkshareableworkspaceowners) | false    |              | Shareable workspace owners controls whose workspaces can be shared within the organization.                                     |
| `sharing_disabled`           | boolean                                                                | false    |              | Sharing disabled is deprecated and left for backward compatibility purposes. Deprecated: use `ShareableWorkspaceOwners` instead |

#### Enumerated Values

| Property                     | Value(s)                               |
|------------------------------|----------------------------------------|
| `shareable_workspace_owners` | `everyone`, `none`, `service_accounts` |

## codersdk.UpdateWorkspaceTTLRequest

```json
{
  "ttl_ms": 0
}
```

### Properties

| Name     | Type    | Required | Restrictions | Description |
|----------|---------|----------|--------------|-------------|
| `ttl_ms` | integer | false    |              |             |

## codersdk.UploadChatFileResponse

```json
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}
```

### Properties

| Name | Type   | Required | Restrictions | Description |
|------|--------|----------|--------------|-------------|
| `id` | string | false    |              |             |

## codersdk.UploadResponse

```json
{
  "hash": "19686d84-b10d-4f90-b18e-84fd3fa038fd"
}
```

### Properties

| Name   | Type   | Required | Restrictions | Description |
|--------|--------|----------|--------------|-------------|
| `hash` | string | false    |              |             |

## codersdk.UpsertWorkspaceAgentPortShareRequest

```json
{
  "agent_name": "string",
  "port": 0,
  "protocol": "http",
  "share_level": "owner"
}
```

### Properties

| Name          | Type                                                                                 | Required | Restrictions | Description |
|---------------|--------------------------------------------------------------------------------------|----------|--------------|-------------|
| `agent_name`  | string                                                                               | false    |              |             |
| `port`        | integer                                                                              | false    |              |             |
| `protocol`    | [codersdk.WorkspaceAgentPortShareProtocol](#codersdkworkspaceagentportshareprotocol) | false    |              |             |
| `share_level` | [codersdk.WorkspaceAgentPortShareLevel](#codersdkworkspaceagentportsharelevel)       | false    |              |             |

#### Enumerated Values

| Property      | Value(s)                                           |
|---------------|----------------------------------------------------|
| `protocol`    | `http`, `https`                                    |
| `share_level` | `authenticated`, `organization`, `owner`, `public` |

## codersdk.UsageAppName

```json
"vscode"
```

### Properties

#### Enumerated Values

| Value(s)                                         |
|--------------------------------------------------|
| `jetbrains`, `reconnecting-pty`, `ssh`, `vscode` |

## codersdk.UsagePeriod

```json
{
  "end": "2019-08-24T14:15:22Z",
  "issued_at": "2019-08-24T14:15:22Z",
  "start": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name        | Type   | Required | Restrictions | Description |
|-------------|--------|----------|--------------|-------------|
| `end`       | string | false    |              |             |
| `issued_at` | string | false    |              |             |
| `start`     | string | false    |              |             |

## codersdk.UsageStatsConfig

```json
{
  "enable": true
}
```

### Properties

| Name     | Type    | Required | Restrictions | Description |
|----------|---------|----------|--------------|-------------|
| `enable` | boolean | false    |              |             |

## codersdk.User

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Properties

| Name                 | Type                                            | Required | Restrictions | Description                                                                                      |
|----------------------|-------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------|
| `avatar_url`         | string                                          | false    |              |                                                                                                  |
| `created_at`         | string                                          | true     |              |                                                                                                  |
| `email`              | string                                          | true     |              |                                                                                                  |
| `has_ai_seat`        | boolean                                         | false    |              | Has ai seat intentionally omits omitempty so the API always includes the field, even when false. |
| `id`                 | string                                          | true     |              |                                                                                                  |
| `is_service_account` | boolean                                         | false    |              |                                                                                                  |
| `last_seen_at`       | string                                          | false    |              |                                                                                                  |
| `login_type`         | [codersdk.LoginType](#codersdklogintype)        | false    |              |                                                                                                  |
| `name`               | string                                          | false    |              |                                                                                                  |
| `organization_ids`   | array of string                                 | false    |              |                                                                                                  |
| `roles`              | array of [codersdk.SlimRole](#codersdkslimrole) | false    |              |                                                                                                  |
| `status`             | [codersdk.UserStatus](#codersdkuserstatus)      | false    |              |                                                                                                  |
| `theme_preference`   | string                                          | false    |              | Deprecated: this value should be retrieved from `codersdk.UserPreferenceSettings` instead.       |
| `updated_at`         | string                                          | false    |              |                                                                                                  |
| `username`           | string                                          | true     |              |                                                                                                  |

#### Enumerated Values

| Property | Value(s)              |
|----------|-----------------------|
| `status` | `active`, `suspended` |

## codersdk.UserActivity

```json
{
  "avatar_url": "http://example.com",
  "seconds": 80500,
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
  "username": "string"
}
```

### Properties

| Name           | Type            | Required | Restrictions | Description |
|----------------|-----------------|----------|--------------|-------------|
| `avatar_url`   | string          | false    |              |             |
| `seconds`      | integer         | false    |              |             |
| `template_ids` | array of string | false    |              |             |
| `user_id`      | string          | false    |              |             |
| `username`     | string          | false    |              |             |

## codersdk.UserActivityInsightsReport

```json
{
  "end_time": "2019-08-24T14:15:22Z",
  "start_time": "2019-08-24T14:15:22Z",
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "users": [
    {
      "avatar_url": "http://example.com",
      "seconds": 80500,
      "template_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
      "username": "string"
    }
  ]
}
```

### Properties

| Name           | Type                                                    | Required | Restrictions | Description |
|----------------|---------------------------------------------------------|----------|--------------|-------------|
| `end_time`     | string                                                  | false    |              |             |
| `start_time`   | string                                                  | false    |              |             |
| `template_ids` | array of string                                         | false    |              |             |
| `users`        | array of [codersdk.UserActivity](#codersdkuseractivity) | false    |              |             |

## codersdk.UserActivityInsightsResponse

```json
{
  "report": {
    "end_time": "2019-08-24T14:15:22Z",
    "start_time": "2019-08-24T14:15:22Z",
    "template_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "users": [
      {
        "avatar_url": "http://example.com",
        "seconds": 80500,
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
        "username": "string"
      }
    ]
  }
}
```

### Properties

| Name     | Type                                                                       | Required | Restrictions | Description |
|----------|----------------------------------------------------------------------------|----------|--------------|-------------|
| `report` | [codersdk.UserActivityInsightsReport](#codersdkuseractivityinsightsreport) | false    |              |             |

## codersdk.UserAppearanceSettings

```json
{
  "terminal_font": "",
  "theme_preference": "string"
}
```

### Properties

| Name               | Type                                                   | Required | Restrictions | Description |
|--------------------|--------------------------------------------------------|----------|--------------|-------------|
| `terminal_font`    | [codersdk.TerminalFontName](#codersdkterminalfontname) | false    |              |             |
| `theme_preference` | string                                                 | false    |              |             |

## codersdk.UserLatency

```json
{
  "avatar_url": "http://example.com",
  "latency_ms": {
    "p50": 31.312,
    "p95": 119.832
  },
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
  "username": "string"
}
```

### Properties

| Name           | Type                                                     | Required | Restrictions | Description |
|----------------|----------------------------------------------------------|----------|--------------|-------------|
| `avatar_url`   | string                                                   | false    |              |             |
| `latency_ms`   | [codersdk.ConnectionLatency](#codersdkconnectionlatency) | false    |              |             |
| `template_ids` | array of string                                          | false    |              |             |
| `user_id`      | string                                                   | false    |              |             |
| `username`     | string                                                   | false    |              |             |

## codersdk.UserLatencyInsightsReport

```json
{
  "end_time": "2019-08-24T14:15:22Z",
  "start_time": "2019-08-24T14:15:22Z",
  "template_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "users": [
    {
      "avatar_url": "http://example.com",
      "latency_ms": {
        "p50": 31.312,
        "p95": 119.832
      },
      "template_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
      "username": "string"
    }
  ]
}
```

### Properties

| Name           | Type                                                  | Required | Restrictions | Description |
|----------------|-------------------------------------------------------|----------|--------------|-------------|
| `end_time`     | string                                                | false    |              |             |
| `start_time`   | string                                                | false    |              |             |
| `template_ids` | array of string                                       | false    |              |             |
| `users`        | array of [codersdk.UserLatency](#codersdkuserlatency) | false    |              |             |

## codersdk.UserLatencyInsightsResponse

```json
{
  "report": {
    "end_time": "2019-08-24T14:15:22Z",
    "start_time": "2019-08-24T14:15:22Z",
    "template_ids": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "users": [
      {
        "avatar_url": "http://example.com",
        "latency_ms": {
          "p50": 31.312,
          "p95": 119.832
        },
        "template_ids": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
        "username": "string"
      }
    ]
  }
}
```

### Properties

| Name     | Type                                                                     | Required | Restrictions | Description |
|----------|--------------------------------------------------------------------------|----------|--------------|-------------|
| `report` | [codersdk.UserLatencyInsightsReport](#codersdkuserlatencyinsightsreport) | false    |              |             |

## codersdk.UserLoginType

```json
{
  "login_type": ""
}
```

### Properties

| Name         | Type                                     | Required | Restrictions | Description |
|--------------|------------------------------------------|----------|--------------|-------------|
| `login_type` | [codersdk.LoginType](#codersdklogintype) | false    |              |             |

## codersdk.UserParameter

```json
{
  "name": "string",
  "value": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `name`  | string | false    |              |             |
| `value` | string | false    |              |             |

## codersdk.UserPreferenceSettings

```json
{
  "code_diff_display_mode": "auto",
  "task_notification_alert_dismissed": true,
  "thinking_display_mode": "auto"
}
```

### Properties

| Name                                | Type                                                         | Required | Restrictions | Description |
|-------------------------------------|--------------------------------------------------------------|----------|--------------|-------------|
| `code_diff_display_mode`            | [codersdk.AgentDisplayMode](#codersdkagentdisplaymode)       | false    |              |             |
| `task_notification_alert_dismissed` | boolean                                                      | false    |              |             |
| `thinking_display_mode`             | [codersdk.ThinkingDisplayMode](#codersdkthinkingdisplaymode) | false    |              |             |

## codersdk.UserQuietHoursScheduleConfig

```json
{
  "allow_user_custom": true,
  "default_schedule": "string"
}
```

### Properties

| Name                | Type    | Required | Restrictions | Description |
|---------------------|---------|----------|--------------|-------------|
| `allow_user_custom` | boolean | false    |              |             |
| `default_schedule`  | string  | false    |              |             |

## codersdk.UserQuietHoursScheduleResponse

```json
{
  "next": "2019-08-24T14:15:22Z",
  "raw_schedule": "string",
  "time": "string",
  "timezone": "string",
  "user_can_set": true,
  "user_set": true
}
```

### Properties

| Name           | Type    | Required | Restrictions | Description                                                                                                                                                                      |
|----------------|---------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `next`         | string  | false    |              | Next is the next time that the quiet hours window will start.                                                                                                                    |
| `raw_schedule` | string  | false    |              |                                                                                                                                                                                  |
| `time`         | string  | false    |              | Time is the time of day that the quiet hours window starts in the given Timezone each day.                                                                                       |
| `timezone`     | string  | false    |              | raw format from the cron expression, UTC if unspecified                                                                                                                          |
| `user_can_set` | boolean | false    |              | User can set is true if the user is allowed to set their own quiet hours schedule. If false, the user cannot set a custom schedule and the default schedule will always be used. |
| `user_set`     | boolean | false    |              | User set is true if the user has set their own quiet hours schedule. If false, the user is using the default schedule.                                                           |

## codersdk.UserSecret

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name          | Type   | Required | Restrictions | Description |
|---------------|--------|----------|--------------|-------------|
| `created_at`  | string | false    |              |             |
| `description` | string | false    |              |             |
| `env_name`    | string | false    |              |             |
| `file_path`   | string | false    |              |             |
| `id`          | string | false    |              |             |
| `name`        | string | false    |              |             |
| `updated_at`  | string | false    |              |             |

## codersdk.UserStatus

```json
"active"
```

### Properties

#### Enumerated Values

| Value(s)                         |
|----------------------------------|
| `active`, `dormant`, `suspended` |

## codersdk.UserStatusChangeCount

```json
{
  "count": 10,
  "date": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name    | Type    | Required | Restrictions | Description |
|---------|---------|----------|--------------|-------------|
| `count` | integer | false    |              |             |
| `date`  | string  | false    |              |             |

## codersdk.ValidateUserPasswordRequest

```json
{
  "password": "string"
}
```

### Properties

| Name       | Type   | Required | Restrictions | Description |
|------------|--------|----------|--------------|-------------|
| `password` | string | true     |              |             |

## codersdk.ValidateUserPasswordResponse

```json
{
  "details": "string",
  "valid": true
}
```

### Properties

| Name      | Type    | Required | Restrictions | Description |
|-----------|---------|----------|--------------|-------------|
| `details` | string  | false    |              |             |
| `valid`   | boolean | false    |              |             |

## codersdk.ValidationError

```json
{
  "detail": "string",
  "field": "string"
}
```

### Properties

| Name     | Type   | Required | Restrictions | Description |
|----------|--------|----------|--------------|-------------|
| `detail` | string | true     |              |             |
| `field`  | string | true     |              |             |

## codersdk.ValidationMonotonicOrder

```json
"increasing"
```

### Properties

#### Enumerated Values

| Value(s)                   |
|----------------------------|
| `decreasing`, `increasing` |

## codersdk.VariableValue

```json
{
  "name": "string",
  "value": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `name`  | string | false    |              |             |
| `value` | string | false    |              |             |

## codersdk.WebpushSubscription

```json
{
  "auth_key": "string",
  "endpoint": "string",
  "p256dh_key": "string"
}
```

### Properties

| Name         | Type   | Required | Restrictions | Description |
|--------------|--------|----------|--------------|-------------|
| `auth_key`   | string | false    |              |             |
| `endpoint`   | string | false    |              |             |
| `p256dh_key` | string | false    |              |             |

## codersdk.Workspace

```json
{
  "allow_renames": true,
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "deleting_at": "2019-08-24T14:15:22Z",
  "dormant_at": "2019-08-24T14:15:22Z",
  "favorite": true,
  "health": {
    "failing_agents": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "healthy": false
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_prebuild": true,
  "last_used_at": "2019-08-24T14:15:22Z",
  "latest_app_status": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "message": "string",
    "needs_user_attention": true,
    "state": "working",
    "uri": "string",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "latest_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  },
  "name": "string",
  "next_start_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "outdated": true,
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "shared_with": [
    {
      "actor_type": "group",
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "roles": [
        "admin"
      ]
    }
  ],
  "task_id": {
    "uuid": "string",
    "valid": true
  },
  "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
  "template_allow_user_cancel_workspace_jobs": true,
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "ttl_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Properties

| Name                                        | Type                                                                    | Required | Restrictions | Description                                                                                                                                                                                                                                                                                                                                 |
|---------------------------------------------|-------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `allow_renames`                             | boolean                                                                 | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `automatic_updates`                         | [codersdk.AutomaticUpdates](#codersdkautomaticupdates)                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `autostart_schedule`                        | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `created_at`                                | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `deleting_at`                               | string                                                                  | false    |              | Deleting at indicates the time at which the workspace will be permanently deleted. A workspace is eligible for deletion if it is dormant (a non-nil dormant_at value) and a value has been specified for time_til_dormant_autodelete on its template.                                                                                       |
| `dormant_at`                                | string                                                                  | false    |              | Dormant at being non-nil indicates a workspace that is dormant. A dormant workspace is no longer accessible must be activated. It is subject to deletion if it breaches the duration of the time_til_ field on its template.                                                                                                                |
| `favorite`                                  | boolean                                                                 | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `health`                                    | [codersdk.WorkspaceHealth](#codersdkworkspacehealth)                    | false    |              | Health shows the health of the workspace and information about what is causing an unhealthy status.                                                                                                                                                                                                                                         |
| `id`                                        | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `is_prebuild`                               | boolean                                                                 | false    |              | Is prebuild indicates whether the workspace is a prebuilt workspace. Prebuilt workspaces are owned by the prebuilds system user and have specific behavior, such as being managed differently from regular workspaces. Once a prebuilt workspace is claimed by a user, it transitions to a regular workspace, and IsPrebuild returns false. |
| `last_used_at`                              | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `latest_app_status`                         | [codersdk.WorkspaceAppStatus](#codersdkworkspaceappstatus)              | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `latest_build`                              | [codersdk.WorkspaceBuild](#codersdkworkspacebuild)                      | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `name`                                      | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `next_start_at`                             | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `organization_id`                           | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `organization_name`                         | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `outdated`                                  | boolean                                                                 | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `owner_avatar_url`                          | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `owner_id`                                  | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `owner_name`                                | string                                                                  | false    |              | Owner name is the username of the owner of the workspace.                                                                                                                                                                                                                                                                                   |
| `shared_with`                               | array of [codersdk.SharedWorkspaceActor](#codersdksharedworkspaceactor) | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `task_id`                                   | [uuid.NullUUID](#uuidnulluuid)                                          | false    |              | Task ID if set, indicates that the workspace is relevant to the given codersdk.Task.                                                                                                                                                                                                                                                        |
| `template_active_version_id`                | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `template_allow_user_cancel_workspace_jobs` | boolean                                                                 | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `template_display_name`                     | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `template_icon`                             | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `template_id`                               | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `template_name`                             | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `template_require_active_version`           | boolean                                                                 | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `template_use_classic_parameter_flow`       | boolean                                                                 | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `ttl_ms`                                    | integer                                                                 | false    |              |                                                                                                                                                                                                                                                                                                                                             |
| `updated_at`                                | string                                                                  | false    |              |                                                                                                                                                                                                                                                                                                                                             |

#### Enumerated Values

| Property            | Value(s)          |
|---------------------|-------------------|
| `automatic_updates` | `always`, `never` |

## codersdk.WorkspaceACL

```json
{
  "group": [
    {
      "avatar_url": "http://example.com",
      "display_name": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "members": [
        {
          "avatar_url": "http://example.com",
          "created_at": "2019-08-24T14:15:22Z",
          "email": "user@example.com",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "is_service_account": true,
          "last_seen_at": "2019-08-24T14:15:22Z",
          "login_type": "",
          "name": "string",
          "status": "active",
          "theme_preference": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "username": "string"
        }
      ],
      "name": "string",
      "organization_display_name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "organization_name": "string",
      "quota_allowance": 0,
      "role": "admin",
      "source": "user",
      "total_member_count": 0
    }
  ],
  "users": [
    {
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "role": "admin",
      "username": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                                        | Required | Restrictions | Description |
|---------|-------------------------------------------------------------|----------|--------------|-------------|
| `group` | array of [codersdk.WorkspaceGroup](#codersdkworkspacegroup) | false    |              |             |
| `users` | array of [codersdk.WorkspaceUser](#codersdkworkspaceuser)   | false    |              |             |

## codersdk.WorkspaceAgent

```json
{
  "api_version": "string",
  "apps": [
    {
      "command": "string",
      "display_name": "string",
      "external": true,
      "group": "string",
      "health": "disabled",
      "healthcheck": {
        "interval": 0,
        "threshold": 0,
        "url": "string"
      },
      "hidden": true,
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "open_in": "slim-window",
      "sharing_level": "owner",
      "slug": "string",
      "statuses": [
        {
          "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
          "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
          "created_at": "2019-08-24T14:15:22Z",
          "icon": "string",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "message": "string",
          "needs_user_attention": true,
          "state": "working",
          "uri": "string",
          "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
        }
      ],
      "subdomain": true,
      "subdomain_name": "string",
      "tooltip": "string",
      "url": "string"
    }
  ],
  "architecture": "string",
  "connection_timeout_seconds": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "directory": "string",
  "disconnected_at": "2019-08-24T14:15:22Z",
  "display_apps": [
    "vscode"
  ],
  "environment_variables": {
    "property1": "string",
    "property2": "string"
  },
  "expanded_directory": "string",
  "first_connected_at": "2019-08-24T14:15:22Z",
  "health": {
    "healthy": false,
    "reason": "agent has lost connection"
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "instance_id": "string",
  "last_connected_at": "2019-08-24T14:15:22Z",
  "latency": {
    "property1": {
      "latency_ms": 0,
      "preferred": true
    },
    "property2": {
      "latency_ms": 0,
      "preferred": true
    }
  },
  "lifecycle_state": "created",
  "log_sources": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "display_name": "string",
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
    }
  ],
  "logs_length": 0,
  "logs_overflowed": true,
  "name": "string",
  "operating_system": "string",
  "parent_id": {
    "uuid": "string",
    "valid": true
  },
  "ready_at": "2019-08-24T14:15:22Z",
  "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  "scripts": [
    {
      "cron": "string",
      "display_name": "string",
      "exit_code": 0,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "log_path": "string",
      "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
      "run_on_start": true,
      "run_on_stop": true,
      "script": "string",
      "start_blocks_login": true,
      "status": "ok",
      "timeout": 0
    }
  ],
  "started_at": "2019-08-24T14:15:22Z",
  "startup_script_behavior": "blocking",
  "status": "connecting",
  "subsystems": [
    "envbox"
  ],
  "troubleshooting_url": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "version": "string"
}
```

### Properties

| Name                         | Type                                                                                         | Required | Restrictions | Description                                                                                                                                                                  |
|------------------------------|----------------------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `api_version`                | string                                                                                       | false    |              |                                                                                                                                                                              |
| `apps`                       | array of [codersdk.WorkspaceApp](#codersdkworkspaceapp)                                      | false    |              |                                                                                                                                                                              |
| `architecture`               | string                                                                                       | false    |              |                                                                                                                                                                              |
| `connection_timeout_seconds` | integer                                                                                      | false    |              |                                                                                                                                                                              |
| `created_at`                 | string                                                                                       | false    |              |                                                                                                                                                                              |
| `directory`                  | string                                                                                       | false    |              |                                                                                                                                                                              |
| `disconnected_at`            | string                                                                                       | false    |              |                                                                                                                                                                              |
| `display_apps`               | array of [codersdk.DisplayApp](#codersdkdisplayapp)                                          | false    |              |                                                                                                                                                                              |
| `environment_variables`      | object                                                                                       | false    |              |                                                                                                                                                                              |
| » `[any property]`           | string                                                                                       | false    |              |                                                                                                                                                                              |
| `expanded_directory`         | string                                                                                       | false    |              |                                                                                                                                                                              |
| `first_connected_at`         | string                                                                                       | false    |              |                                                                                                                                                                              |
| `health`                     | [codersdk.WorkspaceAgentHealth](#codersdkworkspaceagenthealth)                               | false    |              | Health reports the health of the agent.                                                                                                                                      |
| `id`                         | string                                                                                       | false    |              |                                                                                                                                                                              |
| `instance_id`                | string                                                                                       | false    |              |                                                                                                                                                                              |
| `last_connected_at`          | string                                                                                       | false    |              |                                                                                                                                                                              |
| `latency`                    | object                                                                                       | false    |              | Latency is mapped by region name (e.g. "New York City", "Seattle").                                                                                                          |
| » `[any property]`           | [codersdk.DERPRegion](#codersdkderpregion)                                                   | false    |              |                                                                                                                                                                              |
| `lifecycle_state`            | [codersdk.WorkspaceAgentLifecycle](#codersdkworkspaceagentlifecycle)                         | false    |              |                                                                                                                                                                              |
| `log_sources`                | array of [codersdk.WorkspaceAgentLogSource](#codersdkworkspaceagentlogsource)                | false    |              |                                                                                                                                                                              |
| `logs_length`                | integer                                                                                      | false    |              |                                                                                                                                                                              |
| `logs_overflowed`            | boolean                                                                                      | false    |              |                                                                                                                                                                              |
| `name`                       | string                                                                                       | false    |              |                                                                                                                                                                              |
| `operating_system`           | string                                                                                       | false    |              |                                                                                                                                                                              |
| `parent_id`                  | [uuid.NullUUID](#uuidnulluuid)                                                               | false    |              |                                                                                                                                                                              |
| `ready_at`                   | string                                                                                       | false    |              |                                                                                                                                                                              |
| `resource_id`                | string                                                                                       | false    |              |                                                                                                                                                                              |
| `scripts`                    | array of [codersdk.WorkspaceAgentScript](#codersdkworkspaceagentscript)                      | false    |              |                                                                                                                                                                              |
| `started_at`                 | string                                                                                       | false    |              |                                                                                                                                                                              |
| `startup_script_behavior`    | [codersdk.WorkspaceAgentStartupScriptBehavior](#codersdkworkspaceagentstartupscriptbehavior) | false    |              | Startup script behavior is a legacy field that is deprecated in favor of the `coder_script` resource. It's only referenced by old clients. Deprecated: Remove in the future! |
| `status`                     | [codersdk.WorkspaceAgentStatus](#codersdkworkspaceagentstatus)                               | false    |              |                                                                                                                                                                              |
| `subsystems`                 | array of [codersdk.AgentSubsystem](#codersdkagentsubsystem)                                  | false    |              |                                                                                                                                                                              |
| `troubleshooting_url`        | string                                                                                       | false    |              |                                                                                                                                                                              |
| `updated_at`                 | string                                                                                       | false    |              |                                                                                                                                                                              |
| `version`                    | string                                                                                       | false    |              |                                                                                                                                                                              |

## codersdk.WorkspaceAgentContainer

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": "string",
  "image": "string",
  "labels": {
    "property1": "string",
    "property2": "string"
  },
  "name": "string",
  "ports": [
    {
      "host_ip": "string",
      "host_port": 0,
      "network": "string",
      "port": 0
    }
  ],
  "running": true,
  "status": "string",
  "volumes": {
    "property1": "string",
    "property2": "string"
  }
}
```

### Properties

| Name               | Type                                                                                  | Required | Restrictions | Description                                                                                                                                |
|--------------------|---------------------------------------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `created_at`       | string                                                                                | false    |              | Created at is the time the container was created.                                                                                          |
| `id`               | string                                                                                | false    |              | ID is the unique identifier of the container.                                                                                              |
| `image`            | string                                                                                | false    |              | Image is the name of the container image.                                                                                                  |
| `labels`           | object                                                                                | false    |              | Labels is a map of key-value pairs of container labels.                                                                                    |
| » `[any property]` | string                                                                                | false    |              |                                                                                                                                            |
| `name`             | string                                                                                | false    |              | Name is the human-readable name of the container.                                                                                          |
| `ports`            | array of [codersdk.WorkspaceAgentContainerPort](#codersdkworkspaceagentcontainerport) | false    |              | Ports includes ports exposed by the container.                                                                                             |
| `running`          | boolean                                                                               | false    |              | Running is true if the container is currently running.                                                                                     |
| `status`           | string                                                                                | false    |              | Status is the current status of the container. This is somewhat implementation-dependent, but should generally be a human-readable string. |
| `volumes`          | object                                                                                | false    |              | Volumes is a map of "things" mounted into the container. Again, this is somewhat implementation-dependent.                                 |
| » `[any property]` | string                                                                                | false    |              |                                                                                                                                            |

## codersdk.WorkspaceAgentContainerPort

```json
{
  "host_ip": "string",
  "host_port": 0,
  "network": "string",
  "port": 0
}
```

### Properties

| Name        | Type    | Required | Restrictions | Description                                                                                                                |
|-------------|---------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------|
| `host_ip`   | string  | false    |              | Host ip is the IP address of the host interface to which the port is bound. Note that this can be an IPv4 or IPv6 address. |
| `host_port` | integer | false    |              | Host port is the port number *outside* the container.                                                                      |
| `network`   | string  | false    |              | Network is the network protocol used by the port (tcp, udp, etc).                                                          |
| `port`      | integer | false    |              | Port is the port number *inside* the container.                                                                            |

## codersdk.WorkspaceAgentDevcontainer

```json
{
  "agent": {
    "directory": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string"
  },
  "config_path": "string",
  "container": {
    "created_at": "2019-08-24T14:15:22Z",
    "id": "string",
    "image": "string",
    "labels": {
      "property1": "string",
      "property2": "string"
    },
    "name": "string",
    "ports": [
      {
        "host_ip": "string",
        "host_port": 0,
        "network": "string",
        "port": 0
      }
    ],
    "running": true,
    "status": "string",
    "volumes": {
      "property1": "string",
      "property2": "string"
    }
  },
  "dirty": true,
  "error": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "status": "running",
  "subagent_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_folder": "string"
}
```

### Properties

| Name               | Type                                                                                   | Required | Restrictions | Description                |
|--------------------|----------------------------------------------------------------------------------------|----------|--------------|----------------------------|
| `agent`            | [codersdk.WorkspaceAgentDevcontainerAgent](#codersdkworkspaceagentdevcontaineragent)   | false    |              |                            |
| `config_path`      | string                                                                                 | false    |              |                            |
| `container`        | [codersdk.WorkspaceAgentContainer](#codersdkworkspaceagentcontainer)                   | false    |              |                            |
| `dirty`            | boolean                                                                                | false    |              |                            |
| `error`            | string                                                                                 | false    |              |                            |
| `id`               | string                                                                                 | false    |              |                            |
| `name`             | string                                                                                 | false    |              |                            |
| `status`           | [codersdk.WorkspaceAgentDevcontainerStatus](#codersdkworkspaceagentdevcontainerstatus) | false    |              | Additional runtime fields. |
| `subagent_id`      | [uuid.NullUUID](#uuidnulluuid)                                                         | false    |              |                            |
| `workspace_folder` | string                                                                                 | false    |              |                            |

## codersdk.WorkspaceAgentDevcontainerAgent

```json
{
  "directory": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string"
}
```

### Properties

| Name        | Type   | Required | Restrictions | Description |
|-------------|--------|----------|--------------|-------------|
| `directory` | string | false    |              |             |
| `id`        | string | false    |              |             |
| `name`      | string | false    |              |             |

## codersdk.WorkspaceAgentDevcontainerStatus

```json
"running"
```

### Properties

#### Enumerated Values

| Value(s)                                                          |
|-------------------------------------------------------------------|
| `deleting`, `error`, `running`, `starting`, `stopped`, `stopping` |

## codersdk.WorkspaceAgentGitServerMessage

```json
{
  "message": "string",
  "repositories": [
    {
      "branch": "string",
      "remote_origin": "string",
      "removed": true,
      "repo_root": "string",
      "unified_diff": "string"
    }
  ],
  "scanned_at": "2019-08-24T14:15:22Z",
  "type": "changes"
}
```

### Properties

| Name           | Type                                                                                       | Required | Restrictions | Description |
|----------------|--------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `message`      | string                                                                                     | false    |              |             |
| `repositories` | array of [codersdk.WorkspaceAgentRepoChanges](#codersdkworkspaceagentrepochanges)          | false    |              |             |
| `scanned_at`   | string                                                                                     | false    |              |             |
| `type`         | [codersdk.WorkspaceAgentGitServerMessageType](#codersdkworkspaceagentgitservermessagetype) | false    |              |             |

## codersdk.WorkspaceAgentGitServerMessageType

```json
"changes"
```

### Properties

#### Enumerated Values

| Value(s)           |
|--------------------|
| `changes`, `error` |

## codersdk.WorkspaceAgentHealth

```json
{
  "healthy": false,
  "reason": "agent has lost connection"
}
```

### Properties

| Name      | Type    | Required | Restrictions | Description                                                                                   |
|-----------|---------|----------|--------------|-----------------------------------------------------------------------------------------------|
| `healthy` | boolean | false    |              | Healthy is true if the agent is healthy.                                                      |
| `reason`  | string  | false    |              | Reason is a human-readable explanation of the agent's health. It is empty if Healthy is true. |

## codersdk.WorkspaceAgentLifecycle

```json
"created"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                     |
|------------------------------------------------------------------------------------------------------------------------------|
| `created`, `off`, `ready`, `shutdown_error`, `shutdown_timeout`, `shutting_down`, `start_error`, `start_timeout`, `starting` |

## codersdk.WorkspaceAgentListContainersResponse

```json
{
  "containers": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "id": "string",
      "image": "string",
      "labels": {
        "property1": "string",
        "property2": "string"
      },
      "name": "string",
      "ports": [
        {
          "host_ip": "string",
          "host_port": 0,
          "network": "string",
          "port": 0
        }
      ],
      "running": true,
      "status": "string",
      "volumes": {
        "property1": "string",
        "property2": "string"
      }
    }
  ],
  "devcontainers": [
    {
      "agent": {
        "directory": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string"
      },
      "config_path": "string",
      "container": {
        "created_at": "2019-08-24T14:15:22Z",
        "id": "string",
        "image": "string",
        "labels": {
          "property1": "string",
          "property2": "string"
        },
        "name": "string",
        "ports": [
          {
            "host_ip": "string",
            "host_port": 0,
            "network": "string",
            "port": 0
          }
        ],
        "running": true,
        "status": "string",
        "volumes": {
          "property1": "string",
          "property2": "string"
        }
      },
      "dirty": true,
      "error": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "status": "running",
      "subagent_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_folder": "string"
    }
  ],
  "warnings": [
    "string"
  ]
}
```

### Properties

| Name            | Type                                                                                | Required | Restrictions | Description                                                                                                                           |
|-----------------|-------------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------|
| `containers`    | array of [codersdk.WorkspaceAgentContainer](#codersdkworkspaceagentcontainer)       | false    |              | Containers is a list of containers visible to the workspace agent.                                                                    |
| `devcontainers` | array of [codersdk.WorkspaceAgentDevcontainer](#codersdkworkspaceagentdevcontainer) | false    |              | Devcontainers is a list of devcontainers visible to the workspace agent.                                                              |
| `warnings`      | array of string                                                                     | false    |              | Warnings is a list of warnings that may have occurred during the process of listing containers. This should not include fatal errors. |

## codersdk.WorkspaceAgentListeningPort

```json
{
  "network": "string",
  "port": 0,
  "process_name": "string"
}
```

### Properties

| Name           | Type    | Required | Restrictions | Description              |
|----------------|---------|----------|--------------|--------------------------|
| `network`      | string  | false    |              | only "tcp" at the moment |
| `port`         | integer | false    |              |                          |
| `process_name` | string  | false    |              | may be empty             |

## codersdk.WorkspaceAgentListeningPortsResponse

```json
{
  "ports": [
    {
      "network": "string",
      "port": 0,
      "process_name": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                                                                  | Required | Restrictions | Description                                                                                                                                                                                                                                            |
|---------|---------------------------------------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ports` | array of [codersdk.WorkspaceAgentListeningPort](#codersdkworkspaceagentlisteningport) | false    |              | If there are no ports in the list, nothing should be displayed in the UI. There must not be a "no ports available" message or anything similar, as there will always be no ports displayed on platforms where our port detection logic is unsupported. |

## codersdk.WorkspaceAgentLog

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "id": 0,
  "level": "trace",
  "output": "string",
  "source_id": "ae50a35c-df42-4eff-ba26-f8bc28d2af81"
}
```

### Properties

| Name         | Type                                   | Required | Restrictions | Description |
|--------------|----------------------------------------|----------|--------------|-------------|
| `created_at` | string                                 | false    |              |             |
| `id`         | integer                                | false    |              |             |
| `level`      | [codersdk.LogLevel](#codersdkloglevel) | false    |              |             |
| `output`     | string                                 | false    |              |             |
| `source_id`  | string                                 | false    |              |             |

## codersdk.WorkspaceAgentLogSource

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
}
```

### Properties

| Name                 | Type   | Required | Restrictions | Description |
|----------------------|--------|----------|--------------|-------------|
| `created_at`         | string | false    |              |             |
| `display_name`       | string | false    |              |             |
| `icon`               | string | false    |              |             |
| `id`                 | string | false    |              |             |
| `workspace_agent_id` | string | false    |              |             |

## codersdk.WorkspaceAgentPortShare

```json
{
  "agent_name": "string",
  "port": 0,
  "protocol": "http",
  "share_level": "owner",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Properties

| Name           | Type                                                                                 | Required | Restrictions | Description |
|----------------|--------------------------------------------------------------------------------------|----------|--------------|-------------|
| `agent_name`   | string                                                                               | false    |              |             |
| `port`         | integer                                                                              | false    |              |             |
| `protocol`     | [codersdk.WorkspaceAgentPortShareProtocol](#codersdkworkspaceagentportshareprotocol) | false    |              |             |
| `share_level`  | [codersdk.WorkspaceAgentPortShareLevel](#codersdkworkspaceagentportsharelevel)       | false    |              |             |
| `workspace_id` | string                                                                               | false    |              |             |

#### Enumerated Values

| Property      | Value(s)                                           |
|---------------|----------------------------------------------------|
| `protocol`    | `http`, `https`                                    |
| `share_level` | `authenticated`, `organization`, `owner`, `public` |

## codersdk.WorkspaceAgentPortShareLevel

```json
"owner"
```

### Properties

#### Enumerated Values

| Value(s)                                           |
|----------------------------------------------------|
| `authenticated`, `organization`, `owner`, `public` |

## codersdk.WorkspaceAgentPortShareProtocol

```json
"http"
```

### Properties

#### Enumerated Values

| Value(s)        |
|-----------------|
| `http`, `https` |

## codersdk.WorkspaceAgentPortShares

```json
{
  "shares": [
    {
      "agent_name": "string",
      "port": 0,
      "protocol": "http",
      "share_level": "owner",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ]
}
```

### Properties

| Name     | Type                                                                          | Required | Restrictions | Description |
|----------|-------------------------------------------------------------------------------|----------|--------------|-------------|
| `shares` | array of [codersdk.WorkspaceAgentPortShare](#codersdkworkspaceagentportshare) | false    |              |             |

## codersdk.WorkspaceAgentRepoChanges

```json
{
  "branch": "string",
  "remote_origin": "string",
  "removed": true,
  "repo_root": "string",
  "unified_diff": "string"
}
```

### Properties

| Name            | Type    | Required | Restrictions | Description |
|-----------------|---------|----------|--------------|-------------|
| `branch`        | string  | false    |              |             |
| `remote_origin` | string  | false    |              |             |
| `removed`       | boolean | false    |              |             |
| `repo_root`     | string  | false    |              |             |
| `unified_diff`  | string  | false    |              |             |

## codersdk.WorkspaceAgentScript

```json
{
  "cron": "string",
  "display_name": "string",
  "exit_code": 0,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "log_path": "string",
  "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
  "run_on_start": true,
  "run_on_stop": true,
  "script": "string",
  "start_blocks_login": true,
  "status": "ok",
  "timeout": 0
}
```

### Properties

| Name                 | Type                                                                       | Required | Restrictions | Description |
|----------------------|----------------------------------------------------------------------------|----------|--------------|-------------|
| `cron`               | string                                                                     | false    |              |             |
| `display_name`       | string                                                                     | false    |              |             |
| `exit_code`          | integer                                                                    | false    |              |             |
| `id`                 | string                                                                     | false    |              |             |
| `log_path`           | string                                                                     | false    |              |             |
| `log_source_id`      | string                                                                     | false    |              |             |
| `run_on_start`       | boolean                                                                    | false    |              |             |
| `run_on_stop`        | boolean                                                                    | false    |              |             |
| `script`             | string                                                                     | false    |              |             |
| `start_blocks_login` | boolean                                                                    | false    |              |             |
| `status`             | [codersdk.WorkspaceAgentScriptStatus](#codersdkworkspaceagentscriptstatus) | false    |              |             |
| `timeout`            | integer                                                                    | false    |              |             |

## codersdk.WorkspaceAgentScriptStatus

```json
"ok"
```

### Properties

#### Enumerated Values

| Value(s)                                             |
|------------------------------------------------------|
| `exit_failure`, `ok`, `pipes_left_open`, `timed_out` |

## codersdk.WorkspaceAgentStartupScriptBehavior

```json
"blocking"
```

### Properties

#### Enumerated Values

| Value(s)                   |
|----------------------------|
| `blocking`, `non-blocking` |

## codersdk.WorkspaceAgentStatus

```json
"connecting"
```

### Properties

#### Enumerated Values

| Value(s)                                             |
|------------------------------------------------------|
| `connected`, `connecting`, `disconnected`, `timeout` |

## codersdk.WorkspaceApp

```json
{
  "command": "string",
  "display_name": "string",
  "external": true,
  "group": "string",
  "health": "disabled",
  "healthcheck": {
    "interval": 0,
    "threshold": 0,
    "url": "string"
  },
  "hidden": true,
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "open_in": "slim-window",
  "sharing_level": "owner",
  "slug": "string",
  "statuses": [
    {
      "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
      "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
      "created_at": "2019-08-24T14:15:22Z",
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "message": "string",
      "needs_user_attention": true,
      "state": "working",
      "uri": "string",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
    }
  ],
  "subdomain": true,
  "subdomain_name": "string",
  "tooltip": "string",
  "url": "string"
}
```

### Properties

| Name             | Type                                                                   | Required | Restrictions | Description                                                                                                                                                                                                                                    |
|------------------|------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `command`        | string                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `display_name`   | string                                                                 | false    |              | Display name is a friendly name for the app.                                                                                                                                                                                                   |
| `external`       | boolean                                                                | false    |              | External specifies whether the URL should be opened externally on the client or not.                                                                                                                                                           |
| `group`          | string                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `health`         | [codersdk.WorkspaceAppHealth](#codersdkworkspaceapphealth)             | false    |              |                                                                                                                                                                                                                                                |
| `healthcheck`    | [codersdk.Healthcheck](#codersdkhealthcheck)                           | false    |              | Healthcheck specifies the configuration for checking app health.                                                                                                                                                                               |
| `hidden`         | boolean                                                                | false    |              |                                                                                                                                                                                                                                                |
| `icon`           | string                                                                 | false    |              | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard.                                                                                                                                               |
| `id`             | string                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `open_in`        | [codersdk.WorkspaceAppOpenIn](#codersdkworkspaceappopenin)             | false    |              |                                                                                                                                                                                                                                                |
| `sharing_level`  | [codersdk.WorkspaceAppSharingLevel](#codersdkworkspaceappsharinglevel) | false    |              |                                                                                                                                                                                                                                                |
| `slug`           | string                                                                 | false    |              | Slug is a unique identifier within the agent.                                                                                                                                                                                                  |
| `statuses`       | array of [codersdk.WorkspaceAppStatus](#codersdkworkspaceappstatus)    | false    |              | Statuses is a list of statuses for the app.                                                                                                                                                                                                    |
| `subdomain`      | boolean                                                                | false    |              | Subdomain denotes whether the app should be accessed via a path on the `coder server` or via a hostname-based dev URL. If this is set to true and there is no app wildcard configured on the server, the app will not be accessible in the UI. |
| `subdomain_name` | string                                                                 | false    |              | Subdomain name is the application domain exposed on the `coder server`.                                                                                                                                                                        |
| `tooltip`        | string                                                                 | false    |              | Tooltip is an optional markdown supported field that is displayed when hovering over workspace apps in the UI.                                                                                                                                 |
| `url`            | string                                                                 | false    |              | URL is the address being proxied to inside the workspace. If external is specified, this will be opened on the client.                                                                                                                         |

#### Enumerated Values

| Property        | Value(s)                                           |
|-----------------|----------------------------------------------------|
| `sharing_level` | `authenticated`, `organization`, `owner`, `public` |

## codersdk.WorkspaceAppHealth

```json
"disabled"
```

### Properties

#### Enumerated Values

| Value(s)                                           |
|----------------------------------------------------|
| `disabled`, `healthy`, `initializing`, `unhealthy` |

## codersdk.WorkspaceAppOpenIn

```json
"slim-window"
```

### Properties

#### Enumerated Values

| Value(s)             |
|----------------------|
| `slim-window`, `tab` |

## codersdk.WorkspaceAppSharingLevel

```json
"owner"
```

### Properties

#### Enumerated Values

| Value(s)                                           |
|----------------------------------------------------|
| `authenticated`, `organization`, `owner`, `public` |

## codersdk.WorkspaceAppStatus

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
  "created_at": "2019-08-24T14:15:22Z",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "message": "string",
  "needs_user_attention": true,
  "state": "working",
  "uri": "string",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
}
```

### Properties

| Name                   | Type                                                                 | Required | Restrictions | Description                                                                                                                                     |
|------------------------|----------------------------------------------------------------------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| `agent_id`             | string                                                               | false    |              |                                                                                                                                                 |
| `app_id`               | string                                                               | false    |              |                                                                                                                                                 |
| `created_at`           | string                                                               | false    |              |                                                                                                                                                 |
| `icon`                 | string                                                               | false    |              | Deprecated: This field is unused and will be removed in a future version. Icon is an external URL to an icon that will be rendered in the UI.   |
| `id`                   | string                                                               | false    |              |                                                                                                                                                 |
| `message`              | string                                                               | false    |              |                                                                                                                                                 |
| `needs_user_attention` | boolean                                                              | false    |              | Deprecated: This field is unused and will be removed in a future version. NeedsUserAttention specifies whether the status needs user attention. |
| `state`                | [codersdk.WorkspaceAppStatusState](#codersdkworkspaceappstatusstate) | false    |              |                                                                                                                                                 |
| `uri`                  | string                                                               | false    |              | Uri is the URI of the resource that the status is for. e.g. https://github.com/org/repo/pull/123 e.g. file:///path/to/file                      |
| `workspace_id`         | string                                                               | false    |              |                                                                                                                                                 |

## codersdk.WorkspaceAppStatusState

```json
"working"
```

### Properties

#### Enumerated Values

| Value(s)                                 |
|------------------------------------------|
| `complete`, `failure`, `idle`, `working` |

## codersdk.WorkspaceBuild

```json
{
  "build_number": 0,
  "created_at": "2019-08-24T14:15:22Z",
  "daily_cost": 0,
  "deadline": "2019-08-24T14:15:22Z",
  "has_ai_task": true,
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "initiator_name": "string",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "max_deadline": "2019-08-24T14:15:22Z",
  "reason": "initiator",
  "resources": [
    {
      "agents": [
        {
          "api_version": "string",
          "apps": [
            {
              "command": "string",
              "display_name": "string",
              "external": true,
              "group": "string",
              "health": "disabled",
              "healthcheck": {
                "interval": 0,
                "threshold": 0,
                "url": "string"
              },
              "hidden": true,
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "open_in": "slim-window",
              "sharing_level": "owner",
              "slug": "string",
              "statuses": [
                {
                  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                  "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                  "created_at": "2019-08-24T14:15:22Z",
                  "icon": "string",
                  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                  "message": "string",
                  "needs_user_attention": true,
                  "state": "working",
                  "uri": "string",
                  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                }
              ],
              "subdomain": true,
              "subdomain_name": "string",
              "tooltip": "string",
              "url": "string"
            }
          ],
          "architecture": "string",
          "connection_timeout_seconds": 0,
          "created_at": "2019-08-24T14:15:22Z",
          "directory": "string",
          "disconnected_at": "2019-08-24T14:15:22Z",
          "display_apps": [
            "vscode"
          ],
          "environment_variables": {
            "property1": "string",
            "property2": "string"
          },
          "expanded_directory": "string",
          "first_connected_at": "2019-08-24T14:15:22Z",
          "health": {
            "healthy": false,
            "reason": "agent has lost connection"
          },
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "instance_id": "string",
          "last_connected_at": "2019-08-24T14:15:22Z",
          "latency": {
            "property1": {
              "latency_ms": 0,
              "preferred": true
            },
            "property2": {
              "latency_ms": 0,
              "preferred": true
            }
          },
          "lifecycle_state": "created",
          "log_sources": [
            {
              "created_at": "2019-08-24T14:15:22Z",
              "display_name": "string",
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
            }
          ],
          "logs_length": 0,
          "logs_overflowed": true,
          "name": "string",
          "operating_system": "string",
          "parent_id": {
            "uuid": "string",
            "valid": true
          },
          "ready_at": "2019-08-24T14:15:22Z",
          "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
          "scripts": [
            {
              "cron": "string",
              "display_name": "string",
              "exit_code": 0,
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "log_path": "string",
              "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
              "run_on_start": true,
              "run_on_stop": true,
              "script": "string",
              "start_blocks_login": true,
              "status": "ok",
              "timeout": 0
            }
          ],
          "started_at": "2019-08-24T14:15:22Z",
          "startup_script_behavior": "blocking",
          "status": "connecting",
          "subsystems": [
            "envbox"
          ],
          "troubleshooting_url": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "version": "string"
        }
      ],
      "created_at": "2019-08-24T14:15:22Z",
      "daily_cost": 0,
      "hide": true,
      "icon": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "metadata": [
        {
          "key": "string",
          "sensitive": true,
          "value": "string"
        }
      ],
      "name": "string",
      "type": "string",
      "workspace_transition": "start"
    }
  ],
  "status": "pending",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_name": "string",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "transition": "start",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
  "workspace_name": "string",
  "workspace_owner_avatar_url": "string",
  "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
  "workspace_owner_name": "string"
}
```

### Properties

| Name                         | Type                                                              | Required | Restrictions | Description                                                              |
|------------------------------|-------------------------------------------------------------------|----------|--------------|--------------------------------------------------------------------------|
| `build_number`               | integer                                                           | false    |              |                                                                          |
| `created_at`                 | string                                                            | false    |              |                                                                          |
| `daily_cost`                 | integer                                                           | false    |              |                                                                          |
| `deadline`                   | string                                                            | false    |              |                                                                          |
| `has_ai_task`                | boolean                                                           | false    |              | Deprecated: This field has been deprecated in favor of Task WorkspaceID. |
| `has_external_agent`         | boolean                                                           | false    |              |                                                                          |
| `id`                         | string                                                            | false    |              |                                                                          |
| `initiator_id`               | string                                                            | false    |              |                                                                          |
| `initiator_name`             | string                                                            | false    |              |                                                                          |
| `job`                        | [codersdk.ProvisionerJob](#codersdkprovisionerjob)                | false    |              |                                                                          |
| `matched_provisioners`       | [codersdk.MatchedProvisioners](#codersdkmatchedprovisioners)      | false    |              |                                                                          |
| `max_deadline`               | string                                                            | false    |              |                                                                          |
| `reason`                     | [codersdk.BuildReason](#codersdkbuildreason)                      | false    |              |                                                                          |
| `resources`                  | array of [codersdk.WorkspaceResource](#codersdkworkspaceresource) | false    |              |                                                                          |
| `status`                     | [codersdk.WorkspaceStatus](#codersdkworkspacestatus)              | false    |              |                                                                          |
| `template_version_id`        | string                                                            | false    |              |                                                                          |
| `template_version_name`      | string                                                            | false    |              |                                                                          |
| `template_version_preset_id` | string                                                            | false    |              |                                                                          |
| `transition`                 | [codersdk.WorkspaceTransition](#codersdkworkspacetransition)      | false    |              |                                                                          |
| `updated_at`                 | string                                                            | false    |              |                                                                          |
| `workspace_id`               | string                                                            | false    |              |                                                                          |
| `workspace_name`             | string                                                            | false    |              |                                                                          |
| `workspace_owner_avatar_url` | string                                                            | false    |              |                                                                          |
| `workspace_owner_id`         | string                                                            | false    |              |                                                                          |
| `workspace_owner_name`       | string                                                            | false    |              | Workspace owner name is the username of the owner of the workspace.      |

#### Enumerated Values

| Property     | Value(s)                                                                                                          |
|--------------|-------------------------------------------------------------------------------------------------------------------|
| `reason`     | `autostart`, `autostop`, `initiator`                                                                              |
| `status`     | `canceled`, `canceling`, `deleted`, `deleting`, `failed`, `pending`, `running`, `starting`, `stopped`, `stopping` |
| `transition` | `delete`, `start`, `stop`                                                                                         |

## codersdk.WorkspaceBuildParameter

```json
{
  "name": "string",
  "value": "string"
}
```

### Properties

| Name    | Type   | Required | Restrictions | Description |
|---------|--------|----------|--------------|-------------|
| `name`  | string | false    |              |             |
| `value` | string | false    |              |             |

## codersdk.WorkspaceBuildTimings

```json
{
  "agent_connection_timings": [
    {
      "ended_at": "2019-08-24T14:15:22Z",
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z",
      "workspace_agent_id": "string",
      "workspace_agent_name": "string"
    }
  ],
  "agent_script_timings": [
    {
      "display_name": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "exit_code": 0,
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z",
      "status": "string",
      "workspace_agent_id": "string",
      "workspace_agent_name": "string"
    }
  ],
  "provisioner_timings": [
    {
      "action": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "resource": "string",
      "source": "string",
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z"
    }
  ]
}
```

### Properties

| Name                       | Type                                                                      | Required | Restrictions | Description                                                                                                      |
|----------------------------|---------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------|
| `agent_connection_timings` | array of [codersdk.AgentConnectionTiming](#codersdkagentconnectiontiming) | false    |              |                                                                                                                  |
| `agent_script_timings`     | array of [codersdk.AgentScriptTiming](#codersdkagentscripttiming)         | false    |              | Agent script timings Consolidate agent-related timing metrics into a single struct when updating the API version |
| `provisioner_timings`      | array of [codersdk.ProvisionerTiming](#codersdkprovisionertiming)         | false    |              |                                                                                                                  |

## codersdk.WorkspaceConnectionLatencyMS

```json
{
  "p50": 0,
  "p95": 0
}
```

### Properties

| Name  | Type   | Required | Restrictions | Description |
|-------|--------|----------|--------------|-------------|
| `p50` | number | false    |              |             |
| `p95` | number | false    |              |             |

## codersdk.WorkspaceDeploymentStats

```json
{
  "building": 0,
  "connection_latency_ms": {
    "p50": 0,
    "p95": 0
  },
  "failed": 0,
  "pending": 0,
  "running": 0,
  "rx_bytes": 0,
  "stopped": 0,
  "tx_bytes": 0
}
```

### Properties

| Name                    | Type                                                                           | Required | Restrictions | Description |
|-------------------------|--------------------------------------------------------------------------------|----------|--------------|-------------|
| `building`              | integer                                                                        | false    |              |             |
| `connection_latency_ms` | [codersdk.WorkspaceConnectionLatencyMS](#codersdkworkspaceconnectionlatencyms) | false    |              |             |
| `failed`                | integer                                                                        | false    |              |             |
| `pending`               | integer                                                                        | false    |              |             |
| `running`               | integer                                                                        | false    |              |             |
| `rx_bytes`              | integer                                                                        | false    |              |             |
| `stopped`               | integer                                                                        | false    |              |             |
| `tx_bytes`              | integer                                                                        | false    |              |             |

## codersdk.WorkspaceGroup

```json
{
  "avatar_url": "http://example.com",
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "members": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ],
  "name": "string",
  "organization_display_name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "quota_allowance": 0,
  "role": "admin",
  "source": "user",
  "total_member_count": 0
}
```

### Properties

| Name                        | Type                                                  | Required | Restrictions | Description                                                                                                                                                           |
|-----------------------------|-------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `avatar_url`                | string                                                | false    |              |                                                                                                                                                                       |
| `display_name`              | string                                                | false    |              |                                                                                                                                                                       |
| `id`                        | string                                                | false    |              |                                                                                                                                                                       |
| `members`                   | array of [codersdk.ReducedUser](#codersdkreduceduser) | false    |              |                                                                                                                                                                       |
| `name`                      | string                                                | false    |              |                                                                                                                                                                       |
| `organization_display_name` | string                                                | false    |              |                                                                                                                                                                       |
| `organization_id`           | string                                                | false    |              |                                                                                                                                                                       |
| `organization_name`         | string                                                | false    |              |                                                                                                                                                                       |
| `quota_allowance`           | integer                                               | false    |              |                                                                                                                                                                       |
| `role`                      | [codersdk.WorkspaceRole](#codersdkworkspacerole)      | false    |              |                                                                                                                                                                       |
| `source`                    | [codersdk.GroupSource](#codersdkgroupsource)          | false    |              |                                                                                                                                                                       |
| `total_member_count`        | integer                                               | false    |              | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |

#### Enumerated Values

| Property | Value(s)       |
|----------|----------------|
| `role`   | `admin`, `use` |

## codersdk.WorkspaceHealth

```json
{
  "failing_agents": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "healthy": false
}
```

### Properties

| Name             | Type            | Required | Restrictions | Description                                                          |
|------------------|-----------------|----------|--------------|----------------------------------------------------------------------|
| `failing_agents` | array of string | false    |              | Failing agents lists the IDs of the agents that are failing, if any. |
| `healthy`        | boolean         | false    |              | Healthy is true if the workspace is healthy.                         |

## codersdk.WorkspaceProxy

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "deleted": true,
  "derp_enabled": true,
  "derp_only": true,
  "display_name": "string",
  "healthy": true,
  "icon_url": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "path_app_url": "string",
  "status": {
    "checked_at": "2019-08-24T14:15:22Z",
    "report": {
      "errors": [
        "string"
      ],
      "warnings": [
        "string"
      ]
    },
    "status": "ok"
  },
  "updated_at": "2019-08-24T14:15:22Z",
  "version": "string",
  "wildcard_hostname": "string"
}
```

### Properties

| Name                | Type                                                           | Required | Restrictions | Description                                                                                                                                                                       |
|---------------------|----------------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `created_at`        | string                                                         | false    |              |                                                                                                                                                                                   |
| `deleted`           | boolean                                                        | false    |              |                                                                                                                                                                                   |
| `derp_enabled`      | boolean                                                        | false    |              |                                                                                                                                                                                   |
| `derp_only`         | boolean                                                        | false    |              |                                                                                                                                                                                   |
| `display_name`      | string                                                         | false    |              |                                                                                                                                                                                   |
| `healthy`           | boolean                                                        | false    |              |                                                                                                                                                                                   |
| `icon_url`          | string                                                         | false    |              |                                                                                                                                                                                   |
| `id`                | string                                                         | false    |              |                                                                                                                                                                                   |
| `name`              | string                                                         | false    |              |                                                                                                                                                                                   |
| `path_app_url`      | string                                                         | false    |              | Path app URL is the URL to the base path for path apps. Optional unless wildcard_hostname is set. E.g. https://us.example.com                                                     |
| `status`            | [codersdk.WorkspaceProxyStatus](#codersdkworkspaceproxystatus) | false    |              | Status is the latest status check of the proxy. This will be empty for deleted proxies. This value can be used to determine if a workspace proxy is healthy and ready to use.     |
| `updated_at`        | string                                                         | false    |              |                                                                                                                                                                                   |
| `version`           | string                                                         | false    |              |                                                                                                                                                                                   |
| `wildcard_hostname` | string                                                         | false    |              | Wildcard hostname is the wildcard hostname for subdomain apps. E.g. *.us.example.com E.g.*--suffix.au.example.com Optional. Does not need to be on the same domain as PathAppURL. |

## codersdk.WorkspaceProxyStatus

```json
{
  "checked_at": "2019-08-24T14:15:22Z",
  "report": {
    "errors": [
      "string"
    ],
    "warnings": [
      "string"
    ]
  },
  "status": "ok"
}
```

### Properties

| Name         | Type                                                     | Required | Restrictions | Description                                                               |
|--------------|----------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------|
| `checked_at` | string                                                   | false    |              |                                                                           |
| `report`     | [codersdk.ProxyHealthReport](#codersdkproxyhealthreport) | false    |              | Report provides more information about the health of the workspace proxy. |
| `status`     | [codersdk.ProxyHealthStatus](#codersdkproxyhealthstatus) | false    |              |                                                                           |

## codersdk.WorkspaceQuota

```json
{
  "budget": 0,
  "credits_consumed": 0
}
```

### Properties

| Name               | Type    | Required | Restrictions | Description |
|--------------------|---------|----------|--------------|-------------|
| `budget`           | integer | false    |              |             |
| `credits_consumed` | integer | false    |              |             |

## codersdk.WorkspaceResource

```json
{
  "agents": [
    {
      "api_version": "string",
      "apps": [
        {
          "command": "string",
          "display_name": "string",
          "external": true,
          "group": "string",
          "health": "disabled",
          "healthcheck": {
            "interval": 0,
            "threshold": 0,
            "url": "string"
          },
          "hidden": true,
          "icon": "string",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "open_in": "slim-window",
          "sharing_level": "owner",
          "slug": "string",
          "statuses": [
            {
              "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
              "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
              "created_at": "2019-08-24T14:15:22Z",
              "icon": "string",
              "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
              "message": "string",
              "needs_user_attention": true,
              "state": "working",
              "uri": "string",
              "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
            }
          ],
          "subdomain": true,
          "subdomain_name": "string",
          "tooltip": "string",
          "url": "string"
        }
      ],
      "architecture": "string",
      "connection_timeout_seconds": 0,
      "created_at": "2019-08-24T14:15:22Z",
      "directory": "string",
      "disconnected_at": "2019-08-24T14:15:22Z",
      "display_apps": [
        "vscode"
      ],
      "environment_variables": {
        "property1": "string",
        "property2": "string"
      },
      "expanded_directory": "string",
      "first_connected_at": "2019-08-24T14:15:22Z",
      "health": {
        "healthy": false,
        "reason": "agent has lost connection"
      },
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "instance_id": "string",
      "last_connected_at": "2019-08-24T14:15:22Z",
      "latency": {
        "property1": {
          "latency_ms": 0,
          "preferred": true
        },
        "property2": {
          "latency_ms": 0,
          "preferred": true
        }
      },
      "lifecycle_state": "created",
      "log_sources": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "display_name": "string",
          "icon": "string",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
        }
      ],
      "logs_length": 0,
      "logs_overflowed": true,
      "name": "string",
      "operating_system": "string",
      "parent_id": {
        "uuid": "string",
        "valid": true
      },
      "ready_at": "2019-08-24T14:15:22Z",
      "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
      "scripts": [
        {
          "cron": "string",
          "display_name": "string",
          "exit_code": 0,
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "log_path": "string",
          "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
          "run_on_start": true,
          "run_on_stop": true,
          "script": "string",
          "start_blocks_login": true,
          "status": "ok",
          "timeout": 0
        }
      ],
      "started_at": "2019-08-24T14:15:22Z",
      "startup_script_behavior": "blocking",
      "status": "connecting",
      "subsystems": [
        "envbox"
      ],
      "troubleshooting_url": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "version": "string"
    }
  ],
  "created_at": "2019-08-24T14:15:22Z",
  "daily_cost": 0,
  "hide": true,
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
  "metadata": [
    {
      "key": "string",
      "sensitive": true,
      "value": "string"
    }
  ],
  "name": "string",
  "type": "string",
  "workspace_transition": "start"
}
```

### Properties

| Name                   | Type                                                                              | Required | Restrictions | Description |
|------------------------|-----------------------------------------------------------------------------------|----------|--------------|-------------|
| `agents`               | array of [codersdk.WorkspaceAgent](#codersdkworkspaceagent)                       | false    |              |             |
| `created_at`           | string                                                                            | false    |              |             |
| `daily_cost`           | integer                                                                           | false    |              |             |
| `hide`                 | boolean                                                                           | false    |              |             |
| `icon`                 | string                                                                            | false    |              |             |
| `id`                   | string                                                                            | false    |              |             |
| `job_id`               | string                                                                            | false    |              |             |
| `metadata`             | array of [codersdk.WorkspaceResourceMetadata](#codersdkworkspaceresourcemetadata) | false    |              |             |
| `name`                 | string                                                                            | false    |              |             |
| `type`                 | string                                                                            | false    |              |             |
| `workspace_transition` | [codersdk.WorkspaceTransition](#codersdkworkspacetransition)                      | false    |              |             |

#### Enumerated Values

| Property               | Value(s)                  |
|------------------------|---------------------------|
| `workspace_transition` | `delete`, `start`, `stop` |

## codersdk.WorkspaceResourceMetadata

```json
{
  "key": "string",
  "sensitive": true,
  "value": "string"
}
```

### Properties

| Name        | Type    | Required | Restrictions | Description |
|-------------|---------|----------|--------------|-------------|
| `key`       | string  | false    |              |             |
| `sensitive` | boolean | false    |              |             |
| `value`     | string  | false    |              |             |

## codersdk.WorkspaceRole

```json
"admin"
```

### Properties

#### Enumerated Values

| Value(s)           |
|--------------------|
| ``, `admin`, `use` |

## codersdk.WorkspaceSharingSettings

```json
{
  "shareable_workspace_owners": "none",
  "sharing_disabled": true,
  "sharing_globally_disabled": true
}
```

### Properties

| Name                         | Type                                                                   | Required | Restrictions | Description                                                                                                                     |
|------------------------------|------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------|
| `shareable_workspace_owners` | [codersdk.ShareableWorkspaceOwners](#codersdkshareableworkspaceowners) | false    |              | Shareable workspace owners controls whose workspaces can be shared within the organization.                                     |
| `sharing_disabled`           | boolean                                                                | false    |              | Sharing disabled is deprecated and left for backward compatibility purposes. Deprecated: use `ShareableWorkspaceOwners` instead |
| `sharing_globally_disabled`  | boolean                                                                | false    |              | Sharing globally disabled is true if sharing has been disabled for this organization because of a deployment-wide setting.      |

#### Enumerated Values

| Property                     | Value(s)                               |
|------------------------------|----------------------------------------|
| `shareable_workspace_owners` | `everyone`, `none`, `service_accounts` |

## codersdk.WorkspaceStatus

```json
"pending"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                          |
|-------------------------------------------------------------------------------------------------------------------|
| `canceled`, `canceling`, `deleted`, `deleting`, `failed`, `pending`, `running`, `starting`, `stopped`, `stopping` |

## codersdk.WorkspaceTransition

```json
"start"
```

### Properties

#### Enumerated Values

| Value(s)                  |
|---------------------------|
| `delete`, `start`, `stop` |

## codersdk.WorkspaceUser

```json
{
  "avatar_url": "http://example.com",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "role": "admin",
  "username": "string"
}
```

### Properties

| Name         | Type                                             | Required | Restrictions | Description |
|--------------|--------------------------------------------------|----------|--------------|-------------|
| `avatar_url` | string                                           | false    |              |             |
| `id`         | string                                           | true     |              |             |
| `name`       | string                                           | false    |              |             |
| `role`       | [codersdk.WorkspaceRole](#codersdkworkspacerole) | false    |              |             |
| `username`   | string                                           | true     |              |             |

#### Enumerated Values

| Property | Value(s)       |
|----------|----------------|
| `role`   | `admin`, `use` |

## codersdk.WorkspacesResponse

```json
{
  "count": 0,
  "workspaces": [
    {
      "allow_renames": true,
      "automatic_updates": "always",
      "autostart_schedule": "string",
      "created_at": "2019-08-24T14:15:22Z",
      "deleting_at": "2019-08-24T14:15:22Z",
      "dormant_at": "2019-08-24T14:15:22Z",
      "favorite": true,
      "health": {
        "failing_agents": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "healthy": false
      },
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_prebuild": true,
      "last_used_at": "2019-08-24T14:15:22Z",
      "latest_app_status": {
        "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
        "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
        "created_at": "2019-08-24T14:15:22Z",
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "message": "string",
        "needs_user_attention": true,
        "state": "working",
        "uri": "string",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
      },
      "latest_build": {
        "build_number": 0,
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "deadline": "2019-08-24T14:15:22Z",
        "has_ai_task": true,
        "has_external_agent": true,
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
        "initiator_name": "string",
        "job": {
          "available_workers": [
            "497f6eca-6276-4993-bfeb-53cbbbba6f08"
          ],
          "canceled_at": "2019-08-24T14:15:22Z",
          "completed_at": "2019-08-24T14:15:22Z",
          "created_at": "2019-08-24T14:15:22Z",
          "error": "string",
          "error_code": "REQUIRED_TEMPLATE_VARIABLES",
          "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
          "input": {
            "error": "string",
            "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
            "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
          },
          "logs_overflowed": true,
          "metadata": {
            "template_display_name": "string",
            "template_icon": "string",
            "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
            "template_name": "string",
            "template_version_name": "string",
            "workspace_build_transition": "start",
            "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
            "workspace_name": "string"
          },
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "queue_position": 0,
          "queue_size": 0,
          "started_at": "2019-08-24T14:15:22Z",
          "status": "pending",
          "tags": {
            "property1": "string",
            "property2": "string"
          },
          "type": "template_version_import",
          "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
          "worker_name": "string"
        },
        "matched_provisioners": {
          "available": 0,
          "count": 0,
          "most_recently_seen": "2019-08-24T14:15:22Z"
        },
        "max_deadline": "2019-08-24T14:15:22Z",
        "reason": "initiator",
        "resources": [
          {
            "agents": [
              {
                "api_version": "string",
                "apps": [
                  {
                    "command": "string",
                    "display_name": "string",
                    "external": true,
                    "group": "string",
                    "health": "disabled",
                    "healthcheck": {},
                    "hidden": true,
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "open_in": "slim-window",
                    "sharing_level": "owner",
                    "slug": "string",
                    "statuses": [],
                    "subdomain": true,
                    "subdomain_name": "string",
                    "tooltip": "string",
                    "url": "string"
                  }
                ],
                "architecture": "string",
                "connection_timeout_seconds": 0,
                "created_at": "2019-08-24T14:15:22Z",
                "directory": "string",
                "disconnected_at": "2019-08-24T14:15:22Z",
                "display_apps": [
                  "vscode"
                ],
                "environment_variables": {
                  "property1": "string",
                  "property2": "string"
                },
                "expanded_directory": "string",
                "first_connected_at": "2019-08-24T14:15:22Z",
                "health": {
                  "healthy": false,
                  "reason": "agent has lost connection"
                },
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "instance_id": "string",
                "last_connected_at": "2019-08-24T14:15:22Z",
                "latency": {
                  "property1": {
                    "latency_ms": 0,
                    "preferred": true
                  },
                  "property2": {
                    "latency_ms": 0,
                    "preferred": true
                  }
                },
                "lifecycle_state": "created",
                "log_sources": [
                  {
                    "created_at": "2019-08-24T14:15:22Z",
                    "display_name": "string",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
                  }
                ],
                "logs_length": 0,
                "logs_overflowed": true,
                "name": "string",
                "operating_system": "string",
                "parent_id": {
                  "uuid": "string",
                  "valid": true
                },
                "ready_at": "2019-08-24T14:15:22Z",
                "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
                "scripts": [
                  {
                    "cron": "string",
                    "display_name": "string",
                    "exit_code": 0,
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "log_path": "string",
                    "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                    "run_on_start": true,
                    "run_on_stop": true,
                    "script": "string",
                    "start_blocks_login": true,
                    "status": "ok",
                    "timeout": 0
                  }
                ],
                "started_at": "2019-08-24T14:15:22Z",
                "startup_script_behavior": "blocking",
                "status": "connecting",
                "subsystems": [
                  "envbox"
                ],
                "troubleshooting_url": "string",
                "updated_at": "2019-08-24T14:15:22Z",
                "version": "string"
              }
            ],
            "created_at": "2019-08-24T14:15:22Z",
            "daily_cost": 0,
            "hide": true,
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
            "metadata": [
              {
                "key": "string",
                "sensitive": true,
                "value": "string"
              }
            ],
            "name": "string",
            "type": "string",
            "workspace_transition": "start"
          }
        ],
        "status": "pending",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "template_version_name": "string",
        "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
        "transition": "start",
        "updated_at": "2019-08-24T14:15:22Z",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string",
        "workspace_owner_avatar_url": "string",
        "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
        "workspace_owner_name": "string"
      },
      "name": "string",
      "next_start_at": "2019-08-24T14:15:22Z",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "organization_name": "string",
      "outdated": true,
      "owner_avatar_url": "string",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "owner_name": "string",
      "shared_with": [
        {
          "actor_type": "group",
          "avatar_url": "http://example.com",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "name": "string",
          "roles": [
            "admin"
          ]
        }
      ],
      "task_id": {
        "uuid": "string",
        "valid": true
      },
      "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
      "template_allow_user_cancel_workspace_jobs": true,
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_require_active_version": true,
      "template_use_classic_parameter_flow": true,
      "ttl_ms": 0,
      "updated_at": "2019-08-24T14:15:22Z"
    }
  ]
}
```

### Properties

| Name         | Type                                              | Required | Restrictions | Description |
|--------------|---------------------------------------------------|----------|--------------|-------------|
| `count`      | integer                                           | false    |              |             |
| `workspaces` | array of [codersdk.Workspace](#codersdkworkspace) | false    |              |             |

## derp.BytesSentRecv

```json
{
  "key": {},
  "recv": 0,
  "sent": 0
}
```

### Properties

| Name   | Type                             | Required | Restrictions | Description                                                          |
|--------|----------------------------------|----------|--------------|----------------------------------------------------------------------|
| `key`  | [key.NodePublic](#keynodepublic) | false    |              | Key is the public key of the client which sent/received these bytes. |
| `recv` | integer                          | false    |              |                                                                      |
| `sent` | integer                          | false    |              |                                                                      |

## derp.ServerInfoMessage

```json
{
  "tokenBucketBytesBurst": 0,
  "tokenBucketBytesPerSecond": 0
}
```

### Properties

|Name|Type|Required|Restrictions|Description|
|---|---|---|---|---|
|`tokenBucketBytesBurst`|integer|false||Tokenbucketbytesburst is how many bytes the server will allow to burst, temporarily violating TokenBucketBytesPerSecond.
Zero means unspecified. There might be a limit, but the client need not try to respect it.|
|`tokenBucketBytesPerSecond`|integer|false||Tokenbucketbytespersecond is how many bytes per second the server says it will accept, including all framing bytes.
Zero means unspecified. There might be a limit, but the client need not try to respect it.|

## health.Code

```json
"EUNKNOWN"
```

### Properties

#### Enumerated Values

| Value(s)                                                                                                                                                                               |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `EACS01`, `EACS02`, `EACS03`, `EACS04`, `EDB01`, `EDB02`, `EDERP01`, `EDERP02`, `EDERP03`, `EPD01`, `EPD02`, `EPD03`, `EUNKNOWN`, `EWP01`, `EWP02`, `EWP04`, `EWS01`, `EWS02`, `EWS03` |

## health.Message

```json
{
  "code": "EUNKNOWN",
  "message": "string"
}
```

### Properties

| Name      | Type                       | Required | Restrictions | Description |
|-----------|----------------------------|----------|--------------|-------------|
| `code`    | [health.Code](#healthcode) | false    |              |             |
| `message` | string                     | false    |              |             |

## health.Severity

```json
"ok"
```

### Properties

#### Enumerated Values

| Value(s)                 |
|--------------------------|
| `error`, `ok`, `warning` |

## healthsdk.AccessURLReport

```json
{
  "access_url": "string",
  "dismissed": true,
  "error": "string",
  "healthy": true,
  "healthz_response": "string",
  "reachable": true,
  "severity": "ok",
  "status_code": 0,
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name               | Type                                      | Required | Restrictions | Description                                                                                 |
|--------------------|-------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------|
| `access_url`       | string                                    | false    |              |                                                                                             |
| `dismissed`        | boolean                                   | false    |              |                                                                                             |
| `error`            | string                                    | false    |              |                                                                                             |
| `healthy`          | boolean                                   | false    |              | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. |
| `healthz_response` | string                                    | false    |              |                                                                                             |
| `reachable`        | boolean                                   | false    |              |                                                                                             |
| `severity`         | [health.Severity](#healthseverity)        | false    |              |                                                                                             |
| `status_code`      | integer                                   | false    |              |                                                                                             |
| `warnings`         | array of [health.Message](#healthmessage) | false    |              |                                                                                             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.DERPHealthReport

```json
{
  "dismissed": true,
  "error": "string",
  "healthy": true,
  "netcheck": {
    "captivePortal": "string",
    "globalV4": "string",
    "globalV6": "string",
    "hairPinning": "string",
    "icmpv4": true,
    "ipv4": true,
    "ipv4CanSend": true,
    "ipv6": true,
    "ipv6CanSend": true,
    "mappingVariesByDestIP": "string",
    "oshasIPv6": true,
    "pcp": "string",
    "pmp": "string",
    "preferredDERP": 0,
    "regionLatency": {
      "property1": 0,
      "property2": 0
    },
    "regionV4Latency": {
      "property1": 0,
      "property2": 0
    },
    "regionV6Latency": {
      "property1": 0,
      "property2": 0
    },
    "udp": true,
    "upnP": "string"
  },
  "netcheck_err": "string",
  "netcheck_logs": [
    "string"
  ],
  "regions": {
    "property1": {
      "error": "string",
      "healthy": true,
      "node_reports": [
        {
          "can_exchange_messages": true,
          "client_errs": [
            [
              "string"
            ]
          ],
          "client_logs": [
            [
              "string"
            ]
          ],
          "error": "string",
          "healthy": true,
          "node": {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          },
          "node_info": {
            "tokenBucketBytesBurst": 0,
            "tokenBucketBytesPerSecond": 0
          },
          "round_trip_ping": "string",
          "round_trip_ping_ms": 0,
          "severity": "ok",
          "stun": {
            "canSTUN": true,
            "enabled": true,
            "error": "string"
          },
          "uses_websocket": true,
          "warnings": [
            {
              "code": "EUNKNOWN",
              "message": "string"
            }
          ]
        }
      ],
      "region": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      },
      "severity": "ok",
      "warnings": [
        {
          "code": "EUNKNOWN",
          "message": "string"
        }
      ]
    },
    "property2": {
      "error": "string",
      "healthy": true,
      "node_reports": [
        {
          "can_exchange_messages": true,
          "client_errs": [
            [
              "string"
            ]
          ],
          "client_logs": [
            [
              "string"
            ]
          ],
          "error": "string",
          "healthy": true,
          "node": {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          },
          "node_info": {
            "tokenBucketBytesBurst": 0,
            "tokenBucketBytesPerSecond": 0
          },
          "round_trip_ping": "string",
          "round_trip_ping_ms": 0,
          "severity": "ok",
          "stun": {
            "canSTUN": true,
            "enabled": true,
            "error": "string"
          },
          "uses_websocket": true,
          "warnings": [
            {
              "code": "EUNKNOWN",
              "message": "string"
            }
          ]
        }
      ],
      "region": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      },
      "severity": "ok",
      "warnings": [
        {
          "code": "EUNKNOWN",
          "message": "string"
        }
      ]
    }
  },
  "severity": "ok",
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name               | Type                                                     | Required | Restrictions | Description                                                                                 |
|--------------------|----------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------|
| `dismissed`        | boolean                                                  | false    |              |                                                                                             |
| `error`            | string                                                   | false    |              |                                                                                             |
| `healthy`          | boolean                                                  | false    |              | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. |
| `netcheck`         | [netcheck.Report](#netcheckreport)                       | false    |              |                                                                                             |
| `netcheck_err`     | string                                                   | false    |              |                                                                                             |
| `netcheck_logs`    | array of string                                          | false    |              |                                                                                             |
| `regions`          | object                                                   | false    |              |                                                                                             |
| » `[any property]` | [healthsdk.DERPRegionReport](#healthsdkderpregionreport) | false    |              |                                                                                             |
| `severity`         | [health.Severity](#healthseverity)                       | false    |              |                                                                                             |
| `warnings`         | array of [health.Message](#healthmessage)                | false    |              |                                                                                             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.DERPNodeReport

```json
{
  "can_exchange_messages": true,
  "client_errs": [
    [
      "string"
    ]
  ],
  "client_logs": [
    [
      "string"
    ]
  ],
  "error": "string",
  "healthy": true,
  "node": {
    "canPort80": true,
    "certName": "string",
    "derpport": 0,
    "forceHTTP": true,
    "hostName": "string",
    "insecureForTests": true,
    "ipv4": "string",
    "ipv6": "string",
    "name": "string",
    "regionID": 0,
    "stunonly": true,
    "stunport": 0,
    "stuntestIP": "string"
  },
  "node_info": {
    "tokenBucketBytesBurst": 0,
    "tokenBucketBytesPerSecond": 0
  },
  "round_trip_ping": "string",
  "round_trip_ping_ms": 0,
  "severity": "ok",
  "stun": {
    "canSTUN": true,
    "enabled": true,
    "error": "string"
  },
  "uses_websocket": true,
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name                    | Type                                             | Required | Restrictions | Description                                                                                 |
|-------------------------|--------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------|
| `can_exchange_messages` | boolean                                          | false    |              |                                                                                             |
| `client_errs`           | array of array                                   | false    |              |                                                                                             |
| `client_logs`           | array of array                                   | false    |              |                                                                                             |
| `error`                 | string                                           | false    |              |                                                                                             |
| `healthy`               | boolean                                          | false    |              | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. |
| `node`                  | [tailcfg.DERPNode](#tailcfgderpnode)             | false    |              |                                                                                             |
| `node_info`             | [derp.ServerInfoMessage](#derpserverinfomessage) | false    |              |                                                                                             |
| `round_trip_ping`       | string                                           | false    |              |                                                                                             |
| `round_trip_ping_ms`    | integer                                          | false    |              |                                                                                             |
| `severity`              | [health.Severity](#healthseverity)               | false    |              |                                                                                             |
| `stun`                  | [healthsdk.STUNReport](#healthsdkstunreport)     | false    |              |                                                                                             |
| `uses_websocket`        | boolean                                          | false    |              |                                                                                             |
| `warnings`              | array of [health.Message](#healthmessage)        | false    |              |                                                                                             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.DERPRegionReport

```json
{
  "error": "string",
  "healthy": true,
  "node_reports": [
    {
      "can_exchange_messages": true,
      "client_errs": [
        [
          "string"
        ]
      ],
      "client_logs": [
        [
          "string"
        ]
      ],
      "error": "string",
      "healthy": true,
      "node": {
        "canPort80": true,
        "certName": "string",
        "derpport": 0,
        "forceHTTP": true,
        "hostName": "string",
        "insecureForTests": true,
        "ipv4": "string",
        "ipv6": "string",
        "name": "string",
        "regionID": 0,
        "stunonly": true,
        "stunport": 0,
        "stuntestIP": "string"
      },
      "node_info": {
        "tokenBucketBytesBurst": 0,
        "tokenBucketBytesPerSecond": 0
      },
      "round_trip_ping": "string",
      "round_trip_ping_ms": 0,
      "severity": "ok",
      "stun": {
        "canSTUN": true,
        "enabled": true,
        "error": "string"
      },
      "uses_websocket": true,
      "warnings": [
        {
          "code": "EUNKNOWN",
          "message": "string"
        }
      ]
    }
  ],
  "region": {
    "avoid": true,
    "embeddedRelay": true,
    "nodes": [
      {
        "canPort80": true,
        "certName": "string",
        "derpport": 0,
        "forceHTTP": true,
        "hostName": "string",
        "insecureForTests": true,
        "ipv4": "string",
        "ipv6": "string",
        "name": "string",
        "regionID": 0,
        "stunonly": true,
        "stunport": 0,
        "stuntestIP": "string"
      }
    ],
    "regionCode": "string",
    "regionID": 0,
    "regionName": "string"
  },
  "severity": "ok",
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name           | Type                                                          | Required | Restrictions | Description                                                                                 |
|----------------|---------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------|
| `error`        | string                                                        | false    |              |                                                                                             |
| `healthy`      | boolean                                                       | false    |              | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. |
| `node_reports` | array of [healthsdk.DERPNodeReport](#healthsdkderpnodereport) | false    |              |                                                                                             |
| `region`       | [tailcfg.DERPRegion](#tailcfgderpregion)                      | false    |              |                                                                                             |
| `severity`     | [health.Severity](#healthseverity)                            | false    |              |                                                                                             |
| `warnings`     | array of [health.Message](#healthmessage)                     | false    |              |                                                                                             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.DatabaseReport

```json
{
  "dismissed": true,
  "error": "string",
  "healthy": true,
  "latency": "string",
  "latency_ms": 0,
  "reachable": true,
  "severity": "ok",
  "threshold_ms": 0,
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name           | Type                                      | Required | Restrictions | Description                                                                                 |
|----------------|-------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------|
| `dismissed`    | boolean                                   | false    |              |                                                                                             |
| `error`        | string                                    | false    |              |                                                                                             |
| `healthy`      | boolean                                   | false    |              | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. |
| `latency`      | string                                    | false    |              |                                                                                             |
| `latency_ms`   | integer                                   | false    |              |                                                                                             |
| `reachable`    | boolean                                   | false    |              |                                                                                             |
| `severity`     | [health.Severity](#healthseverity)        | false    |              |                                                                                             |
| `threshold_ms` | integer                                   | false    |              |                                                                                             |
| `warnings`     | array of [health.Message](#healthmessage) | false    |              |                                                                                             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.HealthSection

```json
"DERP"
```

### Properties

#### Enumerated Values

| Value(s)                                                                             |
|--------------------------------------------------------------------------------------|
| `AccessURL`, `DERP`, `Database`, `ProvisionerDaemons`, `Websocket`, `WorkspaceProxy` |

## healthsdk.HealthSettings

```json
{
  "dismissed_healthchecks": [
    "DERP"
  ]
}
```

### Properties

| Name                     | Type                                                        | Required | Restrictions | Description |
|--------------------------|-------------------------------------------------------------|----------|--------------|-------------|
| `dismissed_healthchecks` | array of [healthsdk.HealthSection](#healthsdkhealthsection) | false    |              |             |

## healthsdk.HealthcheckReport

```json
{
  "access_url": {
    "access_url": "string",
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "healthz_response": "string",
    "reachable": true,
    "severity": "ok",
    "status_code": 0,
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "coder_version": "string",
  "database": {
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "latency": "string",
    "latency_ms": 0,
    "reachable": true,
    "severity": "ok",
    "threshold_ms": 0,
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "derp": {
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "netcheck": {
      "captivePortal": "string",
      "globalV4": "string",
      "globalV6": "string",
      "hairPinning": "string",
      "icmpv4": true,
      "ipv4": true,
      "ipv4CanSend": true,
      "ipv6": true,
      "ipv6CanSend": true,
      "mappingVariesByDestIP": "string",
      "oshasIPv6": true,
      "pcp": "string",
      "pmp": "string",
      "preferredDERP": 0,
      "regionLatency": {
        "property1": 0,
        "property2": 0
      },
      "regionV4Latency": {
        "property1": 0,
        "property2": 0
      },
      "regionV6Latency": {
        "property1": 0,
        "property2": 0
      },
      "udp": true,
      "upnP": "string"
    },
    "netcheck_err": "string",
    "netcheck_logs": [
      "string"
    ],
    "regions": {
      "property1": {
        "error": "string",
        "healthy": true,
        "node_reports": [
          {
            "can_exchange_messages": true,
            "client_errs": [
              [
                "string"
              ]
            ],
            "client_logs": [
              [
                "string"
              ]
            ],
            "error": "string",
            "healthy": true,
            "node": {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            },
            "node_info": {
              "tokenBucketBytesBurst": 0,
              "tokenBucketBytesPerSecond": 0
            },
            "round_trip_ping": "string",
            "round_trip_ping_ms": 0,
            "severity": "ok",
            "stun": {
              "canSTUN": true,
              "enabled": true,
              "error": "string"
            },
            "uses_websocket": true,
            "warnings": [
              {
                "code": "EUNKNOWN",
                "message": "string"
              }
            ]
          }
        ],
        "region": {
          "avoid": true,
          "embeddedRelay": true,
          "nodes": [
            {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            }
          ],
          "regionCode": "string",
          "regionID": 0,
          "regionName": "string"
        },
        "severity": "ok",
        "warnings": [
          {
            "code": "EUNKNOWN",
            "message": "string"
          }
        ]
      },
      "property2": {
        "error": "string",
        "healthy": true,
        "node_reports": [
          {
            "can_exchange_messages": true,
            "client_errs": [
              [
                "string"
              ]
            ],
            "client_logs": [
              [
                "string"
              ]
            ],
            "error": "string",
            "healthy": true,
            "node": {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            },
            "node_info": {
              "tokenBucketBytesBurst": 0,
              "tokenBucketBytesPerSecond": 0
            },
            "round_trip_ping": "string",
            "round_trip_ping_ms": 0,
            "severity": "ok",
            "stun": {
              "canSTUN": true,
              "enabled": true,
              "error": "string"
            },
            "uses_websocket": true,
            "warnings": [
              {
                "code": "EUNKNOWN",
                "message": "string"
              }
            ]
          }
        ],
        "region": {
          "avoid": true,
          "embeddedRelay": true,
          "nodes": [
            {
              "canPort80": true,
              "certName": "string",
              "derpport": 0,
              "forceHTTP": true,
              "hostName": "string",
              "insecureForTests": true,
              "ipv4": "string",
              "ipv6": "string",
              "name": "string",
              "regionID": 0,
              "stunonly": true,
              "stunport": 0,
              "stuntestIP": "string"
            }
          ],
          "regionCode": "string",
          "regionID": 0,
          "regionName": "string"
        },
        "severity": "ok",
        "warnings": [
          {
            "code": "EUNKNOWN",
            "message": "string"
          }
        ]
      }
    },
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "healthy": true,
  "provisioner_daemons": {
    "dismissed": true,
    "error": "string",
    "items": [
      {
        "provisioner_daemon": {
          "api_version": "string",
          "created_at": "2019-08-24T14:15:22Z",
          "current_job": {
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "status": "pending",
            "template_display_name": "string",
            "template_icon": "string",
            "template_name": "string"
          },
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
          "key_name": "string",
          "last_seen_at": "2019-08-24T14:15:22Z",
          "name": "string",
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "previous_job": {
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "status": "pending",
            "template_display_name": "string",
            "template_icon": "string",
            "template_name": "string"
          },
          "provisioners": [
            "string"
          ],
          "status": "offline",
          "tags": {
            "property1": "string",
            "property2": "string"
          },
          "version": "string"
        },
        "warnings": [
          {
            "code": "EUNKNOWN",
            "message": "string"
          }
        ]
      }
    ],
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "severity": "ok",
  "time": "2019-08-24T14:15:22Z",
  "websocket": {
    "body": "string",
    "code": 0,
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ]
  },
  "workspace_proxy": {
    "dismissed": true,
    "error": "string",
    "healthy": true,
    "severity": "ok",
    "warnings": [
      {
        "code": "EUNKNOWN",
        "message": "string"
      }
    ],
    "workspace_proxies": {
      "regions": [
        {
          "created_at": "2019-08-24T14:15:22Z",
          "deleted": true,
          "derp_enabled": true,
          "derp_only": true,
          "display_name": "string",
          "healthy": true,
          "icon_url": "string",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "name": "string",
          "path_app_url": "string",
          "status": {
            "checked_at": "2019-08-24T14:15:22Z",
            "report": {
              "errors": [
                "string"
              ],
              "warnings": [
                "string"
              ]
            },
            "status": "ok"
          },
          "updated_at": "2019-08-24T14:15:22Z",
          "version": "string",
          "wildcard_hostname": "string"
        }
      ]
    }
  }
}
```

### Properties

| Name                  | Type                                                                     | Required | Restrictions | Description                                                                         |
|-----------------------|--------------------------------------------------------------------------|----------|--------------|-------------------------------------------------------------------------------------|
| `access_url`          | [healthsdk.AccessURLReport](#healthsdkaccessurlreport)                   | false    |              |                                                                                     |
| `coder_version`       | string                                                                   | false    |              | The Coder version of the server that the report was generated on.                   |
| `database`            | [healthsdk.DatabaseReport](#healthsdkdatabasereport)                     | false    |              |                                                                                     |
| `derp`                | [healthsdk.DERPHealthReport](#healthsdkderphealthreport)                 | false    |              |                                                                                     |
| `healthy`             | boolean                                                                  | false    |              | Healthy is true if the report returns no errors. Deprecated: use `Severity` instead |
| `provisioner_daemons` | [healthsdk.ProvisionerDaemonsReport](#healthsdkprovisionerdaemonsreport) | false    |              |                                                                                     |
| `severity`            | [health.Severity](#healthseverity)                                       | false    |              | Severity indicates the status of Coder health.                                      |
| `time`                | string                                                                   | false    |              | Time is the time the report was generated at.                                       |
| `websocket`           | [healthsdk.WebsocketReport](#healthsdkwebsocketreport)                   | false    |              |                                                                                     |
| `workspace_proxy`     | [healthsdk.WorkspaceProxyReport](#healthsdkworkspaceproxyreport)         | false    |              |                                                                                     |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.ProvisionerDaemonsReport

```json
{
  "dismissed": true,
  "error": "string",
  "items": [
    {
      "provisioner_daemon": {
        "api_version": "string",
        "created_at": "2019-08-24T14:15:22Z",
        "current_job": {
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "status": "pending",
          "template_display_name": "string",
          "template_icon": "string",
          "template_name": "string"
        },
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
        "key_name": "string",
        "last_seen_at": "2019-08-24T14:15:22Z",
        "name": "string",
        "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
        "previous_job": {
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "status": "pending",
          "template_display_name": "string",
          "template_icon": "string",
          "template_name": "string"
        },
        "provisioners": [
          "string"
        ],
        "status": "offline",
        "tags": {
          "property1": "string",
          "property2": "string"
        },
        "version": "string"
      },
      "warnings": [
        {
          "code": "EUNKNOWN",
          "message": "string"
        }
      ]
    }
  ],
  "severity": "ok",
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name        | Type                                                                                      | Required | Restrictions | Description |
|-------------|-------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `dismissed` | boolean                                                                                   | false    |              |             |
| `error`     | string                                                                                    | false    |              |             |
| `items`     | array of [healthsdk.ProvisionerDaemonsReportItem](#healthsdkprovisionerdaemonsreportitem) | false    |              |             |
| `severity`  | [health.Severity](#healthseverity)                                                        | false    |              |             |
| `warnings`  | array of [health.Message](#healthmessage)                                                 | false    |              |             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.ProvisionerDaemonsReportItem

```json
{
  "provisioner_daemon": {
    "api_version": "string",
    "created_at": "2019-08-24T14:15:22Z",
    "current_job": {
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "status": "pending",
      "template_display_name": "string",
      "template_icon": "string",
      "template_name": "string"
    },
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
    "key_name": "string",
    "last_seen_at": "2019-08-24T14:15:22Z",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "previous_job": {
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "status": "pending",
      "template_display_name": "string",
      "template_icon": "string",
      "template_name": "string"
    },
    "provisioners": [
      "string"
    ],
    "status": "offline",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "version": "string"
  },
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name                 | Type                                                     | Required | Restrictions | Description |
|----------------------|----------------------------------------------------------|----------|--------------|-------------|
| `provisioner_daemon` | [codersdk.ProvisionerDaemon](#codersdkprovisionerdaemon) | false    |              |             |
| `warnings`           | array of [health.Message](#healthmessage)                | false    |              |             |

## healthsdk.STUNReport

```json
{
  "canSTUN": true,
  "enabled": true,
  "error": "string"
}
```

### Properties

| Name      | Type    | Required | Restrictions | Description |
|-----------|---------|----------|--------------|-------------|
| `canSTUN` | boolean | false    |              |             |
| `enabled` | boolean | false    |              |             |
| `error`   | string  | false    |              |             |

## healthsdk.UpdateHealthSettings

```json
{
  "dismissed_healthchecks": [
    "DERP"
  ]
}
```

### Properties

| Name                     | Type                                                        | Required | Restrictions | Description |
|--------------------------|-------------------------------------------------------------|----------|--------------|-------------|
| `dismissed_healthchecks` | array of [healthsdk.HealthSection](#healthsdkhealthsection) | false    |              |             |

## healthsdk.WebsocketReport

```json
{
  "body": "string",
  "code": 0,
  "dismissed": true,
  "error": "string",
  "healthy": true,
  "severity": "ok",
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ]
}
```

### Properties

| Name        | Type                                      | Required | Restrictions | Description                                                                                 |
|-------------|-------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------|
| `body`      | string                                    | false    |              |                                                                                             |
| `code`      | integer                                   | false    |              |                                                                                             |
| `dismissed` | boolean                                   | false    |              |                                                                                             |
| `error`     | string                                    | false    |              |                                                                                             |
| `healthy`   | boolean                                   | false    |              | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. |
| `severity`  | [health.Severity](#healthseverity)        | false    |              |                                                                                             |
| `warnings`  | array of [health.Message](#healthmessage) | false    |              |                                                                                             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## healthsdk.WorkspaceProxyReport

```json
{
  "dismissed": true,
  "error": "string",
  "healthy": true,
  "severity": "ok",
  "warnings": [
    {
      "code": "EUNKNOWN",
      "message": "string"
    }
  ],
  "workspace_proxies": {
    "regions": [
      {
        "created_at": "2019-08-24T14:15:22Z",
        "deleted": true,
        "derp_enabled": true,
        "derp_only": true,
        "display_name": "string",
        "healthy": true,
        "icon_url": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "name": "string",
        "path_app_url": "string",
        "status": {
          "checked_at": "2019-08-24T14:15:22Z",
          "report": {
            "errors": [
              "string"
            ],
            "warnings": [
              "string"
            ]
          },
          "status": "ok"
        },
        "updated_at": "2019-08-24T14:15:22Z",
        "version": "string",
        "wildcard_hostname": "string"
      }
    ]
  }
}
```

### Properties

| Name                | Type                                                                                                 | Required | Restrictions | Description                                                                                 |
|---------------------|------------------------------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------|
| `dismissed`         | boolean                                                                                              | false    |              |                                                                                             |
| `error`             | string                                                                                               | false    |              |                                                                                             |
| `healthy`           | boolean                                                                                              | false    |              | Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead. |
| `severity`          | [health.Severity](#healthseverity)                                                                   | false    |              |                                                                                             |
| `warnings`          | array of [health.Message](#healthmessage)                                                            | false    |              |                                                                                             |
| `workspace_proxies` | [codersdk.RegionsResponse-codersdk_WorkspaceProxy](#codersdkregionsresponse-codersdk_workspaceproxy) | false    |              |                                                                                             |

#### Enumerated Values

| Property   | Value(s)                 |
|------------|--------------------------|
| `severity` | `error`, `ok`, `warning` |

## key.NodePublic

```json
{}
```

### Properties

None

## netcheck.Report

```json
{
  "captivePortal": "string",
  "globalV4": "string",
  "globalV6": "string",
  "hairPinning": "string",
  "icmpv4": true,
  "ipv4": true,
  "ipv4CanSend": true,
  "ipv6": true,
  "ipv6CanSend": true,
  "mappingVariesByDestIP": "string",
  "oshasIPv6": true,
  "pcp": "string",
  "pmp": "string",
  "preferredDERP": 0,
  "regionLatency": {
    "property1": 0,
    "property2": 0
  },
  "regionV4Latency": {
    "property1": 0,
    "property2": 0
  },
  "regionV6Latency": {
    "property1": 0,
    "property2": 0
  },
  "udp": true,
  "upnP": "string"
}
```

### Properties

| Name                    | Type    | Required | Restrictions | Description                                                                                                                        |
|-------------------------|---------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------|
| `captivePortal`         | string  | false    |              | Captiveportal is set when we think there's a captive portal that is intercepting HTTP traffic.                                     |
| `globalV4`              | string  | false    |              | ip:port of global IPv4                                                                                                             |
| `globalV6`              | string  | false    |              | [ip]:port of global IPv6                                                                                                           |
| `hairPinning`           | string  | false    |              | Hairpinning is whether the router supports communicating between two local devices through the NATted public IP address (on IPv4). |
| `icmpv4`                | boolean | false    |              | an ICMPv4 round trip completed                                                                                                     |
| `ipv4`                  | boolean | false    |              | an IPv4 STUN round trip completed                                                                                                  |
| `ipv4CanSend`           | boolean | false    |              | an IPv4 packet was able to be sent                                                                                                 |
| `ipv6`                  | boolean | false    |              | an IPv6 STUN round trip completed                                                                                                  |
| `ipv6CanSend`           | boolean | false    |              | an IPv6 packet was able to be sent                                                                                                 |
| `mappingVariesByDestIP` | string  | false    |              | Mappingvariesbydestip is whether STUN results depend which STUN server you're talking to (on IPv4).                                |
| `oshasIPv6`             | boolean | false    |              | could bind a socket to ::1                                                                                                         |
| `pcp`                   | string  | false    |              | Pcp is whether PCP appears present on the LAN. Empty means not checked.                                                            |
| `pmp`                   | string  | false    |              | Pmp is whether NAT-PMP appears present on the LAN. Empty means not checked.                                                        |
| `preferredDERP`         | integer | false    |              | or 0 for unknown                                                                                                                   |
| `regionLatency`         | object  | false    |              | keyed by DERP Region ID                                                                                                            |
| » `[any property]`      | integer | false    |              |                                                                                                                                    |
| `regionV4Latency`       | object  | false    |              | keyed by DERP Region ID                                                                                                            |
| » `[any property]`      | integer | false    |              |                                                                                                                                    |
| `regionV6Latency`       | object  | false    |              | keyed by DERP Region ID                                                                                                            |
| » `[any property]`      | integer | false    |              |                                                                                                                                    |
| `udp`                   | boolean | false    |              | a UDP STUN round trip completed                                                                                                    |
| `upnP`                  | string  | false    |              | Upnp is whether UPnP appears present on the LAN. Empty means not checked.                                                          |

## oauth2.Token

```json
{
  "access_token": "string",
  "expires_in": 0,
  "expiry": "string",
  "refresh_token": "string",
  "token_type": "string"
}
```

### Properties

| Name           | Type    | Required | Restrictions | Description                                                                                                                                                                                                                                                                 |
|----------------|---------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `access_token` | string  | false    |              | Access token is the token that authorizes and authenticates the requests.                                                                                                                                                                                                   |
| `expires_in`   | integer | false    |              | Expires in is the OAuth2 wire format "expires_in" field, which specifies how many seconds later the token expires, relative to an unknown time base approximately around "now". It is the application's responsibility to populate `Expiry` from `ExpiresIn` when required. |
|`expiry`|string|false||Expiry is the optional expiration time of the access token.
If zero, [TokenSource] implementations will reuse the same token forever and RefreshToken or equivalent mechanisms for that TokenSource will not be used.|
|`refresh_token`|string|false||Refresh token is a token that's used by the application (as opposed to the user) to refresh the access token if it expires.|
|`token_type`|string|false||Token type is the type of token. The Type method returns either this or "Bearer", the default.|

## regexp.Regexp

```json
{}
```

### Properties

None

## serpent.Annotations

```json
{
  "property1": "string",
  "property2": "string"
}
```

### Properties

| Name             | Type   | Required | Restrictions | Description |
|------------------|--------|----------|--------------|-------------|
| `[any property]` | string | false    |              |             |

## serpent.Group

```json
{
  "description": "string",
  "name": "string",
  "parent": {
    "description": "string",
    "name": "string",
    "parent": {},
    "yaml": "string"
  },
  "yaml": "string"
}
```

### Properties

| Name          | Type                           | Required | Restrictions | Description |
|---------------|--------------------------------|----------|--------------|-------------|
| `description` | string                         | false    |              |             |
| `name`        | string                         | false    |              |             |
| `parent`      | [serpent.Group](#serpentgroup) | false    |              |             |
| `yaml`        | string                         | false    |              |             |

## serpent.HostPort

```json
{
  "host": "string",
  "port": "string"
}
```

### Properties

| Name   | Type   | Required | Restrictions | Description |
|--------|--------|----------|--------------|-------------|
| `host` | string | false    |              |             |
| `port` | string | false    |              |             |

## serpent.Option

```json
{
  "annotations": {
    "property1": "string",
    "property2": "string"
  },
  "default": "string",
  "description": "string",
  "env": "string",
  "flag": "string",
  "flag_shorthand": "string",
  "group": {
    "description": "string",
    "name": "string",
    "parent": {
      "description": "string",
      "name": "string",
      "parent": {},
      "yaml": "string"
    },
    "yaml": "string"
  },
  "hidden": true,
  "name": "string",
  "required": true,
  "use_instead": [
    {
      "annotations": {
        "property1": "string",
        "property2": "string"
      },
      "default": "string",
      "description": "string",
      "env": "string",
      "flag": "string",
      "flag_shorthand": "string",
      "group": {
        "description": "string",
        "name": "string",
        "parent": {
          "description": "string",
          "name": "string",
          "parent": {},
          "yaml": "string"
        },
        "yaml": "string"
      },
      "hidden": true,
      "name": "string",
      "required": true,
      "use_instead": [],
      "value": null,
      "value_source": "",
      "yaml": "string"
    }
  ],
  "value": null,
  "value_source": "",
  "yaml": "string"
}
```

### Properties

| Name             | Type                                       | Required | Restrictions | Description                                                                                                                                        |
|------------------|--------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| `annotations`    | [serpent.Annotations](#serpentannotations) | false    |              | Annotations enable extensions to serpent higher up in the stack. It's useful for help formatting and documentation generation.                     |
| `default`        | string                                     | false    |              | Default is parsed into Value if set. Must be `""` if `DefaultFn` != nil                                                                            |
| `description`    | string                                     | false    |              |                                                                                                                                                    |
| `env`            | string                                     | false    |              | Env is the environment variable used to configure this option. If unset, environment configuring is disabled.                                      |
| `flag`           | string                                     | false    |              | Flag is the long name of the flag used to configure this option. If unset, flag configuring is disabled.                                           |
| `flag_shorthand` | string                                     | false    |              | Flag shorthand is the one-character shorthand for the flag. If unset, no shorthand is used.                                                        |
| `group`          | [serpent.Group](#serpentgroup)             | false    |              | Group is a group hierarchy that helps organize this option in help, configs and other documentation.                                               |
| `hidden`         | boolean                                    | false    |              |                                                                                                                                                    |
| `name`           | string                                     | false    |              |                                                                                                                                                    |
| `required`       | boolean                                    | false    |              | Required means this value must be set by some means. It requires `ValueSource != ValueSourceNone` If `Default` is set, then `Required` is ignored. |
| `use_instead`    | array of [serpent.Option](#serpentoption)  | false    |              | Use instead is a list of options that should be used instead of this one. The field is used to generate a deprecation warning.                     |
| `value`          | any                                        | false    |              | Value includes the types listed in values.go.                                                                                                      |
| `value_source`   | [serpent.ValueSource](#serpentvaluesource) | false    |              |                                                                                                                                                    |
| `yaml`           | string                                     | false    |              | Yaml is the YAML key used to configure this option. If unset, YAML configuring is disabled.                                                        |

## serpent.Regexp

```json
{}
```

### Properties

None

## serpent.Struct-array_codersdk_ExternalAuthConfig

```json
{
  "value": [
    {
      "api_base_url": "string",
      "app_install_url": "string",
      "app_installations_url": "string",
      "auth_url": "string",
      "client_id": "string",
      "code_challenge_methods_supported": [
        "string"
      ],
      "device_code_url": "string",
      "device_flow": true,
      "display_icon": "string",
      "display_name": "string",
      "id": "string",
      "mcp_tool_allow_regex": "string",
      "mcp_tool_deny_regex": "string",
      "mcp_url": "string",
      "no_refresh": true,
      "regex": "string",
      "revoke_url": "string",
      "scopes": [
        "string"
      ],
      "token_url": "string",
      "type": "string",
      "validate_url": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                                                | Required | Restrictions | Description |
|---------|---------------------------------------------------------------------|----------|--------------|-------------|
| `value` | array of [codersdk.ExternalAuthConfig](#codersdkexternalauthconfig) | false    |              |             |

## serpent.Struct-array_codersdk_LinkConfig

```json
{
  "value": [
    {
      "icon": "bug",
      "location": "navbar",
      "name": "string",
      "target": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                                | Required | Restrictions | Description |
|---------|-----------------------------------------------------|----------|--------------|-------------|
| `value` | array of [codersdk.LinkConfig](#codersdklinkconfig) | false    |              |             |

## serpent.URL

```json
{
  "forceQuery": true,
  "fragment": "string",
  "host": "string",
  "omitHost": true,
  "opaque": "string",
  "path": "string",
  "rawFragment": "string",
  "rawPath": "string",
  "rawQuery": "string",
  "scheme": "string",
  "user": {}
}
```

### Properties

| Name         | Type    | Required | Restrictions | Description                                                                                                                                                            |
|--------------|---------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `forceQuery` | boolean | false    |              | Forcequery indicates whether the original URL contained a query ('?') character. When set, the String method will include a trailing '?', even when RawQuery is empty. |
| `fragment`   | string  | false    |              | fragment for references (without '#')                                                                                                                                  |
| `host`       | string  | false    |              | "host" or "host:port" (see Hostname and Port methods)                                                                                                                  |
| `omitHost`   | boolean | false    |              | Omithost indicates the URL has an empty host (authority). When set, the String method will not include the host when it is empty.                                      |
| `opaque`     | string  | false    |              | encoded opaque data                                                                                                                                                    |
| `path`       | string  | false    |              | path (relative paths may omit leading slash)                                                                                                                           |
|`rawFragment`|string|false||Rawfragment is an optional field containing an encoded fragment hint. See the EscapedFragment method for more details.
In general, code should call EscapedFragment instead of reading RawFragment.|
|`rawPath`|string|false||Rawpath is an optional field containing an encoded path hint. See the EscapedPath method for more details.
In general, code should call EscapedPath instead of reading RawPath.|
|`rawQuery`|string|false||Rawquery contains the encoded query values, without the initial '?'. Use URL.Query to decode the query.|
|`scheme`|string|false|||
|`user`|[url.Userinfo](#urluserinfo)|false||username and password information|

## serpent.ValueSource

```json
""
```

### Properties

#### Enumerated Values

| Value(s)                             |
|--------------------------------------|
| ``, `default`, `env`, `flag`, `yaml` |

## tailcfg.DERPHomeParams

```json
{
  "regionScore": {
    "property1": 0,
    "property2": 0
  }
}
```

### Properties

|Name|Type|Required|Restrictions|Description|
|---|---|---|---|---|
|`regionScore`|object|false||Regionscore scales latencies of DERP regions by a given scaling factor when determining which region to use as the home ("preferred") DERP. Scores in the range (0, 1) will cause this region to be proportionally more preferred, and scores in the range (1, ∞) will penalize a region.
If a region is not present in this map, it is treated as having a score of 1.0.
Scores should not be 0 or negative; such scores will be ignored.
A nil map means no change from the previous value (if any); an empty non-nil map can be sent to reset all scores back to 1.0.|
|» `[any property]`|number|false|||

## tailcfg.DERPMap

```json
{
  "homeParams": {
    "regionScore": {
      "property1": 0,
      "property2": 0
    }
  },
  "omitDefaultRegions": true,
  "regions": {
    "property1": {
      "avoid": true,
      "embeddedRelay": true,
      "nodes": [
        {
          "canPort80": true,
          "certName": "string",
          "derpport": 0,
          "forceHTTP": true,
          "hostName": "string",
          "insecureForTests": true,
          "ipv4": "string",
          "ipv6": "string",
          "name": "string",
          "regionID": 0,
          "stunonly": true,
          "stunport": 0,
          "stuntestIP": "string"
        }
      ],
      "regionCode": "string",
      "regionID": 0,
      "regionName": "string"
    },
    "property2": {
      "avoid": true,
      "embeddedRelay": true,
      "nodes": [
        {
          "canPort80": true,
          "certName": "string",
          "derpport": 0,
          "forceHTTP": true,
          "hostName": "string",
          "insecureForTests": true,
          "ipv4": "string",
          "ipv6": "string",
          "name": "string",
          "regionID": 0,
          "stunonly": true,
          "stunport": 0,
          "stuntestIP": "string"
        }
      ],
      "regionCode": "string",
      "regionID": 0,
      "regionName": "string"
    }
  }
}
```

### Properties

|Name|Type|Required|Restrictions|Description|
|---|---|---|---|---|
|`homeParams`|[tailcfg.DERPHomeParams](#tailcfgderphomeparams)|false||Homeparams if non-nil, is a change in home parameters.
The rest of the DEPRMap fields, if zero, means unchanged.|
|`omitDefaultRegions`|boolean|false||Omitdefaultregions specifies to not use Tailscale's DERP servers, and only use those specified in this DERPMap. If there are none set outside of the defaults, this is a noop.
This field is only meaningful if the Regions map is non-nil (indicating a change).|
|`regions`|object|false||Regions is the set of geographic regions running DERP node(s).
It's keyed by the DERPRegion.RegionID.
The numbers are not necessarily contiguous.|
|» `[any property]`|[tailcfg.DERPRegion](#tailcfgderpregion)|false|||

## tailcfg.DERPNode

```json
{
  "canPort80": true,
  "certName": "string",
  "derpport": 0,
  "forceHTTP": true,
  "hostName": "string",
  "insecureForTests": true,
  "ipv4": "string",
  "ipv6": "string",
  "name": "string",
  "regionID": 0,
  "stunonly": true,
  "stunport": 0,
  "stuntestIP": "string"
}
```

### Properties

| Name        | Type    | Required | Restrictions | Description                                                                                                                                                                                                     |
|-------------|---------|----------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `canPort80` | boolean | false    |              | Canport80 specifies whether this DERP node is accessible over HTTP on port 80 specifically. This is used for captive portal checks.                                                                             |
| `certName`  | string  | false    |              | Certname optionally specifies the expected TLS cert common name. If empty, HostName is used. If CertName is non-empty, HostName is only used for the TCP dial (if IPv4/IPv6 are not present) + TLS ClientHello. |
|`derpport`|integer|false||Derpport optionally provides an alternate TLS port number for the DERP HTTPS server.
If zero, 443 is used.|
|`forceHTTP`|boolean|false||Forcehttp is used by unit tests to force HTTP. It should not be set by users.|
|`hostName`|string|false||Hostname is the DERP node's hostname.
It is required but need not be unique; multiple nodes may have the same HostName but vary in configuration otherwise.|
|`insecureForTests`|boolean|false||Insecurefortests is used by unit tests to disable TLS verification. It should not be set by users.|
|`ipv4`|string|false||Ipv4 optionally forces an IPv4 address to use, instead of using DNS. If empty, A record(s) from DNS lookups of HostName are used. If the string is not an IPv4 address, IPv4 is not used; the conventional string to disable IPv4 (and not use DNS) is "none".|
|`ipv6`|string|false||Ipv6 optionally forces an IPv6 address to use, instead of using DNS. If empty, AAAA record(s) from DNS lookups of HostName are used. If the string is not an IPv6 address, IPv6 is not used; the conventional string to disable IPv6 (and not use DNS) is "none".|
|`name`|string|false||Name is a unique node name (across all regions). It is not a host name. It's typically of the form "1b", "2a", "3b", etc. (region ID + suffix within that region)|
|`regionID`|integer|false||Regionid is the RegionID of the DERPRegion that this node is running in.|
|`stunonly`|boolean|false||Stunonly marks a node as only a STUN server and not a DERP server.|
|`stunport`|integer|false||Port optionally specifies a STUN port to use. Zero means 3478. To disable STUN on this node, use -1.|
|`stuntestIP`|string|false||Stuntestip is used in tests to override the STUN server's IP. If empty, it's assumed to be the same as the DERP server.|

## tailcfg.DERPRegion

```json
{
  "avoid": true,
  "embeddedRelay": true,
  "nodes": [
    {
      "canPort80": true,
      "certName": "string",
      "derpport": 0,
      "forceHTTP": true,
      "hostName": "string",
      "insecureForTests": true,
      "ipv4": "string",
      "ipv6": "string",
      "name": "string",
      "regionID": 0,
      "stunonly": true,
      "stunport": 0,
      "stuntestIP": "string"
    }
  ],
  "regionCode": "string",
  "regionID": 0,
  "regionName": "string"
}
```

### Properties

| Name            | Type    | Required | Restrictions | Description                                                                                                                                                                                                                         |
|-----------------|---------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `avoid`         | boolean | false    |              | Avoid is whether the client should avoid picking this as its home region. The region should only be used if a peer is there. Clients already using this region as their home should migrate away to a new region without Avoid set. |
| `embeddedRelay` | boolean | false    |              | Embeddedrelay is true when the region is bundled with the Coder control plane.                                                                                                                                                      |
|`nodes`|array of [tailcfg.DERPNode](#tailcfgderpnode)|false||Nodes are the DERP nodes running in this region, in priority order for the current client. Client TLS connections should ideally only go to the first entry (falling back to the second if necessary). STUN packets should go to the first 1 or 2.
If nodes within a region route packets amongst themselves, but not to other regions. That said, each user/domain should get a the same preferred node order, so if all nodes for a user/network pick the first one (as they should, when things are healthy), the inter-cluster routing is minimal to zero.|
|`regionCode`|string|false||Regioncode is a short name for the region. It's usually a popular city or airport code in the region: "nyc", "sf", "sin", "fra", etc.|
|`regionID`|integer|false||Regionid is a unique integer for a geographic region.
It corresponds to the legacy derpN.tailscale.com hostnames used by older clients. (Older clients will continue to resolve derpN.tailscale.com when contacting peers, rather than use the server-provided DERPMap)
RegionIDs must be non-zero, positive, and guaranteed to fit in a JavaScript number.
RegionIDs in range 900-999 are reserved for end users to run their own DERP nodes.|
|`regionName`|string|false||Regionname is a long English name for the region: "New York City", "San Francisco", "Singapore", "Frankfurt", etc.|

## url.Userinfo

```json
{}
```

### Properties

None

## uuid.NullUUID

```json
{
  "uuid": "string",
  "valid": true
}
```

### Properties

| Name    | Type    | Required | Restrictions | Description                       |
|---------|---------|----------|--------------|-----------------------------------|
| `uuid`  | string  | false    |              |                                   |
| `valid` | boolean | false    |              | Valid is true if UUID is not NULL |

## workspaceapps.AccessMethod

```json
"path"
```

### Properties

#### Enumerated Values

| Value(s)                        |
|---------------------------------|
| `path`, `subdomain`, `terminal` |

## workspaceapps.IssueTokenRequest

```json
{
  "app_hostname": "string",
  "app_path": "string",
  "app_query": "string",
  "app_request": {
    "access_method": "path",
    "agent_name_or_id": "string",
    "app_prefix": "string",
    "app_slug_or_port": "string",
    "base_path": "string",
    "username_or_id": "string",
    "workspace_name_or_id": "string"
  },
  "path_app_base_url": "string",
  "session_token": "string"
}
```

### Properties

| Name                | Type                                           | Required | Restrictions | Description                                                                                                     |
|---------------------|------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------------------------------|
| `app_hostname`      | string                                         | false    |              | App hostname is the optional hostname for subdomain apps on the external proxy. It must start with an asterisk. |
| `app_path`          | string                                         | false    |              | App path is the path of the user underneath the app base path.                                                  |
| `app_query`         | string                                         | false    |              | App query is the query parameters the user provided in the app request.                                         |
| `app_request`       | [workspaceapps.Request](#workspaceappsrequest) | false    |              |                                                                                                                 |
| `path_app_base_url` | string                                         | false    |              | Path app base URL is required.                                                                                  |
| `session_token`     | string                                         | false    |              | Session token is the session token provided by the user.                                                        |

## workspaceapps.Request

```json
{
  "access_method": "path",
  "agent_name_or_id": "string",
  "app_prefix": "string",
  "app_slug_or_port": "string",
  "base_path": "string",
  "username_or_id": "string",
  "workspace_name_or_id": "string"
}
```

### Properties

| Name                   | Type                                                     | Required | Restrictions | Description                                                                                                                                                                           |
|------------------------|----------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `access_method`        | [workspaceapps.AccessMethod](#workspaceappsaccessmethod) | false    |              |                                                                                                                                                                                       |
| `agent_name_or_id`     | string                                                   | false    |              | Agent name or ID is not required if the workspace has only one agent.                                                                                                                 |
| `app_prefix`           | string                                                   | false    |              | Prefix is the prefix of the subdomain app URL. Prefix should have a trailing "---" if set.                                                                                            |
| `app_slug_or_port`     | string                                                   | false    |              |                                                                                                                                                                                       |
| `base_path`            | string                                                   | false    |              | Base path of the app. For path apps, this is the path prefix in the router for this particular app. For subdomain apps, this should be "/". This is used for setting the cookie path. |
| `username_or_id`       | string                                                   | false    |              | For the following fields, if the AccessMethod is AccessMethodTerminal, then only AgentNameOrID may be set and it must be a UUID. The other fields must be left blank.                 |
| `workspace_name_or_id` | string                                                   | false    |              |                                                                                                                                                                                       |

## workspaceapps.StatsReport

```json
{
  "access_method": "path",
  "agent_id": "string",
  "requests": 0,
  "session_ended_at": "string",
  "session_id": "string",
  "session_started_at": "string",
  "slug_or_port": "string",
  "user_id": "string",
  "workspace_id": "string"
}
```

### Properties

| Name                 | Type                                                     | Required | Restrictions | Description                                                                             |
|----------------------|----------------------------------------------------------|----------|--------------|-----------------------------------------------------------------------------------------|
| `access_method`      | [workspaceapps.AccessMethod](#workspaceappsaccessmethod) | false    |              |                                                                                         |
| `agent_id`           | string                                                   | false    |              |                                                                                         |
| `requests`           | integer                                                  | false    |              |                                                                                         |
| `session_ended_at`   | string                                                   | false    |              | Updated periodically while app is in use active and when the last connection is closed. |
| `session_id`         | string                                                   | false    |              |                                                                                         |
| `session_started_at` | string                                                   | false    |              |                                                                                         |
| `slug_or_port`       | string                                                   | false    |              |                                                                                         |
| `user_id`            | string                                                   | false    |              |                                                                                         |
| `workspace_id`       | string                                                   | false    |              |                                                                                         |

## workspacesdk.AgentConnectionInfo

```json
{
  "derp_force_websockets": true,
  "derp_map": {
    "homeParams": {
      "regionScore": {
        "property1": 0,
        "property2": 0
      }
    },
    "omitDefaultRegions": true,
    "regions": {
      "property1": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      },
      "property2": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      }
    }
  },
  "disable_direct_connections": true,
  "hostname_suffix": "string"
}
```

### Properties

| Name                         | Type                               | Required | Restrictions | Description |
|------------------------------|------------------------------------|----------|--------------|-------------|
| `derp_force_websockets`      | boolean                            | false    |              |             |
| `derp_map`                   | [tailcfg.DERPMap](#tailcfgderpmap) | false    |              |             |
| `disable_direct_connections` | boolean                            | false    |              |             |
| `hostname_suffix`            | string                             | false    |              |             |

## wsproxysdk.CryptoKeysResponse

```json
{
  "crypto_keys": [
    {
      "deletes_at": "2019-08-24T14:15:22Z",
      "feature": "workspace_apps_api_key",
      "secret": "string",
      "sequence": 0,
      "starts_at": "2019-08-24T14:15:22Z"
    }
  ]
}
```

### Properties

| Name          | Type                                              | Required | Restrictions | Description |
|---------------|---------------------------------------------------|----------|--------------|-------------|
| `crypto_keys` | array of [codersdk.CryptoKey](#codersdkcryptokey) | false    |              |             |

## wsproxysdk.DeregisterWorkspaceProxyRequest

```json
{
  "replica_id": "string"
}
```

### Properties

| Name         | Type   | Required | Restrictions | Description                                                                                                                                                                                       |
|--------------|--------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `replica_id` | string | false    |              | Replica ID is a unique identifier for the replica of the proxy that is deregistering. It should be generated by the client on startup and should've already been passed to the register endpoint. |

## wsproxysdk.IssueSignedAppTokenResponse

```json
{
  "signed_token_str": "string"
}
```

### Properties

| Name               | Type   | Required | Restrictions | Description                                                 |
|--------------------|--------|----------|--------------|-------------------------------------------------------------|
| `signed_token_str` | string | false    |              | Signed token str should be set as a cookie on the response. |

## wsproxysdk.RegisterWorkspaceProxyRequest

```json
{
  "access_url": "string",
  "derp_enabled": true,
  "derp_only": true,
  "hostname": "string",
  "replica_error": "string",
  "replica_id": "string",
  "replica_relay_address": "string",
  "version": "string",
  "wildcard_hostname": "string"
}
```

### Properties

| Name           | Type    | Required | Restrictions | Description                                                                                                                              |
|----------------|---------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------|
| `access_url`   | string  | false    |              | Access URL that hits the workspace proxy api.                                                                                            |
| `derp_enabled` | boolean | false    |              | Derp enabled indicates whether the proxy should be included in the DERP map or not.                                                      |
| `derp_only`    | boolean | false    |              | Derp only indicates whether the proxy should only be included in the DERP map and should not be used for serving apps.                   |
| `hostname`     | string  | false    |              | Hostname is the OS hostname of the machine that the proxy is running on.  This is only used for tracking purposes in the replicas table. |
|`replica_error`|string|false||Replica error is the error that the replica encountered when trying to dial it's peers. This is stored in the replicas table for debugging purposes but does not affect the proxy's ability to register.
This value is only stored on subsequent requests to the register endpoint, not the first request.|
|`replica_id`|string|false||Replica ID is a unique identifier for the replica of the proxy that is registering. It should be generated by the client on startup and persisted (in memory only) until the process is restarted.|
|`replica_relay_address`|string|false||Replica relay address is the DERP address of the replica that other replicas may use to connect internally for DERP meshing.|
|`version`|string|false||Version is the Coder version of the proxy.|
|`wildcard_hostname`|string|false||Wildcard hostname that the workspace proxy api is serving for subdomain apps.|

## wsproxysdk.RegisterWorkspaceProxyResponse

```json
{
  "derp_force_websockets": true,
  "derp_map": {
    "homeParams": {
      "regionScore": {
        "property1": 0,
        "property2": 0
      }
    },
    "omitDefaultRegions": true,
    "regions": {
      "property1": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      },
      "property2": {
        "avoid": true,
        "embeddedRelay": true,
        "nodes": [
          {
            "canPort80": true,
            "certName": "string",
            "derpport": 0,
            "forceHTTP": true,
            "hostName": "string",
            "insecureForTests": true,
            "ipv4": "string",
            "ipv6": "string",
            "name": "string",
            "regionID": 0,
            "stunonly": true,
            "stunport": 0,
            "stuntestIP": "string"
          }
        ],
        "regionCode": "string",
        "regionID": 0,
        "regionName": "string"
      }
    }
  },
  "derp_mesh_key": "string",
  "derp_region_id": 0,
  "sibling_replicas": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "database_latency": 0,
      "error": "string",
      "hostname": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "region_id": 0,
      "relay_address": "string"
    }
  ]
}
```

### Properties

| Name                    | Type                                          | Required | Restrictions | Description                                                                            |
|-------------------------|-----------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------|
| `derp_force_websockets` | boolean                                       | false    |              |                                                                                        |
| `derp_map`              | [tailcfg.DERPMap](#tailcfgderpmap)            | false    |              |                                                                                        |
| `derp_mesh_key`         | string                                        | false    |              |                                                                                        |
| `derp_region_id`        | integer                                       | false    |              |                                                                                        |
| `sibling_replicas`      | array of [codersdk.Replica](#codersdkreplica) | false    |              | Sibling replicas is a list of all other replicas of the proxy that have not timed out. |

## wsproxysdk.ReportAppStatsRequest

```json
{
  "stats": [
    {
      "access_method": "path",
      "agent_id": "string",
      "requests": 0,
      "session_ended_at": "string",
      "session_id": "string",
      "session_started_at": "string",
      "slug_or_port": "string",
      "user_id": "string",
      "workspace_id": "string"
    }
  ]
}
```

### Properties

| Name    | Type                                                            | Required | Restrictions | Description |
|---------|-----------------------------------------------------------------|----------|--------------|-------------|
| `stats` | array of [workspaceapps.StatsReport](#workspaceappsstatsreport) | false    |              |             |

---

# Secrets

Source: https://coder.com/docs/reference/api/secrets

# Secrets

## List user secrets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/secrets \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/secrets`

### Parameters

| Name   | In   | Type   | Required | Description              |
|--------|------|--------|----------|--------------------------|
| `user` | path | string | true     | User ID, username, or me |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "description": "string",
    "env_name": "string",
    "file_path": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "updated_at": "2019-08-24T14:15:22Z"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                        |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.UserSecret](schemas.md#codersdkusersecret) |

<h3 id="list-user-secrets-responseschema">Response Schema</h3>

Status Code **200**

| Name            | Type              | Required | Restrictions | Description |
|-----------------|-------------------|----------|--------------|-------------|
| `[array item]`  | array             | false    |              |             |
| `» created_at`  | string(date-time) | false    |              |             |
| `» description` | string            | false    |              |             |
| `» env_name`    | string            | false    |              |             |
| `» file_path`   | string            | false    |              |             |
| `» id`          | string(uuid)      | false    |              |             |
| `» name`        | string            | false    |              |             |
| `» updated_at`  | string(date-time) | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create a new user secret

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/{user}/secrets \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/{user}/secrets`

> Body parameter

```json
{
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "name": "string",
  "value": "string"
}
```

### Parameters

| Name   | In   | Type                                                                           | Required | Description              |
|--------|------|--------------------------------------------------------------------------------|----------|--------------------------|
| `user` | path | string                                                                         | true     | User ID, username, or me |
| `body` | body | [codersdk.CreateUserSecretRequest](schemas.md#codersdkcreateusersecretrequest) | true     | Create secret request    |

### Example responses

> 201 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                               |
|--------|--------------------------------------------------------------|-------------|------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.UserSecret](schemas.md#codersdkusersecret) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get a user secret by name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/secrets/{name} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/secrets/{name}`

### Parameters

| Name   | In   | Type   | Required | Description              |
|--------|------|--------|----------|--------------------------|
| `user` | path | string | true     | User ID, username, or me |
| `name` | path | string | true     | Secret name              |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                               |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserSecret](schemas.md#codersdkusersecret) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete a user secret

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/users/{user}/secrets/{name} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/users/{user}/secrets/{name}`

### Parameters

| Name   | In   | Type   | Required | Description              |
|--------|------|--------|----------|--------------------------|
| `user` | path | string | true     | User ID, username, or me |
| `name` | path | string | true     | Secret name              |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update a user secret

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/users/{user}/secrets/{name} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/users/{user}/secrets/{name}`

> Body parameter

```json
{
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "value": "string"
}
```

### Parameters

| Name   | In   | Type                                                                           | Required | Description              |
|--------|------|--------------------------------------------------------------------------------|----------|--------------------------|
| `user` | path | string                                                                         | true     | User ID, username, or me |
| `name` | path | string                                                                         | true     | Secret name              |
| `body` | body | [codersdk.UpdateUserSecretRequest](schemas.md#codersdkupdateusersecretrequest) | true     | Update secret request    |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "env_name": "string",
  "file_path": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                               |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserSecret](schemas.md#codersdkusersecret) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Tasks

Source: https://coder.com/docs/reference/api/tasks

# Tasks

## List AI tasks

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/tasks \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/tasks`

### Parameters

| Name | In    | Type   | Required | Description                                                                                                         |
|------|-------|--------|----------|---------------------------------------------------------------------------------------------------------------------|
| `q`  | query | string | false    | Search query for filtering tasks. Supports: owner:<username/uuid/me>, organization:<org-name/uuid>, status:<status> |

### Example responses

> 200 Response

```json
{
  "count": 0,
  "tasks": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "current_state": {
        "message": "string",
        "state": "working",
        "timestamp": "2019-08-24T14:15:22Z",
        "uri": "string"
      },
      "display_name": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initial_prompt": "string",
      "name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "owner_avatar_url": "string",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "owner_name": "string",
      "status": "pending",
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "updated_at": "2019-08-24T14:15:22Z",
      "workspace_agent_health": {
        "healthy": false,
        "reason": "agent has lost connection"
      },
      "workspace_agent_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_agent_lifecycle": "created",
      "workspace_app_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_build_number": 0,
      "workspace_id": {
        "uuid": "string",
        "valid": true
      },
      "workspace_name": "string",
      "workspace_status": "pending"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                             |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TasksListResponse](schemas.md#codersdktaskslistresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create a new AI task

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/tasks/{user} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/tasks/{user}`

> Body parameter

```json
{
  "display_name": "string",
  "input": "string",
  "name": "string",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1"
}
```

### Parameters

| Name   | In   | Type                                                               | Required | Description                                           |
|--------|------|--------------------------------------------------------------------|----------|-------------------------------------------------------|
| `user` | path | string                                                             | true     | Username, user ID, or 'me' for the authenticated user |
| `body` | body | [codersdk.CreateTaskRequest](schemas.md#codersdkcreatetaskrequest) | true     | Create task request                                   |

### Example responses

> 201 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "current_state": {
    "message": "string",
    "state": "working",
    "timestamp": "2019-08-24T14:15:22Z",
    "uri": "string"
  },
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initial_prompt": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "status": "pending",
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_agent_health": {
    "healthy": false,
    "reason": "agent has lost connection"
  },
  "workspace_agent_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_agent_lifecycle": "created",
  "workspace_app_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_build_number": 0,
  "workspace_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_name": "string",
  "workspace_status": "pending"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                   |
|--------|--------------------------------------------------------------|-------------|------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.Task](schemas.md#codersdktask) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get AI task by ID or name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/tasks/{user}/{task} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/tasks/{user}/{task}`

### Parameters

| Name   | In   | Type   | Required | Description                                           |
|--------|------|--------|----------|-------------------------------------------------------|
| `user` | path | string | true     | Username, user ID, or 'me' for the authenticated user |
| `task` | path | string | true     | Task ID, or task name                                 |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "current_state": {
    "message": "string",
    "state": "working",
    "timestamp": "2019-08-24T14:15:22Z",
    "uri": "string"
  },
  "display_name": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initial_prompt": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "status": "pending",
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "updated_at": "2019-08-24T14:15:22Z",
  "workspace_agent_health": {
    "healthy": false,
    "reason": "agent has lost connection"
  },
  "workspace_agent_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_agent_lifecycle": "created",
  "workspace_app_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_build_number": 0,
  "workspace_id": {
    "uuid": "string",
    "valid": true
  },
  "workspace_name": "string",
  "workspace_status": "pending"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Task](schemas.md#codersdktask) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete AI task

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/tasks/{user}/{task} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/tasks/{user}/{task}`

### Parameters

| Name   | In   | Type   | Required | Description                                           |
|--------|------|--------|----------|-------------------------------------------------------|
| `user` | path | string | true     | Username, user ID, or 'me' for the authenticated user |
| `task` | path | string | true     | Task ID, or task name                                 |

### Responses

| Status | Meaning                                                       | Description | Schema |
|--------|---------------------------------------------------------------|-------------|--------|
| 202    | [Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) | Accepted    |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update AI task input

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/tasks/{user}/{task}/input \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/tasks/{user}/{task}/input`

> Body parameter

```json
{
  "input": "string"
}
```

### Parameters

| Name   | In   | Type                                                                         | Required | Description                                           |
|--------|------|------------------------------------------------------------------------------|----------|-------------------------------------------------------|
| `user` | path | string                                                                       | true     | Username, user ID, or 'me' for the authenticated user |
| `task` | path | string                                                                       | true     | Task ID, or task name                                 |
| `body` | body | [codersdk.UpdateTaskInputRequest](schemas.md#codersdkupdatetaskinputrequest) | true     | Update task input request                             |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get AI task logs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/tasks/{user}/{task}/logs \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/tasks/{user}/{task}/logs`

### Parameters

| Name   | In   | Type   | Required | Description                                           |
|--------|------|--------|----------|-------------------------------------------------------|
| `user` | path | string | true     | Username, user ID, or 'me' for the authenticated user |
| `task` | path | string | true     | Task ID, or task name                                 |

### Example responses

> 200 Response

```json
{
  "logs": [
    {
      "content": "string",
      "id": 0,
      "time": "2019-08-24T14:15:22Z",
      "type": "input"
    }
  ],
  "snapshot": true,
  "snapshot_at": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TaskLogsResponse](schemas.md#codersdktasklogsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Pause task

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/tasks/{user}/{task}/pause \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/tasks/{user}/{task}/pause`

### Parameters

| Name   | In   | Type         | Required | Description                                           |
|--------|------|--------------|----------|-------------------------------------------------------|
| `user` | path | string       | true     | Username, user ID, or 'me' for the authenticated user |
| `task` | path | string(uuid) | true     | Task ID                                               |

### Example responses

> 202 Response

```json
{
  "workspace_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  }
}
```

### Responses

| Status | Meaning                                                       | Description | Schema                                                             |
|--------|---------------------------------------------------------------|-------------|--------------------------------------------------------------------|
| 202    | [Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) | Accepted    | [codersdk.PauseTaskResponse](schemas.md#codersdkpausetaskresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Resume task

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/tasks/{user}/{task}/resume \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/tasks/{user}/{task}/resume`

### Parameters

| Name   | In   | Type         | Required | Description                                           |
|--------|------|--------------|----------|-------------------------------------------------------|
| `user` | path | string       | true     | Username, user ID, or 'me' for the authenticated user |
| `task` | path | string(uuid) | true     | Task ID                                               |

### Example responses

> 202 Response

```json
{
  "workspace_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  }
}
```

### Responses

| Status | Meaning                                                       | Description | Schema                                                               |
|--------|---------------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 202    | [Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) | Accepted    | [codersdk.ResumeTaskResponse](schemas.md#codersdkresumetaskresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Send input to AI task

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/tasks/{user}/{task}/send \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/tasks/{user}/{task}/send`

> Body parameter

```json
{
  "input": "string"
}
```

### Parameters

| Name   | In   | Type                                                           | Required | Description                                           |
|--------|------|----------------------------------------------------------------|----------|-------------------------------------------------------|
| `user` | path | string                                                         | true     | Username, user ID, or 'me' for the authenticated user |
| `task` | path | string                                                         | true     | Task ID, or task name                                 |
| `body` | body | [codersdk.TaskSendRequest](schemas.md#codersdktasksendrequest) | true     | Task input request                                    |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Upload task log snapshot

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaceagents/me/tasks/{task}/log-snapshot?format=agentapi \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaceagents/me/tasks/{task}/log-snapshot`

> Body parameter

```json
{}
```

### Parameters

| Name     | In    | Type         | Required | Description                                                  |
|----------|-------|--------------|----------|--------------------------------------------------------------|
| `task`   | path  | string(uuid) | true     | Task ID                                                      |
| `format` | query | string       | true     | Snapshot format                                              |
| `body`   | body  | object       | true     | Raw snapshot payload (structure depends on format parameter) |

#### Enumerated Values

| Parameter | Value(s)   |
|-----------|------------|
| `format`  | `agentapi` |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Templates

Source: https://coder.com/docs/reference/api/templates

# Templates

## Get templates by organization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/templates`

Returns a list of templates for the specified organization.
By default, only non-deprecated templates are returned.
To include deprecated templates, specify `deprecated:true` in the search query.

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  {
    "active_user_count": 0,
    "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc",
    "activity_bump_ms": 0,
    "allow_user_autostart": true,
    "allow_user_autostop": true,
    "allow_user_cancel_workspace_jobs": true,
    "autostart_requirement": {
      "days_of_week": [
        "monday"
      ]
    },
    "autostop_requirement": {
      "days_of_week": [
        "monday"
      ],
      "weeks": 0
    },
    "build_time_stats": {
      "property1": {
        "p50": 123,
        "p95": 146
      },
      "property2": {
        "p50": 123,
        "p95": 146
      }
    },
    "cors_behavior": "simple",
    "created_at": "2019-08-24T14:15:22Z",
    "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f",
    "created_by_name": "string",
    "default_ttl_ms": 0,
    "deleted": true,
    "deprecated": true,
    "deprecation_message": "string",
    "description": "string",
    "disable_module_cache": true,
    "display_name": "string",
    "failure_ttl_ms": 0,
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "max_port_share_level": "owner",
    "name": "string",
    "organization_display_name": "string",
    "organization_icon": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_name": "string",
    "provisioner": "terraform",
    "require_active_version": true,
    "time_til_dormant_autodelete_ms": 0,
    "time_til_dormant_ms": 0,
    "updated_at": "2019-08-24T14:15:22Z",
    "use_classic_parameter_flow": true
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                    |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Template](schemas.md#codersdktemplate) |

<h3 id="get-templates-by-organization-responseschema">Response Schema</h3>

Status Code **200**

| Name                                 | Type                                                                                     | Required | Restrictions | Description                                                                                                                                                                |
|--------------------------------------|------------------------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                       | array                                                                                    | false    |              |                                                                                                                                                                            |
| `» active_user_count`                | integer                                                                                  | false    |              | Active user count is set to -1 when loading.                                                                                                                               |
| `» active_version_id`                | string(uuid)                                                                             | false    |              |                                                                                                                                                                            |
| `» activity_bump_ms`                 | integer                                                                                  | false    |              |                                                                                                                                                                            |
| `» allow_user_autostart`             | boolean                                                                                  | false    |              | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature.    |
| `» allow_user_autostop`              | boolean                                                                                  | false    |              |                                                                                                                                                                            |
| `» allow_user_cancel_workspace_jobs` | boolean                                                                                  | false    |              |                                                                                                                                                                            |
| `» autostart_requirement`            | [codersdk.TemplateAutostartRequirement](schemas.md#codersdktemplateautostartrequirement) | false    |              |                                                                                                                                                                            |
| `»» days_of_week`                    | array                                                                                    | false    |              | Days of week is a list of days of the week in which autostart is allowed to happen. If no days are specified, autostart is not allowed.                                    |
| `» autostop_requirement`             | [codersdk.TemplateAutostopRequirement](schemas.md#codersdktemplateautostoprequirement)   | false    |              | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature. |
|`»» days_of_week`|array|false||Days of week is a list of days of the week on which restarts are required. Restarts happen within the user's quiet hours (in their configured timezone). If no days are specified, restarts are not required. Weekdays cannot be specified twice.
Restarts will only happen on weekdays in this list on weeks which line up with Weeks.|
|`»» weeks`|integer|false||Weeks is the number of weeks between required restarts. Weeks are synced across all workspaces (and Coder deployments) using modulo math on a hardcoded epoch week of January 2nd, 2023 (the first Monday of 2023). Values of 0 or 1 indicate weekly restarts. Values of 2 indicate fortnightly restarts, etc.|
|`» build_time_stats`|[codersdk.TemplateBuildTimeStats](schemas.md#codersdktemplatebuildtimestats)|false|||
|`»» [any property]`|[codersdk.TransitionStats](schemas.md#codersdktransitionstats)|false|||
|`»»» p50`|integer|false|||
|`»»» p95`|integer|false|||
|`» cors_behavior`|[codersdk.CORSBehavior](schemas.md#codersdkcorsbehavior)|false|||
|`» created_at`|string(date-time)|false|||
|`» created_by_id`|string(uuid)|false|||
|`» created_by_name`|string|false|||
|`» default_ttl_ms`|integer|false|||
|`» deleted`|boolean|false|||
|`» deprecated`|boolean|false|||
|`» deprecation_message`|string|false|||
|`» description`|string|false|||
|`» disable_module_cache`|boolean|false||Disable module cache disables the use of cached Terraform modules during provisioning.|
|`» display_name`|string|false|||
|`» failure_ttl_ms`|integer|false||Failure ttl ms TimeTilDormantMillis, and TimeTilDormantAutoDeleteMillis are enterprise-only. Their values are used if your license is entitled to use the advanced template scheduling feature.|
|`» icon`|string|false|||
|`» id`|string(uuid)|false|||
|`» max_port_share_level`|[codersdk.WorkspaceAgentPortShareLevel](schemas.md#codersdkworkspaceagentportsharelevel)|false|||
|`» name`|string|false|||
|`» organization_display_name`|string|false|||
|`» organization_icon`|string|false|||
|`» organization_id`|string(uuid)|false|||
|`» organization_name`|string(url)|false|||
|`» provisioner`|string|false|||
|`» require_active_version`|boolean|false||Require active version mandates that workspaces are built with the active template version.|
|`» time_til_dormant_autodelete_ms`|integer|false|||
|`» time_til_dormant_ms`|integer|false|||
|`» updated_at`|string(date-time)|false|||
|`» use_classic_parameter_flow`|boolean|false|||

#### Enumerated Values

| Property               | Value(s)                                           |
|------------------------|----------------------------------------------------|
| `cors_behavior`        | `passthru`, `simple`                               |
| `max_port_share_level` | `authenticated`, `organization`, `owner`, `public` |
| `provisioner`          | `terraform`                                        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create template by organization

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templates \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations/{organization}/templates`

> Body parameter

```json
{
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "cors_behavior": "simple",
  "default_ttl_ms": 0,
  "delete_ttl_ms": 0,
  "description": "string",
  "disable_everyone_group_access": true,
  "display_name": "string",
  "dormant_ttl_ms": 0,
  "failure_ttl_ms": 0,
  "icon": "string",
  "max_port_share_level": "owner",
  "name": "string",
  "require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1"
}
```

### Parameters

| Name           | In   | Type                                                                       | Required | Description     |
|----------------|------|----------------------------------------------------------------------------|----------|-----------------|
| `organization` | path | string                                                                     | true     | Organization ID |
| `body`         | body | [codersdk.CreateTemplateRequest](schemas.md#codersdkcreatetemplaterequest) | true     | Request body    |

### Example responses

> 200 Response

```json
{
  "active_user_count": 0,
  "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc",
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "build_time_stats": {
    "property1": {
      "p50": 123,
      "p95": 146
    },
    "property2": {
      "p50": 123,
      "p95": 146
    }
  },
  "cors_behavior": "simple",
  "created_at": "2019-08-24T14:15:22Z",
  "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f",
  "created_by_name": "string",
  "default_ttl_ms": 0,
  "deleted": true,
  "deprecated": true,
  "deprecation_message": "string",
  "description": "string",
  "disable_module_cache": true,
  "display_name": "string",
  "failure_ttl_ms": 0,
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "max_port_share_level": "owner",
  "name": "string",
  "organization_display_name": "string",
  "organization_icon": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "provisioner": "terraform",
  "require_active_version": true,
  "time_til_dormant_autodelete_ms": 0,
  "time_til_dormant_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z",
  "use_classic_parameter_flow": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Template](schemas.md#codersdktemplate) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template examples by organization

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/examples \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/templates/examples`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |

### Example responses

> 200 Response

```json
[
  {
    "description": "string",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "markdown": "string",
    "name": "string",
    "tags": [
      "string"
    ],
    "url": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                  |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.TemplateExample](schemas.md#codersdktemplateexample) |

<h3 id="get-template-examples-by-organization-responseschema">Response Schema</h3>

Status Code **200**

| Name            | Type         | Required | Restrictions | Description |
|-----------------|--------------|----------|--------------|-------------|
| `[array item]`  | array        | false    |              |             |
| `» description` | string       | false    |              |             |
| `» icon`        | string       | false    |              |             |
| `» id`          | string(uuid) | false    |              |             |
| `» markdown`    | string       | false    |              |             |
| `» name`        | string       | false    |              |             |
| `» tags`        | array        | false    |              |             |
| `» url`         | string       | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get templates by organization and template name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/{templatename} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/templates/{templatename}`

### Parameters

| Name           | In   | Type         | Required | Description     |
|----------------|------|--------------|----------|-----------------|
| `organization` | path | string(uuid) | true     | Organization ID |
| `templatename` | path | string       | true     | Template name   |

### Example responses

> 200 Response

```json
{
  "active_user_count": 0,
  "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc",
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "build_time_stats": {
    "property1": {
      "p50": 123,
      "p95": 146
    },
    "property2": {
      "p50": 123,
      "p95": 146
    }
  },
  "cors_behavior": "simple",
  "created_at": "2019-08-24T14:15:22Z",
  "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f",
  "created_by_name": "string",
  "default_ttl_ms": 0,
  "deleted": true,
  "deprecated": true,
  "deprecation_message": "string",
  "description": "string",
  "disable_module_cache": true,
  "display_name": "string",
  "failure_ttl_ms": 0,
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "max_port_share_level": "owner",
  "name": "string",
  "organization_display_name": "string",
  "organization_icon": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "provisioner": "terraform",
  "require_active_version": true,
  "time_til_dormant_autodelete_ms": 0,
  "time_til_dormant_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z",
  "use_classic_parameter_flow": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Template](schemas.md#codersdktemplate) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version by organization, template, and name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}`

### Parameters

| Name                  | In   | Type         | Required | Description           |
|-----------------------|------|--------------|----------|-----------------------|
| `organization`        | path | string(uuid) | true     | Organization ID       |
| `templatename`        | path | string       | true     | Template name         |
| `templateversionname` | path | string       | true     | Template version name |

### Example responses

> 200 Response

```json
{
  "archived": true,
  "created_at": "2019-08-24T14:15:22Z",
  "created_by": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "message": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "readme": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "UNSUPPORTED_WORKSPACES"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get previous template version by organization, template, and name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous`

### Parameters

| Name                  | In   | Type         | Required | Description           |
|-----------------------|------|--------------|----------|-----------------------|
| `organization`        | path | string(uuid) | true     | Organization ID       |
| `templatename`        | path | string       | true     | Template name         |
| `templateversionname` | path | string       | true     | Template version name |

### Example responses

> 200 Response

```json
{
  "archived": true,
  "created_at": "2019-08-24T14:15:22Z",
  "created_by": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "message": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "readme": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "UNSUPPORTED_WORKSPACES"
  ]
}
```

### Responses

| Status | Meaning                                                         | Description | Schema                                                         |
|--------|-----------------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)         | OK          | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |                                                                |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create template version by organization

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templateversions \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations/{organization}/templateversions`

> Body parameter

```json
{
  "example_id": "string",
  "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
  "message": "string",
  "name": "string",
  "provisioner": "terraform",
  "storage_method": "file",
  "tags": {
    "property1": "string",
    "property2": "string"
  },
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "user_variable_values": [
    {
      "name": "string",
      "value": "string"
    }
  ]
}
```

### Parameters

| Name           | In   | Type                                                                                     | Required | Description                     |
|----------------|------|------------------------------------------------------------------------------------------|----------|---------------------------------|
| `organization` | path | string(uuid)                                                                             | true     | Organization ID                 |
| `body`         | body | [codersdk.CreateTemplateVersionRequest](schemas.md#codersdkcreatetemplateversionrequest) | true     | Create template version request |

### Example responses

> 201 Response

```json
{
  "archived": true,
  "created_at": "2019-08-24T14:15:22Z",
  "created_by": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "message": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "readme": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "UNSUPPORTED_WORKSPACES"
  ]
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                         |
|--------|--------------------------------------------------------------|-------------|----------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get all templates

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates`

Returns a list of templates.
By default, only non-deprecated templates are returned.
To include deprecated templates, specify `deprecated:true` in the search query.

### Example responses

> 200 Response

```json
[
  {
    "active_user_count": 0,
    "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc",
    "activity_bump_ms": 0,
    "allow_user_autostart": true,
    "allow_user_autostop": true,
    "allow_user_cancel_workspace_jobs": true,
    "autostart_requirement": {
      "days_of_week": [
        "monday"
      ]
    },
    "autostop_requirement": {
      "days_of_week": [
        "monday"
      ],
      "weeks": 0
    },
    "build_time_stats": {
      "property1": {
        "p50": 123,
        "p95": 146
      },
      "property2": {
        "p50": 123,
        "p95": 146
      }
    },
    "cors_behavior": "simple",
    "created_at": "2019-08-24T14:15:22Z",
    "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f",
    "created_by_name": "string",
    "default_ttl_ms": 0,
    "deleted": true,
    "deprecated": true,
    "deprecation_message": "string",
    "description": "string",
    "disable_module_cache": true,
    "display_name": "string",
    "failure_ttl_ms": 0,
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "max_port_share_level": "owner",
    "name": "string",
    "organization_display_name": "string",
    "organization_icon": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "organization_name": "string",
    "provisioner": "terraform",
    "require_active_version": true,
    "time_til_dormant_autodelete_ms": 0,
    "time_til_dormant_ms": 0,
    "updated_at": "2019-08-24T14:15:22Z",
    "use_classic_parameter_flow": true
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                    |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Template](schemas.md#codersdktemplate) |

<h3 id="get-all-templates-responseschema">Response Schema</h3>

Status Code **200**

| Name                                 | Type                                                                                     | Required | Restrictions | Description                                                                                                                                                                |
|--------------------------------------|------------------------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                       | array                                                                                    | false    |              |                                                                                                                                                                            |
| `» active_user_count`                | integer                                                                                  | false    |              | Active user count is set to -1 when loading.                                                                                                                               |
| `» active_version_id`                | string(uuid)                                                                             | false    |              |                                                                                                                                                                            |
| `» activity_bump_ms`                 | integer                                                                                  | false    |              |                                                                                                                                                                            |
| `» allow_user_autostart`             | boolean                                                                                  | false    |              | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature.    |
| `» allow_user_autostop`              | boolean                                                                                  | false    |              |                                                                                                                                                                            |
| `» allow_user_cancel_workspace_jobs` | boolean                                                                                  | false    |              |                                                                                                                                                                            |
| `» autostart_requirement`            | [codersdk.TemplateAutostartRequirement](schemas.md#codersdktemplateautostartrequirement) | false    |              |                                                                                                                                                                            |
| `»» days_of_week`                    | array                                                                                    | false    |              | Days of week is a list of days of the week in which autostart is allowed to happen. If no days are specified, autostart is not allowed.                                    |
| `» autostop_requirement`             | [codersdk.TemplateAutostopRequirement](schemas.md#codersdktemplateautostoprequirement)   | false    |              | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature. |
|`»» days_of_week`|array|false||Days of week is a list of days of the week on which restarts are required. Restarts happen within the user's quiet hours (in their configured timezone). If no days are specified, restarts are not required. Weekdays cannot be specified twice.
Restarts will only happen on weekdays in this list on weeks which line up with Weeks.|
|`»» weeks`|integer|false||Weeks is the number of weeks between required restarts. Weeks are synced across all workspaces (and Coder deployments) using modulo math on a hardcoded epoch week of January 2nd, 2023 (the first Monday of 2023). Values of 0 or 1 indicate weekly restarts. Values of 2 indicate fortnightly restarts, etc.|
|`» build_time_stats`|[codersdk.TemplateBuildTimeStats](schemas.md#codersdktemplatebuildtimestats)|false|||
|`»» [any property]`|[codersdk.TransitionStats](schemas.md#codersdktransitionstats)|false|||
|`»»» p50`|integer|false|||
|`»»» p95`|integer|false|||
|`» cors_behavior`|[codersdk.CORSBehavior](schemas.md#codersdkcorsbehavior)|false|||
|`» created_at`|string(date-time)|false|||
|`» created_by_id`|string(uuid)|false|||
|`» created_by_name`|string|false|||
|`» default_ttl_ms`|integer|false|||
|`» deleted`|boolean|false|||
|`» deprecated`|boolean|false|||
|`» deprecation_message`|string|false|||
|`» description`|string|false|||
|`» disable_module_cache`|boolean|false||Disable module cache disables the use of cached Terraform modules during provisioning.|
|`» display_name`|string|false|||
|`» failure_ttl_ms`|integer|false||Failure ttl ms TimeTilDormantMillis, and TimeTilDormantAutoDeleteMillis are enterprise-only. Their values are used if your license is entitled to use the advanced template scheduling feature.|
|`» icon`|string|false|||
|`» id`|string(uuid)|false|||
|`» max_port_share_level`|[codersdk.WorkspaceAgentPortShareLevel](schemas.md#codersdkworkspaceagentportsharelevel)|false|||
|`» name`|string|false|||
|`» organization_display_name`|string|false|||
|`» organization_icon`|string|false|||
|`» organization_id`|string(uuid)|false|||
|`» organization_name`|string(url)|false|||
|`» provisioner`|string|false|||
|`» require_active_version`|boolean|false||Require active version mandates that workspaces are built with the active template version.|
|`» time_til_dormant_autodelete_ms`|integer|false|||
|`» time_til_dormant_ms`|integer|false|||
|`» updated_at`|string(date-time)|false|||
|`» use_classic_parameter_flow`|boolean|false|||

#### Enumerated Values

| Property               | Value(s)                                           |
|------------------------|----------------------------------------------------|
| `cors_behavior`        | `passthru`, `simple`                               |
| `max_port_share_level` | `authenticated`, `organization`, `owner`, `public` |
| `provisioner`          | `terraform`                                        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template examples

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates/examples \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates/examples`

### Example responses

> 200 Response

```json
[
  {
    "description": "string",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "markdown": "string",
    "name": "string",
    "tags": [
      "string"
    ],
    "url": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                  |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.TemplateExample](schemas.md#codersdktemplateexample) |

<h3 id="get-template-examples-responseschema">Response Schema</h3>

Status Code **200**

| Name            | Type         | Required | Restrictions | Description |
|-----------------|--------------|----------|--------------|-------------|
| `[array item]`  | array        | false    |              |             |
| `» description` | string       | false    |              |             |
| `» icon`        | string       | false    |              |             |
| `» id`          | string(uuid) | false    |              |             |
| `» markdown`    | string       | false    |              |             |
| `» name`        | string       | false    |              |             |
| `» tags`        | array        | false    |              |             |
| `» url`         | string       | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template settings by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates/{template} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates/{template}`

### Parameters

| Name       | In   | Type         | Required | Description |
|------------|------|--------------|----------|-------------|
| `template` | path | string(uuid) | true     | Template ID |

### Example responses

> 200 Response

```json
{
  "active_user_count": 0,
  "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc",
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "build_time_stats": {
    "property1": {
      "p50": 123,
      "p95": 146
    },
    "property2": {
      "p50": 123,
      "p95": 146
    }
  },
  "cors_behavior": "simple",
  "created_at": "2019-08-24T14:15:22Z",
  "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f",
  "created_by_name": "string",
  "default_ttl_ms": 0,
  "deleted": true,
  "deprecated": true,
  "deprecation_message": "string",
  "description": "string",
  "disable_module_cache": true,
  "display_name": "string",
  "failure_ttl_ms": 0,
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "max_port_share_level": "owner",
  "name": "string",
  "organization_display_name": "string",
  "organization_icon": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "provisioner": "terraform",
  "require_active_version": true,
  "time_til_dormant_autodelete_ms": 0,
  "time_til_dormant_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z",
  "use_classic_parameter_flow": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Template](schemas.md#codersdktemplate) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete template by ID

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/templates/{template} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/templates/{template}`

### Parameters

| Name       | In   | Type         | Required | Description |
|------------|------|--------------|----------|-------------|
| `template` | path | string(uuid) | true     | Template ID |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update template settings by ID

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/templates/{template} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/templates/{template}`

> Body parameter

```json
{
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "cors_behavior": "simple",
  "default_ttl_ms": 0,
  "deprecation_message": "string",
  "description": "string",
  "disable_everyone_group_access": true,
  "disable_module_cache": true,
  "display_name": "string",
  "failure_ttl_ms": 0,
  "icon": "string",
  "max_port_share_level": "owner",
  "name": "string",
  "require_active_version": true,
  "time_til_dormant_autodelete_ms": 0,
  "time_til_dormant_ms": 0,
  "update_workspace_dormant_at": true,
  "update_workspace_last_used_at": true,
  "use_classic_parameter_flow": true
}
```

### Parameters

| Name       | In   | Type                                                                 | Required | Description                     |
|------------|------|----------------------------------------------------------------------|----------|---------------------------------|
| `template` | path | string(uuid)                                                         | true     | Template ID                     |
| `body`     | body | [codersdk.UpdateTemplateMeta](schemas.md#codersdkupdatetemplatemeta) | true     | Patch template settings request |

### Example responses

> 200 Response

```json
{
  "active_user_count": 0,
  "active_version_id": "eae64611-bd53-4a80-bb77-df1e432c0fbc",
  "activity_bump_ms": 0,
  "allow_user_autostart": true,
  "allow_user_autostop": true,
  "allow_user_cancel_workspace_jobs": true,
  "autostart_requirement": {
    "days_of_week": [
      "monday"
    ]
  },
  "autostop_requirement": {
    "days_of_week": [
      "monday"
    ],
    "weeks": 0
  },
  "build_time_stats": {
    "property1": {
      "p50": 123,
      "p95": 146
    },
    "property2": {
      "p50": 123,
      "p95": 146
    }
  },
  "cors_behavior": "simple",
  "created_at": "2019-08-24T14:15:22Z",
  "created_by_id": "9377d689-01fb-4abf-8450-3368d2c1924f",
  "created_by_name": "string",
  "default_ttl_ms": 0,
  "deleted": true,
  "deprecated": true,
  "deprecation_message": "string",
  "description": "string",
  "disable_module_cache": true,
  "display_name": "string",
  "failure_ttl_ms": 0,
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "max_port_share_level": "owner",
  "name": "string",
  "organization_display_name": "string",
  "organization_icon": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "provisioner": "terraform",
  "require_active_version": true,
  "time_til_dormant_autodelete_ms": 0,
  "time_til_dormant_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z",
  "use_classic_parameter_flow": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Template](schemas.md#codersdktemplate) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template DAUs by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates/{template}/daus \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates/{template}/daus`

### Parameters

| Name       | In   | Type         | Required | Description |
|------------|------|--------------|----------|-------------|
| `template` | path | string(uuid) | true     | Template ID |

### Example responses

> 200 Response

```json
{
  "entries": [
    {
      "amount": 0,
      "date": "string"
    }
  ],
  "tz_hour_offset": 0
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.DAUsResponse](schemas.md#codersdkdausresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List template versions by template ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates/{template}/versions`

### Parameters

| Name               | In    | Type         | Required | Description                           |
|--------------------|-------|--------------|----------|---------------------------------------|
| `template`         | path  | string(uuid) | true     | Template ID                           |
| `after_id`         | query | string(uuid) | false    | After ID                              |
| `include_archived` | query | boolean      | false    | Include archived versions in the list |
| `limit`            | query | integer      | false    | Page limit                            |
| `offset`           | query | integer      | false    | Page offset                           |

### Example responses

> 200 Response

```json
[
  {
    "archived": true,
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": {
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "username": "string"
    },
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "message": "string",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "readme": "string",
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "updated_at": "2019-08-24T14:15:22Z",
    "warnings": [
      "UNSUPPORTED_WORKSPACES"
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                  |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |

<h3 id="list-template-versions-by-template-id-responseschema">Response Schema</h3>

Status Code **200**

| Name                             | Type                                                                         | Required | Restrictions | Description                                                                                                                                                         |
|----------------------------------|------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                   | array                                                                        | false    |              |                                                                                                                                                                     |
| `» archived`                     | boolean                                                                      | false    |              |                                                                                                                                                                     |
| `» created_at`                   | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `» created_by`                   | [codersdk.MinimalUser](schemas.md#codersdkminimaluser)                       | false    |              |                                                                                                                                                                     |
| `»» avatar_url`                  | string(uri)                                                                  | false    |              |                                                                                                                                                                     |
| `»» id`                          | string(uuid)                                                                 | true     |              |                                                                                                                                                                     |
| `»» name`                        | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» username`                    | string                                                                       | true     |              |                                                                                                                                                                     |
| `» has_external_agent`           | boolean                                                                      | false    |              |                                                                                                                                                                     |
| `» id`                           | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `» job`                          | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob)                 | false    |              |                                                                                                                                                                     |
| `»» available_workers`           | array                                                                        | false    |              |                                                                                                                                                                     |
| `»» canceled_at`                 | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» completed_at`                | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» created_at`                  | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» error`                       | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» error_code`                  | [codersdk.JobErrorCode](schemas.md#codersdkjoberrorcode)                     | false    |              |                                                                                                                                                                     |
| `»» file_id`                     | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» id`                          | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» initiator_id`                | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» input`                       | [codersdk.ProvisionerJobInput](schemas.md#codersdkprovisionerjobinput)       | false    |              |                                                                                                                                                                     |
| `»»» error`                      | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_version_id`        | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»»» workspace_build_id`         | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» logs_overflowed`             | boolean                                                                      | false    |              |                                                                                                                                                                     |
| `»» metadata`                    | [codersdk.ProvisionerJobMetadata](schemas.md#codersdkprovisionerjobmetadata) | false    |              |                                                                                                                                                                     |
| `»»» template_display_name`      | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_icon`              | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_id`                | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»»» template_name`              | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_version_name`      | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» workspace_build_transition` | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)       | false    |              |                                                                                                                                                                     |
| `»»» workspace_id`               | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»»» workspace_name`             | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» organization_id`             | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» queue_position`              | integer                                                                      | false    |              |                                                                                                                                                                     |
| `»» queue_size`                  | integer                                                                      | false    |              |                                                                                                                                                                     |
| `»» started_at`                  | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» status`                      | [codersdk.ProvisionerJobStatus](schemas.md#codersdkprovisionerjobstatus)     | false    |              |                                                                                                                                                                     |
| `»» tags`                        | object                                                                       | false    |              |                                                                                                                                                                     |
| `»»» [any property]`             | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» type`                        | [codersdk.ProvisionerJobType](schemas.md#codersdkprovisionerjobtype)         | false    |              |                                                                                                                                                                     |
| `»» worker_id`                   | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» worker_name`                 | string                                                                       | false    |              |                                                                                                                                                                     |
| `» matched_provisioners`         | [codersdk.MatchedProvisioners](schemas.md#codersdkmatchedprovisioners)       | false    |              |                                                                                                                                                                     |
| `»» available`                   | integer                                                                      | false    |              | Available is the number of provisioner daemons that are available to take jobs. This may be less than the count if some provisioners are busy or have been stopped. |
| `»» count`                       | integer                                                                      | false    |              | Count is the number of provisioner daemons that matched the given tags. If the count is 0, it means no provisioner daemons matched the requested tags.              |
| `»» most_recently_seen`          | string(date-time)                                                            | false    |              | Most recently seen is the most recently seen time of the set of matched provisioners. If no provisioners matched, this field will be null.                          |
| `» message`                      | string                                                                       | false    |              |                                                                                                                                                                     |
| `» name`                         | string                                                                       | false    |              |                                                                                                                                                                     |
| `» organization_id`              | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `» readme`                       | string                                                                       | false    |              |                                                                                                                                                                     |
| `» template_id`                  | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `» updated_at`                   | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `» warnings`                     | array                                                                        | false    |              |                                                                                                                                                                     |

#### Enumerated Values

| Property                     | Value(s)                                                                 |
|------------------------------|--------------------------------------------------------------------------|
| `error_code`                 | `INSUFFICIENT_QUOTA`, `REQUIRED_TEMPLATE_VARIABLES`                      |
| `workspace_build_transition` | `delete`, `start`, `stop`                                                |
| `status`                     | `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded`     |
| `type`                       | `template_version_dry_run`, `template_version_import`, `workspace_build` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update active template version by template ID

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/templates/{template}/versions \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/templates/{template}/versions`

> Body parameter

```json
{
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}
```

### Parameters

| Name       | In   | Type                                                                                   | Required | Description               |
|------------|------|----------------------------------------------------------------------------------------|----------|---------------------------|
| `template` | path | string(uuid)                                                                           | true     | Template ID               |
| `body`     | body | [codersdk.UpdateActiveTemplateVersion](schemas.md#codersdkupdateactivetemplateversion) | true     | Modified template version |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Archive template unused versions by template id

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/templates/{template}/versions/archive \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/templates/{template}/versions/archive`

> Body parameter

```json
{
  "all": true
}
```

### Parameters

| Name       | In   | Type                                                                                         | Required | Description     |
|------------|------|----------------------------------------------------------------------------------------------|----------|-----------------|
| `template` | path | string(uuid)                                                                                 | true     | Template ID     |
| `body`     | body | [codersdk.ArchiveTemplateVersionsRequest](schemas.md#codersdkarchivetemplateversionsrequest) | true     | Archive request |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version by template ID and name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions/{templateversionname} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templates/{template}/versions/{templateversionname}`

### Parameters

| Name                  | In   | Type         | Required | Description           |
|-----------------------|------|--------------|----------|-----------------------|
| `template`            | path | string(uuid) | true     | Template ID           |
| `templateversionname` | path | string       | true     | Template version name |

### Example responses

> 200 Response

```json
[
  {
    "archived": true,
    "created_at": "2019-08-24T14:15:22Z",
    "created_by": {
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "username": "string"
    },
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "message": "string",
    "name": "string",
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "readme": "string",
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "updated_at": "2019-08-24T14:15:22Z",
    "warnings": [
      "UNSUPPORTED_WORKSPACES"
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                  |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |

<h3 id="get-template-version-by-template-id-and-name-responseschema">Response Schema</h3>

Status Code **200**

| Name                             | Type                                                                         | Required | Restrictions | Description                                                                                                                                                         |
|----------------------------------|------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                   | array                                                                        | false    |              |                                                                                                                                                                     |
| `» archived`                     | boolean                                                                      | false    |              |                                                                                                                                                                     |
| `» created_at`                   | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `» created_by`                   | [codersdk.MinimalUser](schemas.md#codersdkminimaluser)                       | false    |              |                                                                                                                                                                     |
| `»» avatar_url`                  | string(uri)                                                                  | false    |              |                                                                                                                                                                     |
| `»» id`                          | string(uuid)                                                                 | true     |              |                                                                                                                                                                     |
| `»» name`                        | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» username`                    | string                                                                       | true     |              |                                                                                                                                                                     |
| `» has_external_agent`           | boolean                                                                      | false    |              |                                                                                                                                                                     |
| `» id`                           | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `» job`                          | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob)                 | false    |              |                                                                                                                                                                     |
| `»» available_workers`           | array                                                                        | false    |              |                                                                                                                                                                     |
| `»» canceled_at`                 | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» completed_at`                | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» created_at`                  | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» error`                       | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» error_code`                  | [codersdk.JobErrorCode](schemas.md#codersdkjoberrorcode)                     | false    |              |                                                                                                                                                                     |
| `»» file_id`                     | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» id`                          | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» initiator_id`                | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» input`                       | [codersdk.ProvisionerJobInput](schemas.md#codersdkprovisionerjobinput)       | false    |              |                                                                                                                                                                     |
| `»»» error`                      | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_version_id`        | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»»» workspace_build_id`         | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» logs_overflowed`             | boolean                                                                      | false    |              |                                                                                                                                                                     |
| `»» metadata`                    | [codersdk.ProvisionerJobMetadata](schemas.md#codersdkprovisionerjobmetadata) | false    |              |                                                                                                                                                                     |
| `»»» template_display_name`      | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_icon`              | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_id`                | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»»» template_name`              | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» template_version_name`      | string                                                                       | false    |              |                                                                                                                                                                     |
| `»»» workspace_build_transition` | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)       | false    |              |                                                                                                                                                                     |
| `»»» workspace_id`               | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»»» workspace_name`             | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» organization_id`             | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» queue_position`              | integer                                                                      | false    |              |                                                                                                                                                                     |
| `»» queue_size`                  | integer                                                                      | false    |              |                                                                                                                                                                     |
| `»» started_at`                  | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `»» status`                      | [codersdk.ProvisionerJobStatus](schemas.md#codersdkprovisionerjobstatus)     | false    |              |                                                                                                                                                                     |
| `»» tags`                        | object                                                                       | false    |              |                                                                                                                                                                     |
| `»»» [any property]`             | string                                                                       | false    |              |                                                                                                                                                                     |
| `»» type`                        | [codersdk.ProvisionerJobType](schemas.md#codersdkprovisionerjobtype)         | false    |              |                                                                                                                                                                     |
| `»» worker_id`                   | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `»» worker_name`                 | string                                                                       | false    |              |                                                                                                                                                                     |
| `» matched_provisioners`         | [codersdk.MatchedProvisioners](schemas.md#codersdkmatchedprovisioners)       | false    |              |                                                                                                                                                                     |
| `»» available`                   | integer                                                                      | false    |              | Available is the number of provisioner daemons that are available to take jobs. This may be less than the count if some provisioners are busy or have been stopped. |
| `»» count`                       | integer                                                                      | false    |              | Count is the number of provisioner daemons that matched the given tags. If the count is 0, it means no provisioner daemons matched the requested tags.              |
| `»» most_recently_seen`          | string(date-time)                                                            | false    |              | Most recently seen is the most recently seen time of the set of matched provisioners. If no provisioners matched, this field will be null.                          |
| `» message`                      | string                                                                       | false    |              |                                                                                                                                                                     |
| `» name`                         | string                                                                       | false    |              |                                                                                                                                                                     |
| `» organization_id`              | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `» readme`                       | string                                                                       | false    |              |                                                                                                                                                                     |
| `» template_id`                  | string(uuid)                                                                 | false    |              |                                                                                                                                                                     |
| `» updated_at`                   | string(date-time)                                                            | false    |              |                                                                                                                                                                     |
| `» warnings`                     | array                                                                        | false    |              |                                                                                                                                                                     |

#### Enumerated Values

| Property                     | Value(s)                                                                 |
|------------------------------|--------------------------------------------------------------------------|
| `error_code`                 | `INSUFFICIENT_QUOTA`, `REQUIRED_TEMPLATE_VARIABLES`                      |
| `workspace_build_transition` | `delete`, `start`, `stop`                                                |
| `status`                     | `canceled`, `canceling`, `failed`, `pending`, `running`, `succeeded`     |
| `type`                       | `template_version_dry_run`, `template_version_import`, `workspace_build` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
{
  "archived": true,
  "created_at": "2019-08-24T14:15:22Z",
  "created_by": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "message": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "readme": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "UNSUPPORTED_WORKSPACES"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Patch template version by ID

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/templateversions/{templateversion}`

> Body parameter

```json
{
  "message": "string",
  "name": "string"
}
```

### Parameters

| Name              | In   | Type                                                                                   | Required | Description                    |
|-------------------|------|----------------------------------------------------------------------------------------|----------|--------------------------------|
| `templateversion` | path | string(uuid)                                                                           | true     | Template version ID            |
| `body`            | body | [codersdk.PatchTemplateVersionRequest](schemas.md#codersdkpatchtemplateversionrequest) | true     | Patch template version request |

### Example responses

> 200 Response

```json
{
  "archived": true,
  "created_at": "2019-08-24T14:15:22Z",
  "created_by": {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  },
  "has_external_agent": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "job": {
    "available_workers": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "canceled_at": "2019-08-24T14:15:22Z",
    "completed_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "error": "string",
    "error_code": "REQUIRED_TEMPLATE_VARIABLES",
    "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "input": {
      "error": "string",
      "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
      "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
    },
    "logs_overflowed": true,
    "metadata": {
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_version_name": "string",
      "workspace_build_transition": "start",
      "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
      "workspace_name": "string"
    },
    "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
    "queue_position": 0,
    "queue_size": 0,
    "started_at": "2019-08-24T14:15:22Z",
    "status": "pending",
    "tags": {
      "property1": "string",
      "property2": "string"
    },
    "type": "template_version_import",
    "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
    "worker_name": "string"
  },
  "matched_provisioners": {
    "available": 0,
    "count": 0,
    "most_recently_seen": "2019-08-24T14:15:22Z"
  },
  "message": "string",
  "name": "string",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "readme": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "updated_at": "2019-08-24T14:15:22Z",
  "warnings": [
    "UNSUPPORTED_WORKSPACES"
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.TemplateVersion](schemas.md#codersdktemplateversion) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Archive template version

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/archive \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/templateversions/{templateversion}/archive`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Cancel template version by ID

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion}/cancel \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/templateversions/{templateversion}/cancel`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create template version dry-run

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/templateversions/{templateversion}/dry-run`

> Body parameter

```json
{
  "rich_parameter_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "user_variable_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "workspace_name": "string"
}
```

### Parameters

| Name              | In   | Type                                                                                                 | Required | Description         |
|-------------------|------|------------------------------------------------------------------------------------------------------|----------|---------------------|
| `templateversion` | path | string(uuid)                                                                                         | true     | Template version ID |
| `body`            | body | [codersdk.CreateTemplateVersionDryRunRequest](schemas.md#codersdkcreatetemplateversiondryrunrequest) | true     | Dry-run request     |

### Example responses

> 201 Response

```json
{
  "available_workers": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "canceled_at": "2019-08-24T14:15:22Z",
  "completed_at": "2019-08-24T14:15:22Z",
  "created_at": "2019-08-24T14:15:22Z",
  "error": "string",
  "error_code": "REQUIRED_TEMPLATE_VARIABLES",
  "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "input": {
    "error": "string",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
  },
  "logs_overflowed": true,
  "metadata": {
    "template_display_name": "string",
    "template_icon": "string",
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "template_name": "string",
    "template_version_name": "string",
    "workspace_build_transition": "start",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string"
  },
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "queue_position": 0,
  "queue_size": 0,
  "started_at": "2019-08-24T14:15:22Z",
  "status": "pending",
  "tags": {
    "property1": "string",
    "property2": "string"
  },
  "type": "template_version_import",
  "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
  "worker_name": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                       |
|--------|--------------------------------------------------------------|-------------|--------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version dry-run by job ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/dry-run/{jobID}`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |
| `jobID`           | path | string(uuid) | true     | Job ID              |

### Example responses

> 200 Response

```json
{
  "available_workers": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "canceled_at": "2019-08-24T14:15:22Z",
  "completed_at": "2019-08-24T14:15:22Z",
  "created_at": "2019-08-24T14:15:22Z",
  "error": "string",
  "error_code": "REQUIRED_TEMPLATE_VARIABLES",
  "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
  "input": {
    "error": "string",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
  },
  "logs_overflowed": true,
  "metadata": {
    "template_display_name": "string",
    "template_icon": "string",
    "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
    "template_name": "string",
    "template_version_name": "string",
    "workspace_build_transition": "start",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string"
  },
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "queue_position": 0,
  "queue_size": 0,
  "started_at": "2019-08-24T14:15:22Z",
  "status": "pending",
  "tags": {
    "property1": "string",
    "property2": "string"
  },
  "type": "template_version_import",
  "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
  "worker_name": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                       |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ProvisionerJob](schemas.md#codersdkprovisionerjob) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Cancel template version dry-run by job ID

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID}/cancel \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/templateversions/{templateversion}/dry-run/{jobID}/cancel`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `jobID`           | path | string(uuid) | true     | Job ID              |
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version dry-run logs by job ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID}/logs \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/dry-run/{jobID}/logs`

### Parameters

| Name              | In    | Type         | Required | Description                                                                                                                                 |
|-------------------|-------|--------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `templateversion` | path  | string(uuid) | true     | Template version ID                                                                                                                         |
| `jobID`           | path  | string(uuid) | true     | Job ID                                                                                                                                      |
| `before`          | query | integer      | false    | Before Unix timestamp                                                                                                                       |
| `after`           | query | integer      | false    | After Unix timestamp                                                                                                                        |
| `follow`          | query | boolean      | false    | Follow log stream                                                                                                                           |
| `format`          | query | string       | false    | Log output format. Accepted: 'json' (default), 'text' (plain text with RFC3339 timestamps and ANSI colors). Not supported with follow=true. |

#### Enumerated Values

| Parameter | Value(s)       |
|-----------|----------------|
| `format`  | `json`, `text` |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "id": 0,
    "log_level": "trace",
    "log_source": "provisioner_daemon",
    "output": "string",
    "stage": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) |

<h3 id="get-template-version-dry-run-logs-by-job-id-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type                                               | Required | Restrictions | Description |
|----------------|----------------------------------------------------|----------|--------------|-------------|
| `[array item]` | array                                              | false    |              |             |
| `» created_at` | string(date-time)                                  | false    |              |             |
| `» id`         | integer                                            | false    |              |             |
| `» log_level`  | [codersdk.LogLevel](schemas.md#codersdkloglevel)   | false    |              |             |
| `» log_source` | [codersdk.LogSource](schemas.md#codersdklogsource) | false    |              |             |
| `» output`     | string                                             | false    |              |             |
| `» stage`      | string                                             | false    |              |             |

#### Enumerated Values

| Property     | Value(s)                                  |
|--------------|-------------------------------------------|
| `log_level`  | `debug`, `error`, `info`, `trace`, `warn` |
| `log_source` | `provisioner`, `provisioner_daemon`       |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version dry-run matched provisioners

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID}/matched-provisioners \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/dry-run/{jobID}/matched-provisioners`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |
| `jobID`           | path | string(uuid) | true     | Job ID              |

### Example responses

> 200 Response

```json
{
  "available": 0,
  "count": 0,
  "most_recently_seen": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                 |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.MatchedProvisioners](schemas.md#codersdkmatchedprovisioners) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version dry-run resources by job ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dry-run/{jobID}/resources \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/dry-run/{jobID}/resources`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |
| `jobID`           | path | string(uuid) | true     | Job ID              |

### Example responses

> 200 Response

```json
[
  {
    "agents": [
      {
        "api_version": "string",
        "apps": [
          {
            "command": "string",
            "display_name": "string",
            "external": true,
            "group": "string",
            "health": "disabled",
            "healthcheck": {
              "interval": 0,
              "threshold": 0,
              "url": "string"
            },
            "hidden": true,
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "open_in": "slim-window",
            "sharing_level": "owner",
            "slug": "string",
            "statuses": [
              {
                "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                "created_at": "2019-08-24T14:15:22Z",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "message": "string",
                "needs_user_attention": true,
                "state": "working",
                "uri": "string",
                "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
              }
            ],
            "subdomain": true,
            "subdomain_name": "string",
            "tooltip": "string",
            "url": "string"
          }
        ],
        "architecture": "string",
        "connection_timeout_seconds": 0,
        "created_at": "2019-08-24T14:15:22Z",
        "directory": "string",
        "disconnected_at": "2019-08-24T14:15:22Z",
        "display_apps": [
          "vscode"
        ],
        "environment_variables": {
          "property1": "string",
          "property2": "string"
        },
        "expanded_directory": "string",
        "first_connected_at": "2019-08-24T14:15:22Z",
        "health": {
          "healthy": false,
          "reason": "agent has lost connection"
        },
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "instance_id": "string",
        "last_connected_at": "2019-08-24T14:15:22Z",
        "latency": {
          "property1": {
            "latency_ms": 0,
            "preferred": true
          },
          "property2": {
            "latency_ms": 0,
            "preferred": true
          }
        },
        "lifecycle_state": "created",
        "log_sources": [
          {
            "created_at": "2019-08-24T14:15:22Z",
            "display_name": "string",
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
          }
        ],
        "logs_length": 0,
        "logs_overflowed": true,
        "name": "string",
        "operating_system": "string",
        "parent_id": {
          "uuid": "string",
          "valid": true
        },
        "ready_at": "2019-08-24T14:15:22Z",
        "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
        "scripts": [
          {
            "cron": "string",
            "display_name": "string",
            "exit_code": 0,
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "log_path": "string",
            "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
            "run_on_start": true,
            "run_on_stop": true,
            "script": "string",
            "start_blocks_login": true,
            "status": "ok",
            "timeout": 0
          }
        ],
        "started_at": "2019-08-24T14:15:22Z",
        "startup_script_behavior": "blocking",
        "status": "connecting",
        "subsystems": [
          "envbox"
        ],
        "troubleshooting_url": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "version": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "hide": true,
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
    "metadata": [
      {
        "key": "string",
        "sensitive": true,
        "value": "string"
      }
    ],
    "name": "string",
    "type": "string",
    "workspace_transition": "start"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) |

<h3 id="get-template-version-dry-run-resources-by-job-id-responseschema">Response Schema</h3>

Status Code **200**

| Name                            | Type                                                                                                   | Required | Restrictions | Description                                                                                                                                                                                                                                    |
|---------------------------------|--------------------------------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                  | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `» agents`                      | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» api_version`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» apps`                       | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» command`                   | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              | Display name is a friendly name for the app.                                                                                                                                                                                                   |
| `»»» external`                  | boolean                                                                                                | false    |              | External specifies whether the URL should be opened externally on the client or not.                                                                                                                                                           |
| `»»» group`                     | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» health`                    | [codersdk.WorkspaceAppHealth](schemas.md#codersdkworkspaceapphealth)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» healthcheck`               | [codersdk.Healthcheck](schemas.md#codersdkhealthcheck)                                                 | false    |              | Healthcheck specifies the configuration for checking app health.                                                                                                                                                                               |
| `»»»» interval`                 | integer                                                                                                | false    |              | Interval specifies the seconds between each health check.                                                                                                                                                                                      |
| `»»»» threshold`                | integer                                                                                                | false    |              | Threshold specifies the number of consecutive failed health checks before returning "unhealthy".                                                                                                                                               |
| `»»»» url`                      | string                                                                                                 | false    |              | URL specifies the endpoint to check for the app health.                                                                                                                                                                                        |
| `»»» hidden`                    | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» icon`                      | string                                                                                                 | false    |              | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard.                                                                                                                                               |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» open_in`                   | [codersdk.WorkspaceAppOpenIn](schemas.md#codersdkworkspaceappopenin)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» sharing_level`             | [codersdk.WorkspaceAppSharingLevel](schemas.md#codersdkworkspaceappsharinglevel)                       | false    |              |                                                                                                                                                                                                                                                |
| `»»» slug`                      | string                                                                                                 | false    |              | Slug is a unique identifier within the agent.                                                                                                                                                                                                  |
| `»»» statuses`                  | array                                                                                                  | false    |              | Statuses is a list of statuses for the app.                                                                                                                                                                                                    |
| `»»»» agent_id`                 | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» app_id`                   | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» created_at`               | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»»» icon`                     | string                                                                                                 | false    |              | Deprecated: This field is unused and will be removed in a future version. Icon is an external URL to an icon that will be rendered in the UI.                                                                                                  |
| `»»»» id`                       | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» message`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» needs_user_attention`     | boolean                                                                                                | false    |              | Deprecated: This field is unused and will be removed in a future version. NeedsUserAttention specifies whether the status needs user attention.                                                                                                |
| `»»»» state`                    | [codersdk.WorkspaceAppStatusState](schemas.md#codersdkworkspaceappstatusstate)                         | false    |              |                                                                                                                                                                                                                                                |
| `»»»» uri`                      | string                                                                                                 | false    |              | Uri is the URI of the resource that the status is for. e.g. https://github.com/org/repo/pull/123 e.g. file:///path/to/file                                                                                                                     |
| `»»»» workspace_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» subdomain`                 | boolean                                                                                                | false    |              | Subdomain denotes whether the app should be accessed via a path on the `coder server` or via a hostname-based dev URL. If this is set to true and there is no app wildcard configured on the server, the app will not be accessible in the UI. |
| `»»» subdomain_name`            | string                                                                                                 | false    |              | Subdomain name is the application domain exposed on the `coder server`.                                                                                                                                                                        |
| `»»» tooltip`                   | string                                                                                                 | false    |              | Tooltip is an optional markdown supported field that is displayed when hovering over workspace apps in the UI.                                                                                                                                 |
| `»»» url`                       | string                                                                                                 | false    |              | URL is the address being proxied to inside the workspace. If external is specified, this will be opened on the client.                                                                                                                         |
| `»» architecture`               | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» connection_timeout_seconds` | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» created_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» directory`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» disconnected_at`            | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» display_apps`               | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» environment_variables`      | object                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» [any property]`            | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» expanded_directory`         | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» first_connected_at`         | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» health`                     | [codersdk.WorkspaceAgentHealth](schemas.md#codersdkworkspaceagenthealth)                               | false    |              | Health reports the health of the agent.                                                                                                                                                                                                        |
| `»»» healthy`                   | boolean                                                                                                | false    |              | Healthy is true if the agent is healthy.                                                                                                                                                                                                       |
| `»»» reason`                    | string                                                                                                 | false    |              | Reason is a human-readable explanation of the agent's health. It is empty if Healthy is true.                                                                                                                                                  |
| `»» id`                         | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» instance_id`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» last_connected_at`          | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» latency`                    | object                                                                                                 | false    |              | Latency is mapped by region name (e.g. "New York City", "Seattle").                                                                                                                                                                            |
| `»»» [any property]`            | [codersdk.DERPRegion](schemas.md#codersdkderpregion)                                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»»» latency_ms`               | number                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» preferred`                | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» lifecycle_state`            | [codersdk.WorkspaceAgentLifecycle](schemas.md#codersdkworkspaceagentlifecycle)                         | false    |              |                                                                                                                                                                                                                                                |
| `»» log_sources`                | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» created_at`                | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» icon`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» workspace_agent_id`        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» logs_length`                | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» logs_overflowed`            | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» name`                       | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» operating_system`           | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» parent_id`                  | [uuid.NullUUID](schemas.md#uuidnulluuid)                                                               | false    |              |                                                                                                                                                                                                                                                |
| `»»» uuid`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» valid`                     | boolean                                                                                                | false    |              | Valid is true if UUID is not NULL                                                                                                                                                                                                              |
| `»» ready_at`                   | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» resource_id`                | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» scripts`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» cron`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» exit_code`                 | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» log_path`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» log_source_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» run_on_start`              | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» run_on_stop`               | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» script`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» start_blocks_login`        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» status`                    | [codersdk.WorkspaceAgentScriptStatus](schemas.md#codersdkworkspaceagentscriptstatus)                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» timeout`                   | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» started_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» startup_script_behavior`    | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false    |              | Startup script behavior is a legacy field that is deprecated in favor of the `coder_script` resource. It's only referenced by old clients. Deprecated: Remove in the future!                                                                   |
| `»» status`                     | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus)                               | false    |              |                                                                                                                                                                                                                                                |
| `»» subsystems`                 | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» troubleshooting_url`        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» updated_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» version`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» created_at`                  | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `» daily_cost`                  | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» hide`                        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» icon`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» id`                          | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» job_id`                      | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» metadata`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» key`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» sensitive`                  | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» value`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» name`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» type`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_transition`        | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)                                 | false    |              |                                                                                                                                                                                                                                                |

#### Enumerated Values

| Property                  | Value(s)                                                                                                                     |
|---------------------------|------------------------------------------------------------------------------------------------------------------------------|
| `health`                  | `disabled`, `healthy`, `initializing`, `unhealthy`                                                                           |
| `open_in`                 | `slim-window`, `tab`                                                                                                         |
| `sharing_level`           | `authenticated`, `organization`, `owner`, `public`                                                                           |
| `state`                   | `complete`, `failure`, `idle`, `working`                                                                                     |
| `lifecycle_state`         | `created`, `off`, `ready`, `shutdown_error`, `shutdown_timeout`, `shutting_down`, `start_error`, `start_timeout`, `starting` |
| `status`                  | `connected`, `connecting`, `disconnected`, `exit_failure`, `ok`, `pipes_left_open`, `timed_out`, `timeout`                   |
| `startup_script_behavior` | `blocking`, `non-blocking`                                                                                                   |
| `workspace_transition`    | `delete`, `start`, `stop`                                                                                                    |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Open dynamic parameters WebSocket by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/dynamic-parameters \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/dynamic-parameters`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Responses

| Status | Meaning                                                                  | Description         | Schema |
|--------|--------------------------------------------------------------------------|---------------------|--------|
| 101    | [Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) | Switching Protocols |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Evaluate dynamic parameters for template version

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/dynamic-parameters/evaluate \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/templateversions/{templateversion}/dynamic-parameters/evaluate`

> Body parameter

```json
{
  "id": 0,
  "inputs": {
    "property1": "string",
    "property2": "string"
  },
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05"
}
```

### Parameters

| Name              | In   | Type                                                                             | Required | Description              |
|-------------------|------|----------------------------------------------------------------------------------|----------|--------------------------|
| `templateversion` | path | string(uuid)                                                                     | true     | Template version ID      |
| `body`            | body | [codersdk.DynamicParametersRequest](schemas.md#codersdkdynamicparametersrequest) | true     | Initial parameter values |

### Example responses

> 200 Response

```json
{
  "diagnostics": [
    {
      "detail": "string",
      "extra": {
        "code": "string"
      },
      "severity": "error",
      "summary": "string"
    }
  ],
  "id": 0,
  "parameters": [
    {
      "default_value": {
        "valid": true,
        "value": "string"
      },
      "description": "string",
      "diagnostics": [
        {
          "detail": "string",
          "extra": {
            "code": "string"
          },
          "severity": "error",
          "summary": "string"
        }
      ],
      "display_name": "string",
      "ephemeral": true,
      "form_type": "",
      "icon": "string",
      "mutable": true,
      "name": "string",
      "options": [
        {
          "description": "string",
          "icon": "string",
          "name": "string",
          "value": {
            "valid": true,
            "value": "string"
          }
        }
      ],
      "order": 0,
      "required": true,
      "styling": {
        "disabled": true,
        "label": "string",
        "mask_input": true,
        "placeholder": "string"
      },
      "type": "string",
      "validations": [
        {
          "validation_error": "string",
          "validation_max": 0,
          "validation_min": 0,
          "validation_monotonic": "string",
          "validation_regex": "string"
        }
      ],
      "value": {
        "valid": true,
        "value": "string"
      }
    }
  ],
  "secret_requirements": [
    {
      "env": "string",
      "file": "string",
      "help_message": "string",
      "satisfied": true
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                             |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.DynamicParametersResponse](schemas.md#codersdkdynamicparametersresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get external auth by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/external-auth \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/external-auth`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
[
  {
    "authenticate_url": "string",
    "authenticated": true,
    "display_icon": "string",
    "display_name": "string",
    "id": "string",
    "optional": true,
    "type": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                          |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.TemplateVersionExternalAuth](schemas.md#codersdktemplateversionexternalauth) |

<h3 id="get-external-auth-by-template-version-responseschema">Response Schema</h3>

Status Code **200**

| Name                 | Type    | Required | Restrictions | Description |
|----------------------|---------|----------|--------------|-------------|
| `[array item]`       | array   | false    |              |             |
| `» authenticate_url` | string  | false    |              |             |
| `» authenticated`    | boolean | false    |              |             |
| `» display_icon`     | string  | false    |              |             |
| `» display_name`     | string  | false    |              |             |
| `» id`               | string  | false    |              |             |
| `» optional`         | boolean | false    |              |             |
| `» type`             | string  | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get logs by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/logs \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/logs`

### Parameters

| Name              | In    | Type         | Required | Description                                                                                                                                 |
|-------------------|-------|--------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `templateversion` | path  | string(uuid) | true     | Template version ID                                                                                                                         |
| `before`          | query | integer      | false    | Before log id                                                                                                                               |
| `after`           | query | integer      | false    | After log id                                                                                                                                |
| `follow`          | query | boolean      | false    | Follow log stream                                                                                                                           |
| `format`          | query | string       | false    | Log output format. Accepted: 'json' (default), 'text' (plain text with RFC3339 timestamps and ANSI colors). Not supported with follow=true. |

#### Enumerated Values

| Parameter | Value(s)       |
|-----------|----------------|
| `format`  | `json`, `text` |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "id": 0,
    "log_level": "trace",
    "log_source": "provisioner_daemon",
    "output": "string",
    "stage": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.ProvisionerJobLog](schemas.md#codersdkprovisionerjoblog) |

<h3 id="get-logs-by-template-version-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type                                               | Required | Restrictions | Description |
|----------------|----------------------------------------------------|----------|--------------|-------------|
| `[array item]` | array                                              | false    |              |             |
| `» created_at` | string(date-time)                                  | false    |              |             |
| `» id`         | integer                                            | false    |              |             |
| `» log_level`  | [codersdk.LogLevel](schemas.md#codersdkloglevel)   | false    |              |             |
| `» log_source` | [codersdk.LogSource](schemas.md#codersdklogsource) | false    |              |             |
| `» output`     | string                                             | false    |              |             |
| `» stage`      | string                                             | false    |              |             |

#### Enumerated Values

| Property     | Value(s)                                  |
|--------------|-------------------------------------------|
| `log_level`  | `debug`, `error`, `info`, `trace`, `warn` |
| `log_source` | `provisioner`, `provisioner_daemon`       |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Removed: Get parameters by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/parameters \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/parameters`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template version presets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/presets \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/presets`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
[
  {
    "default": true,
    "description": "string",
    "desiredPrebuildInstances": 0,
    "icon": "string",
    "id": "string",
    "name": "string",
    "parameters": [
      {
        "name": "string",
        "value": "string"
      }
    ]
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Preset](schemas.md#codersdkpreset) |

<h3 id="get-template-version-presets-responseschema">Response Schema</h3>

Status Code **200**

| Name                         | Type    | Required | Restrictions | Description |
|------------------------------|---------|----------|--------------|-------------|
| `[array item]`               | array   | false    |              |             |
| `» default`                  | boolean | false    |              |             |
| `» description`              | string  | false    |              |             |
| `» desiredPrebuildInstances` | integer | false    |              |             |
| `» icon`                     | string  | false    |              |             |
| `» id`                       | string  | false    |              |             |
| `» name`                     | string  | false    |              |             |
| `» parameters`               | array   | false    |              |             |
| `»» name`                    | string  | false    |              |             |
| `»» value`                   | string  | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get resources by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/resources \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/resources`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
[
  {
    "agents": [
      {
        "api_version": "string",
        "apps": [
          {
            "command": "string",
            "display_name": "string",
            "external": true,
            "group": "string",
            "health": "disabled",
            "healthcheck": {
              "interval": 0,
              "threshold": 0,
              "url": "string"
            },
            "hidden": true,
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "open_in": "slim-window",
            "sharing_level": "owner",
            "slug": "string",
            "statuses": [
              {
                "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                "created_at": "2019-08-24T14:15:22Z",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "message": "string",
                "needs_user_attention": true,
                "state": "working",
                "uri": "string",
                "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
              }
            ],
            "subdomain": true,
            "subdomain_name": "string",
            "tooltip": "string",
            "url": "string"
          }
        ],
        "architecture": "string",
        "connection_timeout_seconds": 0,
        "created_at": "2019-08-24T14:15:22Z",
        "directory": "string",
        "disconnected_at": "2019-08-24T14:15:22Z",
        "display_apps": [
          "vscode"
        ],
        "environment_variables": {
          "property1": "string",
          "property2": "string"
        },
        "expanded_directory": "string",
        "first_connected_at": "2019-08-24T14:15:22Z",
        "health": {
          "healthy": false,
          "reason": "agent has lost connection"
        },
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "instance_id": "string",
        "last_connected_at": "2019-08-24T14:15:22Z",
        "latency": {
          "property1": {
            "latency_ms": 0,
            "preferred": true
          },
          "property2": {
            "latency_ms": 0,
            "preferred": true
          }
        },
        "lifecycle_state": "created",
        "log_sources": [
          {
            "created_at": "2019-08-24T14:15:22Z",
            "display_name": "string",
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
          }
        ],
        "logs_length": 0,
        "logs_overflowed": true,
        "name": "string",
        "operating_system": "string",
        "parent_id": {
          "uuid": "string",
          "valid": true
        },
        "ready_at": "2019-08-24T14:15:22Z",
        "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
        "scripts": [
          {
            "cron": "string",
            "display_name": "string",
            "exit_code": 0,
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "log_path": "string",
            "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
            "run_on_start": true,
            "run_on_stop": true,
            "script": "string",
            "start_blocks_login": true,
            "status": "ok",
            "timeout": 0
          }
        ],
        "started_at": "2019-08-24T14:15:22Z",
        "startup_script_behavior": "blocking",
        "status": "connecting",
        "subsystems": [
          "envbox"
        ],
        "troubleshooting_url": "string",
        "updated_at": "2019-08-24T14:15:22Z",
        "version": "string"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "hide": true,
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
    "metadata": [
      {
        "key": "string",
        "sensitive": true,
        "value": "string"
      }
    ],
    "name": "string",
    "type": "string",
    "workspace_transition": "start"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                      |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.WorkspaceResource](schemas.md#codersdkworkspaceresource) |

<h3 id="get-resources-by-template-version-responseschema">Response Schema</h3>

Status Code **200**

| Name                            | Type                                                                                                   | Required | Restrictions | Description                                                                                                                                                                                                                                    |
|---------------------------------|--------------------------------------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]`                  | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `» agents`                      | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» api_version`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» apps`                       | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» command`                   | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              | Display name is a friendly name for the app.                                                                                                                                                                                                   |
| `»»» external`                  | boolean                                                                                                | false    |              | External specifies whether the URL should be opened externally on the client or not.                                                                                                                                                           |
| `»»» group`                     | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» health`                    | [codersdk.WorkspaceAppHealth](schemas.md#codersdkworkspaceapphealth)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» healthcheck`               | [codersdk.Healthcheck](schemas.md#codersdkhealthcheck)                                                 | false    |              | Healthcheck specifies the configuration for checking app health.                                                                                                                                                                               |
| `»»»» interval`                 | integer                                                                                                | false    |              | Interval specifies the seconds between each health check.                                                                                                                                                                                      |
| `»»»» threshold`                | integer                                                                                                | false    |              | Threshold specifies the number of consecutive failed health checks before returning "unhealthy".                                                                                                                                               |
| `»»»» url`                      | string                                                                                                 | false    |              | URL specifies the endpoint to check for the app health.                                                                                                                                                                                        |
| `»»» hidden`                    | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» icon`                      | string                                                                                                 | false    |              | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard.                                                                                                                                               |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» open_in`                   | [codersdk.WorkspaceAppOpenIn](schemas.md#codersdkworkspaceappopenin)                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» sharing_level`             | [codersdk.WorkspaceAppSharingLevel](schemas.md#codersdkworkspaceappsharinglevel)                       | false    |              |                                                                                                                                                                                                                                                |
| `»»» slug`                      | string                                                                                                 | false    |              | Slug is a unique identifier within the agent.                                                                                                                                                                                                  |
| `»»» statuses`                  | array                                                                                                  | false    |              | Statuses is a list of statuses for the app.                                                                                                                                                                                                    |
| `»»»» agent_id`                 | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» app_id`                   | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» created_at`               | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»»» icon`                     | string                                                                                                 | false    |              | Deprecated: This field is unused and will be removed in a future version. Icon is an external URL to an icon that will be rendered in the UI.                                                                                                  |
| `»»»» id`                       | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»»» message`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» needs_user_attention`     | boolean                                                                                                | false    |              | Deprecated: This field is unused and will be removed in a future version. NeedsUserAttention specifies whether the status needs user attention.                                                                                                |
| `»»»» state`                    | [codersdk.WorkspaceAppStatusState](schemas.md#codersdkworkspaceappstatusstate)                         | false    |              |                                                                                                                                                                                                                                                |
| `»»»» uri`                      | string                                                                                                 | false    |              | Uri is the URI of the resource that the status is for. e.g. https://github.com/org/repo/pull/123 e.g. file:///path/to/file                                                                                                                     |
| `»»»» workspace_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» subdomain`                 | boolean                                                                                                | false    |              | Subdomain denotes whether the app should be accessed via a path on the `coder server` or via a hostname-based dev URL. If this is set to true and there is no app wildcard configured on the server, the app will not be accessible in the UI. |
| `»»» subdomain_name`            | string                                                                                                 | false    |              | Subdomain name is the application domain exposed on the `coder server`.                                                                                                                                                                        |
| `»»» tooltip`                   | string                                                                                                 | false    |              | Tooltip is an optional markdown supported field that is displayed when hovering over workspace apps in the UI.                                                                                                                                 |
| `»»» url`                       | string                                                                                                 | false    |              | URL is the address being proxied to inside the workspace. If external is specified, this will be opened on the client.                                                                                                                         |
| `»» architecture`               | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» connection_timeout_seconds` | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» created_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» directory`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» disconnected_at`            | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» display_apps`               | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» environment_variables`      | object                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» [any property]`            | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» expanded_directory`         | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» first_connected_at`         | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» health`                     | [codersdk.WorkspaceAgentHealth](schemas.md#codersdkworkspaceagenthealth)                               | false    |              | Health reports the health of the agent.                                                                                                                                                                                                        |
| `»»» healthy`                   | boolean                                                                                                | false    |              | Healthy is true if the agent is healthy.                                                                                                                                                                                                       |
| `»»» reason`                    | string                                                                                                 | false    |              | Reason is a human-readable explanation of the agent's health. It is empty if Healthy is true.                                                                                                                                                  |
| `»» id`                         | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» instance_id`                | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» last_connected_at`          | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» latency`                    | object                                                                                                 | false    |              | Latency is mapped by region name (e.g. "New York City", "Seattle").                                                                                                                                                                            |
| `»»» [any property]`            | [codersdk.DERPRegion](schemas.md#codersdkderpregion)                                                   | false    |              |                                                                                                                                                                                                                                                |
| `»»»» latency_ms`               | number                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»»» preferred`                | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» lifecycle_state`            | [codersdk.WorkspaceAgentLifecycle](schemas.md#codersdkworkspaceagentlifecycle)                         | false    |              |                                                                                                                                                                                                                                                |
| `»» log_sources`                | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» created_at`                | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» icon`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» workspace_agent_id`        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» logs_length`                | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» logs_overflowed`            | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» name`                       | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» operating_system`           | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» parent_id`                  | [uuid.NullUUID](schemas.md#uuidnulluuid)                                                               | false    |              |                                                                                                                                                                                                                                                |
| `»»» uuid`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» valid`                     | boolean                                                                                                | false    |              | Valid is true if UUID is not NULL                                                                                                                                                                                                              |
| `»» ready_at`                   | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» resource_id`                | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»» scripts`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»»» cron`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» display_name`              | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» exit_code`                 | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» id`                        | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» log_path`                  | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» log_source_id`             | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `»»» run_on_start`              | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» run_on_stop`               | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» script`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»»» start_blocks_login`        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»»» status`                    | [codersdk.WorkspaceAgentScriptStatus](schemas.md#codersdkworkspaceagentscriptstatus)                   | false    |              |                                                                                                                                                                                                                                                |
| `»»» timeout`                   | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» started_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» startup_script_behavior`    | [codersdk.WorkspaceAgentStartupScriptBehavior](schemas.md#codersdkworkspaceagentstartupscriptbehavior) | false    |              | Startup script behavior is a legacy field that is deprecated in favor of the `coder_script` resource. It's only referenced by old clients. Deprecated: Remove in the future!                                                                   |
| `»» status`                     | [codersdk.WorkspaceAgentStatus](schemas.md#codersdkworkspaceagentstatus)                               | false    |              |                                                                                                                                                                                                                                                |
| `»» subsystems`                 | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» troubleshooting_url`        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» updated_at`                 | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `»» version`                    | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» created_at`                  | string(date-time)                                                                                      | false    |              |                                                                                                                                                                                                                                                |
| `» daily_cost`                  | integer                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» hide`                        | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `» icon`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» id`                          | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» job_id`                      | string(uuid)                                                                                           | false    |              |                                                                                                                                                                                                                                                |
| `» metadata`                    | array                                                                                                  | false    |              |                                                                                                                                                                                                                                                |
| `»» key`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `»» sensitive`                  | boolean                                                                                                | false    |              |                                                                                                                                                                                                                                                |
| `»» value`                      | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» name`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» type`                        | string                                                                                                 | false    |              |                                                                                                                                                                                                                                                |
| `» workspace_transition`        | [codersdk.WorkspaceTransition](schemas.md#codersdkworkspacetransition)                                 | false    |              |                                                                                                                                                                                                                                                |

#### Enumerated Values

| Property                  | Value(s)                                                                                                                     |
|---------------------------|------------------------------------------------------------------------------------------------------------------------------|
| `health`                  | `disabled`, `healthy`, `initializing`, `unhealthy`                                                                           |
| `open_in`                 | `slim-window`, `tab`                                                                                                         |
| `sharing_level`           | `authenticated`, `organization`, `owner`, `public`                                                                           |
| `state`                   | `complete`, `failure`, `idle`, `working`                                                                                     |
| `lifecycle_state`         | `created`, `off`, `ready`, `shutdown_error`, `shutdown_timeout`, `shutting_down`, `start_error`, `start_timeout`, `starting` |
| `status`                  | `connected`, `connecting`, `disconnected`, `exit_failure`, `ok`, `pipes_left_open`, `timed_out`, `timeout`                   |
| `startup_script_behavior` | `blocking`, `non-blocking`                                                                                                   |
| `workspace_transition`    | `delete`, `start`, `stop`                                                                                                    |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get rich parameters by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/rich-parameters \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/rich-parameters`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
[
  {
    "default_value": "string",
    "description": "string",
    "description_plaintext": "string",
    "display_name": "string",
    "ephemeral": true,
    "form_type": "",
    "icon": "string",
    "mutable": true,
    "name": "string",
    "options": [
      {
        "description": "string",
        "icon": "string",
        "name": "string",
        "value": "string"
      }
    ],
    "required": true,
    "type": "string",
    "validation_error": "string",
    "validation_max": 0,
    "validation_min": 0,
    "validation_monotonic": "increasing",
    "validation_regex": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                    |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.TemplateVersionParameter](schemas.md#codersdktemplateversionparameter) |

<h3 id="get-rich-parameters-by-template-version-responseschema">Response Schema</h3>

Status Code **200**

| Name                      | Type                                                                             | Required | Restrictions | Description                                                                                        |
|---------------------------|----------------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------|
| `[array item]`            | array                                                                            | false    |              |                                                                                                    |
| `» default_value`         | string                                                                           | false    |              |                                                                                                    |
| `» description`           | string                                                                           | false    |              |                                                                                                    |
| `» description_plaintext` | string                                                                           | false    |              |                                                                                                    |
| `» display_name`          | string                                                                           | false    |              |                                                                                                    |
| `» ephemeral`             | boolean                                                                          | false    |              |                                                                                                    |
| `» form_type`             | string                                                                           | false    |              | Form type has an enum value of empty string, `""`. Keep the leading comma in the enums struct tag. |
| `» icon`                  | string                                                                           | false    |              |                                                                                                    |
| `» mutable`               | boolean                                                                          | false    |              |                                                                                                    |
| `» name`                  | string                                                                           | false    |              |                                                                                                    |
| `» options`               | array                                                                            | false    |              |                                                                                                    |
| `»» description`          | string                                                                           | false    |              |                                                                                                    |
| `»» icon`                 | string                                                                           | false    |              |                                                                                                    |
| `»» name`                 | string                                                                           | false    |              |                                                                                                    |
| `»» value`                | string                                                                           | false    |              |                                                                                                    |
| `» required`              | boolean                                                                          | false    |              |                                                                                                    |
| `» type`                  | string                                                                           | false    |              |                                                                                                    |
| `» validation_error`      | string                                                                           | false    |              |                                                                                                    |
| `» validation_max`        | integer                                                                          | false    |              |                                                                                                    |
| `» validation_min`        | integer                                                                          | false    |              |                                                                                                    |
| `» validation_monotonic`  | [codersdk.ValidationMonotonicOrder](schemas.md#codersdkvalidationmonotonicorder) | false    |              |                                                                                                    |
| `» validation_regex`      | string                                                                           | false    |              |                                                                                                    |

#### Enumerated Values

| Property               | Value(s)                                                                                                            |
|------------------------|---------------------------------------------------------------------------------------------------------------------|
| `form_type`            | ``, `checkbox`, `dropdown`, `error`, `input`, `multi-select`, `radio`, `slider`, `switch`, `tag-select`, `textarea` |
| `type`                 | `bool`, `list(string)`, `number`, `string`                                                                          |
| `validation_monotonic` | `decreasing`, `increasing`                                                                                          |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Removed: Get schema by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/schema \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/schema`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Unarchive template version

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/unarchive \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/templateversions/{templateversion}/unarchive`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get template variables by template version

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/variables \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/templateversions/{templateversion}/variables`

### Parameters

| Name              | In   | Type         | Required | Description         |
|-------------------|------|--------------|----------|---------------------|
| `templateversion` | path | string(uuid) | true     | Template version ID |

### Example responses

> 200 Response

```json
[
  {
    "default_value": "string",
    "description": "string",
    "name": "string",
    "required": true,
    "sensitive": true,
    "type": "string",
    "value": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                  |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.TemplateVersionVariable](schemas.md#codersdktemplateversionvariable) |

<h3 id="get-template-variables-by-template-version-responseschema">Response Schema</h3>

Status Code **200**

| Name              | Type    | Required | Restrictions | Description |
|-------------------|---------|----------|--------------|-------------|
| `[array item]`    | array   | false    |              |             |
| `» default_value` | string  | false    |              |             |
| `» description`   | string  | false    |              |             |
| `» name`          | string  | false    |              |             |
| `» required`      | boolean | false    |              |             |
| `» sensitive`     | boolean | false    |              |             |
| `» type`          | string  | false    |              |             |
| `» value`         | string  | false    |              |             |

#### Enumerated Values

| Property | Value(s)                   |
|----------|----------------------------|
| `type`   | `bool`, `number`, `string` |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Users

Source: https://coder.com/docs/reference/api/users

# Users

## Get users

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users`

### Parameters

| Name       | In    | Type         | Required | Description  |
|------------|-------|--------------|----------|--------------|
| `q`        | query | string       | false    | Search query |
| `after_id` | query | string(uuid) | false    | After ID     |
| `limit`    | query | integer      | false    | Page limit   |
| `offset`   | query | integer      | false    | Page offset  |

### Example responses

> 200 Response

```json
{
  "count": 0,
  "users": [
    {
      "avatar_url": "http://example.com",
      "created_at": "2019-08-24T14:15:22Z",
      "email": "user@example.com",
      "has_ai_seat": true,
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_service_account": true,
      "last_seen_at": "2019-08-24T14:15:22Z",
      "login_type": "",
      "name": "string",
      "organization_ids": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "roles": [
        {
          "display_name": "string",
          "name": "string",
          "organization_id": "string"
        }
      ],
      "status": "active",
      "theme_preference": "string",
      "updated_at": "2019-08-24T14:15:22Z",
      "username": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                           |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GetUsersResponse](schemas.md#codersdkgetusersresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create new user

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users`

> Body parameter

```json
{
  "email": "user@example.com",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "password": "string",
  "roles": [
    "string"
  ],
  "service_account": true,
  "user_status": "active",
  "username": "string"
}
```

### Parameters

| Name   | In   | Type                                                                               | Required | Description         |
|--------|------|------------------------------------------------------------------------------------|----------|---------------------|
| `body` | body | [codersdk.CreateUserRequestWithOrgs](schemas.md#codersdkcreateuserrequestwithorgs) | true     | Create user request |

### Example responses

> 201 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                   |
|--------|--------------------------------------------------------------|-------------|------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get authentication methods

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/authmethods \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/authmethods`

### Example responses

> 200 Response

```json
{
  "github": {
    "default_provider_configured": true,
    "enabled": true
  },
  "oidc": {
    "enabled": true,
    "iconUrl": "string",
    "signInText": "string"
  },
  "password": {
    "enabled": true
  },
  "terms_of_service_url": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                 |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.AuthMethods](schemas.md#codersdkauthmethods) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Check initial user created

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/first \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/first`

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create initial user

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/first \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/first`

> Body parameter

```json
{
  "email": "string",
  "name": "string",
  "onboarding_info": {
    "newsletter_marketing": true,
    "newsletter_releases": true
  },
  "password": "string",
  "trial": true,
  "trial_info": {
    "company_name": "string",
    "country": "string",
    "developers": "string",
    "first_name": "string",
    "job_title": "string",
    "last_name": "string",
    "phone_number": "string"
  },
  "username": "string"
}
```

### Parameters

| Name   | In   | Type                                                                         | Required | Description        |
|--------|------|------------------------------------------------------------------------------|----------|--------------------|
| `body` | body | [codersdk.CreateFirstUserRequest](schemas.md#codersdkcreatefirstuserrequest) | true     | First user request |

### Example responses

> 201 Response

```json
{
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                         |
|--------|--------------------------------------------------------------|-------------|--------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.CreateFirstUserResponse](schemas.md#codersdkcreatefirstuserresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Log out user

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/logout \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/logout`

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## OAuth 2.0 GitHub Callback

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/oauth2/github/callback \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/oauth2/github/callback`

### Responses

| Status | Meaning                                                                 | Description        | Schema |
|--------|-------------------------------------------------------------------------|--------------------|--------|
| 307    | [Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) | Temporary Redirect |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get Github device auth

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/oauth2/github/device \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/oauth2/github/device`

### Example responses

> 200 Response

```json
{
  "device_code": "string",
  "expires_in": 0,
  "interval": 0,
  "user_code": "string",
  "verification_uri": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ExternalAuthDevice](schemas.md#codersdkexternalauthdevice) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get OIDC claims for the authenticated user

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/oidc-claims \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/oidc-claims`

### Example responses

> 200 Response

```json
{
  "claims": {}
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.OIDCClaimsResponse](schemas.md#codersdkoidcclaimsresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## OpenID Connect Callback

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/oidc/callback \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/oidc/callback`

### Responses

| Status | Meaning                                                                 | Description        | Schema |
|--------|-------------------------------------------------------------------------|--------------------|--------|
| 307    | [Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) | Temporary Redirect |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user by name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}`

### Parameters

| Name   | In   | Type   | Required | Description              |
|--------|------|--------|----------|--------------------------|
| `user` | path | string | true     | User ID, username, or me |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete user

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/users/{user} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/users/{user}`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user appearance settings

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/appearance \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/appearance`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "terminal_font": "",
  "theme_preference": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                       |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserAppearanceSettings](schemas.md#codersdkuserappearancesettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update user appearance settings

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/appearance \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/appearance`

> Body parameter

```json
{
  "terminal_font": "",
  "theme_preference": "string"
}
```

### Parameters

| Name   | In   | Type                                                                                                   | Required | Description             |
|--------|------|--------------------------------------------------------------------------------------------------------|----------|-------------------------|
| `user` | path | string                                                                                                 | true     | User ID, name, or me    |
| `body` | body | [codersdk.UpdateUserAppearanceSettingsRequest](schemas.md#codersdkupdateuserappearancesettingsrequest) | true     | New appearance settings |

### Example responses

> 200 Response

```json
{
  "terminal_font": "",
  "theme_preference": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                       |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserAppearanceSettings](schemas.md#codersdkuserappearancesettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get autofill build parameters for user

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/autofill-parameters?template_id=string \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/autofill-parameters`

### Parameters

| Name          | In    | Type   | Required | Description              |
|---------------|-------|--------|----------|--------------------------|
| `user`        | path  | string | true     | User ID, username, or me |
| `template_id` | query | string | true     | Template ID              |

### Example responses

> 200 Response

```json
[
  {
    "name": "string",
    "value": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                              |
|--------|---------------------------------------------------------|-------------|---------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.UserParameter](schemas.md#codersdkuserparameter) |

<h3 id="get-autofill-build-parameters-for-user-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type   | Required | Restrictions | Description |
|----------------|--------|----------|--------------|-------------|
| `[array item]` | array  | false    |              |             |
| `» name`       | string | false    |              |             |
| `» value`      | string | false    |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user Git SSH key

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/gitsshkey \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/gitsshkey`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "public_key": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GitSSHKey](schemas.md#codersdkgitsshkey) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Regenerate user SSH key

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/gitsshkey \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/gitsshkey`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "public_key": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.GitSSHKey](schemas.md#codersdkgitsshkey) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create new session key

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/{user}/keys \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/{user}/keys`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 201 Response

```json
{
  "key": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                       |
|--------|--------------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.GenerateAPIKeyResponse](schemas.md#codersdkgenerateapikeyresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user tokens

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/tokens \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/keys/tokens`

### Parameters

| Name              | In    | Type    | Required | Description                        |
|-------------------|-------|---------|----------|------------------------------------|
| `user`            | path  | string  | true     | User ID, name, or me               |
| `include_expired` | query | boolean | false    | Include expired tokens in the list |

### Example responses

> 200 Response

```json
[
  {
    "allow_list": [
      {
        "id": "string",
        "type": "*"
      }
    ],
    "created_at": "2019-08-24T14:15:22Z",
    "expires_at": "2019-08-24T14:15:22Z",
    "id": "string",
    "last_used": "2019-08-24T14:15:22Z",
    "lifetime_seconds": 0,
    "login_type": "password",
    "scope": "all",
    "scopes": [
      "all"
    ],
    "token_name": "string",
    "updated_at": "2019-08-24T14:15:22Z",
    "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.APIKey](schemas.md#codersdkapikey) |

<h3 id="get-user-tokens-responseschema">Response Schema</h3>

Status Code **200**

| Name                 | Type                                                     | Required | Restrictions | Description                     |
|----------------------|----------------------------------------------------------|----------|--------------|---------------------------------|
| `[array item]`       | array                                                    | false    |              |                                 |
| `» allow_list`       | array                                                    | false    |              |                                 |
| `»» id`              | string                                                   | false    |              |                                 |
| `»» type`            | [codersdk.RBACResource](schemas.md#codersdkrbacresource) | false    |              |                                 |
| `» created_at`       | string(date-time)                                        | true     |              |                                 |
| `» expires_at`       | string(date-time)                                        | true     |              |                                 |
| `» id`               | string                                                   | true     |              |                                 |
| `» last_used`        | string(date-time)                                        | true     |              |                                 |
| `» lifetime_seconds` | integer                                                  | true     |              |                                 |
| `» login_type`       | [codersdk.LoginType](schemas.md#codersdklogintype)       | true     |              |                                 |
| `» scope`            | [codersdk.APIKeyScope](schemas.md#codersdkapikeyscope)   | false    |              | Deprecated: use Scopes instead. |
| `» scopes`           | array                                                    | false    |              |                                 |
| `» token_name`       | string                                                   | true     |              |                                 |
| `» updated_at`       | string(date-time)                                        | true     |              |                                 |
| `» user_id`          | string(uuid)                                             | true     |              |                                 |

#### Enumerated Values

| Property     | Value(s)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type`       | `*`, `ai_seat`, `aibridge_interception`, `api_key`, `assign_org_role`, `assign_role`, `audit_log`, `boundary_usage`, `chat`, `connection_log`, `crypto_key`, `debug_info`, `deployment_config`, `deployment_stats`, `file`, `group`, `group_member`, `idpsync_settings`, `inbox_notification`, `license`, `notification_message`, `notification_preference`, `notification_template`, `oauth2_app`, `oauth2_app_code_token`, `oauth2_app_secret`, `organization`, `organization_member`, `prebuilt_workspace`, `provisioner_daemon`, `provisioner_jobs`, `replicas`, `system`, `tailnet_coordinator`, `task`, `template`, `usage_event`, `user`, `user_secret`, `webpush_subscription`, `workspace`, `workspace_agent_devcontainers`, `workspace_agent_resource_monitor`, `workspace_dormant`, `workspace_proxy` |
| `login_type` | `github`, `oidc`, `password`, `token`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scope`      | `all`, `application_connect`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create token API key

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/{user}/keys/tokens \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/{user}/keys/tokens`

> Body parameter

```json
{
  "allow_list": [
    {
      "id": "string",
      "type": "*"
    }
  ],
  "lifetime": 0,
  "scope": "all",
  "scopes": [
    "all"
  ],
  "token_name": "string"
}
```

### Parameters

| Name   | In   | Type                                                                 | Required | Description          |
|--------|------|----------------------------------------------------------------------|----------|----------------------|
| `user` | path | string                                                               | true     | User ID, name, or me |
| `body` | body | [codersdk.CreateTokenRequest](schemas.md#codersdkcreatetokenrequest) | true     | Create token request |

### Example responses

> 201 Response

```json
{
  "key": "string"
}
```

### Responses

| Status | Meaning                                                      | Description | Schema                                                                       |
|--------|--------------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 201    | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created     | [codersdk.GenerateAPIKeyResponse](schemas.md#codersdkgenerateapikeyresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get API key by token name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/tokens/{keyname} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/keys/tokens/{keyname}`

### Parameters

| Name      | In   | Type           | Required | Description          |
|-----------|------|----------------|----------|----------------------|
| `user`    | path | string         | true     | User ID, name, or me |
| `keyname` | path | string(string) | true     | Key Name             |

### Example responses

> 200 Response

```json
{
  "allow_list": [
    {
      "id": "string",
      "type": "*"
    }
  ],
  "created_at": "2019-08-24T14:15:22Z",
  "expires_at": "2019-08-24T14:15:22Z",
  "id": "string",
  "last_used": "2019-08-24T14:15:22Z",
  "lifetime_seconds": 0,
  "login_type": "password",
  "scope": "all",
  "scopes": [
    "all"
  ],
  "token_name": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.APIKey](schemas.md#codersdkapikey) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get API key by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/keys/{keyid} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/keys/{keyid}`

### Parameters

| Name    | In   | Type           | Required | Description          |
|---------|------|----------------|----------|----------------------|
| `user`  | path | string         | true     | User ID, name, or me |
| `keyid` | path | string(string) | true     | Key ID               |

### Example responses

> 200 Response

```json
{
  "allow_list": [
    {
      "id": "string",
      "type": "*"
    }
  ],
  "created_at": "2019-08-24T14:15:22Z",
  "expires_at": "2019-08-24T14:15:22Z",
  "id": "string",
  "last_used": "2019-08-24T14:15:22Z",
  "lifetime_seconds": 0,
  "login_type": "password",
  "scope": "all",
  "scopes": [
    "all"
  ],
  "token_name": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                       |
|--------|---------------------------------------------------------|-------------|----------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.APIKey](schemas.md#codersdkapikey) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Delete API key

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/users/{user}/keys/{keyid} \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/users/{user}/keys/{keyid}`

### Parameters

| Name    | In   | Type           | Required | Description          |
|---------|------|----------------|----------|----------------------|
| `user`  | path | string         | true     | User ID, name, or me |
| `keyid` | path | string(string) | true     | Key ID               |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Expire API key

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/keys/{keyid}/expire \
  -H 'Accept: */*' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/keys/{keyid}/expire`

### Parameters

| Name    | In   | Type           | Required | Description          |
|---------|------|----------------|----------|----------------------|
| `user`  | path | string         | true     | User ID, name, or me |
| `keyid` | path | string(string) | true     | Key ID               |

### Example responses

> 404 Response

### Responses

| Status | Meaning                                                                    | Description           | Schema                                           |
|--------|----------------------------------------------------------------------------|-----------------------|--------------------------------------------------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5)            | No Content            |                                                  |
| 404    | [Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4)             | Not Found             | [codersdk.Response](schemas.md#codersdkresponse) |
| 500    | [Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) | Internal Server Error | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user login type

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/login-type \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/login-type`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "login_type": ""
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                     |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserLoginType](schemas.md#codersdkuserlogintype) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get organizations by user

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/organizations \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/organizations`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
[
  {
    "created_at": "2019-08-24T14:15:22Z",
    "description": "string",
    "display_name": "string",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "is_default": true,
    "name": "string",
    "updated_at": "2019-08-24T14:15:22Z"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                            |
|--------|---------------------------------------------------------|-------------|-------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.Organization](schemas.md#codersdkorganization) |

<h3 id="get-organizations-by-user-responseschema">Response Schema</h3>

Status Code **200**

| Name             | Type              | Required | Restrictions | Description |
|------------------|-------------------|----------|--------------|-------------|
| `[array item]`   | array             | false    |              |             |
| `» created_at`   | string(date-time) | true     |              |             |
| `» description`  | string            | false    |              |             |
| `» display_name` | string            | false    |              |             |
| `» icon`         | string            | false    |              |             |
| `» id`           | string(uuid)      | true     |              |             |
| `» is_default`   | boolean           | true     |              |             |
| `» name`         | string            | false    |              |             |
| `» updated_at`   | string(date-time) | true     |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get organization by user and organization name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/organizations/{organizationname} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/organizations/{organizationname}`

### Parameters

| Name               | In   | Type   | Required | Description          |
|--------------------|------|--------|----------|----------------------|
| `user`             | path | string | true     | User ID, name, or me |
| `organizationname` | path | string | true     | Organization name    |

### Example responses

> 200 Response

```json
{
  "created_at": "2019-08-24T14:15:22Z",
  "description": "string",
  "display_name": "string",
  "icon": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_default": true,
  "name": "string",
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Organization](schemas.md#codersdkorganization) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update user password

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/password \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/password`

> Body parameter

```json
{
  "old_password": "string",
  "password": "string"
}
```

### Parameters

| Name   | In   | Type                                                                               | Required | Description             |
|--------|------|------------------------------------------------------------------------------------|----------|-------------------------|
| `user` | path | string                                                                             | true     | User ID, name, or me    |
| `body` | body | [codersdk.UpdateUserPasswordRequest](schemas.md#codersdkupdateuserpasswordrequest) | true     | Update password request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user preference settings

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/preferences \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/preferences`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "code_diff_display_mode": "auto",
  "task_notification_alert_dismissed": true,
  "thinking_display_mode": "auto"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                       |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserPreferenceSettings](schemas.md#codersdkuserpreferencesettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update user preference settings

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/preferences \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/preferences`

> Body parameter

```json
{
  "code_diff_display_mode": "auto",
  "task_notification_alert_dismissed": true,
  "thinking_display_mode": "auto"
}
```

### Parameters

| Name   | In   | Type                                                                                                   | Required | Description             |
|--------|------|--------------------------------------------------------------------------------------------------------|----------|-------------------------|
| `user` | path | string                                                                                                 | true     | User ID, name, or me    |
| `body` | body | [codersdk.UpdateUserPreferenceSettingsRequest](schemas.md#codersdkupdateuserpreferencesettingsrequest) | true     | New preference settings |

### Example responses

> 200 Response

```json
{
  "code_diff_display_mode": "auto",
  "task_notification_alert_dismissed": true,
  "thinking_display_mode": "auto"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                       |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.UserPreferenceSettings](schemas.md#codersdkuserpreferencesettings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update user profile

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/profile \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/profile`

> Body parameter

```json
{
  "name": "string",
  "username": "string"
}
```

### Parameters

| Name   | In   | Type                                                                             | Required | Description          |
|--------|------|----------------------------------------------------------------------------------|----------|----------------------|
| `user` | path | string                                                                           | true     | User ID, name, or me |
| `body` | body | [codersdk.UpdateUserProfileRequest](schemas.md#codersdkupdateuserprofilerequest) | true     | Updated profile      |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get user roles

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/roles \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/roles`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Assign role to user

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/roles \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/roles`

> Body parameter

```json
{
  "roles": [
    "string"
  ]
}
```

### Parameters

| Name   | In   | Type                                                   | Required | Description          |
|--------|------|--------------------------------------------------------|----------|----------------------|
| `user` | path | string                                                 | true     | User ID, name, or me |
| `body` | body | [codersdk.UpdateRoles](schemas.md#codersdkupdateroles) | true     | Update roles request |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Activate user account

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/activate \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/status/activate`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Suspend user account

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/suspend \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/users/{user}/status/suspend`

### Parameters

| Name   | In   | Type   | Required | Description          |
|--------|------|--------|----------|----------------------|
| `user` | path | string | true     | User ID, name, or me |

### Example responses

> 200 Response

```json
{
  "avatar_url": "http://example.com",
  "created_at": "2019-08-24T14:15:22Z",
  "email": "user@example.com",
  "has_ai_seat": true,
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_service_account": true,
  "last_seen_at": "2019-08-24T14:15:22Z",
  "login_type": "",
  "name": "string",
  "organization_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "roles": [
    {
      "display_name": "string",
      "name": "string",
      "organization_id": "string"
    }
  ],
  "status": "active",
  "theme_preference": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "username": "string"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                   |
|--------|---------------------------------------------------------|-------------|------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.User](schemas.md#codersdkuser) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# WorkspaceProxies

Source: https://coder.com/docs/reference/api/workspaceproxies

# WorkspaceProxies

## Get site-wide regions for workspace connections

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/regions \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/regions`

### Example responses

> 200 Response

```json
{
  "regions": [
    {
      "display_name": "string",
      "healthy": true,
      "icon_url": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "path_app_url": "string",
      "wildcard_hostname": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                                         |
|--------|---------------------------------------------------------|-------------|------------------------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.RegionsResponse-codersdk_Region](schemas.md#codersdkregionsresponse-codersdk_region) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Workspaces

Source: https://coder.com/docs/reference/api/workspaces

# Workspaces

## Create user workspace by organization

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/members/{user}/workspaces \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/organizations/{organization}/members/{user}/workspaces`

Create a new workspace using a template. The request must
specify either the Template ID or the Template Version ID,
not both. If the Template ID is specified, the active version
of the template will be used.

> Body parameter

```json
{
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "name": "string",
  "rich_parameter_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "ttl_ms": 0
}
```

### Parameters

| Name           | In   | Type                                                                         | Required | Description              |
|----------------|------|------------------------------------------------------------------------------|----------|--------------------------|
| `organization` | path | string(uuid)                                                                 | true     | Organization ID          |
| `user`         | path | string                                                                       | true     | Username, UUID, or me    |
| `body`         | body | [codersdk.CreateWorkspaceRequest](schemas.md#codersdkcreateworkspacerequest) | true     | Create workspace request |

### Example responses

> 200 Response

```json
{
  "allow_renames": true,
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "deleting_at": "2019-08-24T14:15:22Z",
  "dormant_at": "2019-08-24T14:15:22Z",
  "favorite": true,
  "health": {
    "failing_agents": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "healthy": false
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_prebuild": true,
  "last_used_at": "2019-08-24T14:15:22Z",
  "latest_app_status": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "message": "string",
    "needs_user_attention": true,
    "state": "working",
    "uri": "string",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "latest_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  },
  "name": "string",
  "next_start_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "outdated": true,
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "shared_with": [
    {
      "actor_type": "group",
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "roles": [
        "admin"
      ]
    }
  ],
  "task_id": {
    "uuid": "string",
    "valid": true
  },
  "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
  "template_allow_user_cancel_workspace_jobs": true,
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "ttl_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Workspace](schemas.md#codersdkworkspace) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get users available for workspace creation

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/members/{user}/workspaces/available-users \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/organizations/{organization}/members/{user}/workspaces/available-users`

### Parameters

| Name           | In    | Type         | Required | Description           |
|----------------|-------|--------------|----------|-----------------------|
| `organization` | path  | string(uuid) | true     | Organization ID       |
| `user`         | path  | string       | true     | User ID, name, or me  |
| `q`            | query | string       | false    | Search query          |
| `limit`        | query | integer      | false    | Limit results         |
| `offset`       | query | integer      | false    | Offset for pagination |

### Example responses

> 200 Response

```json
[
  {
    "avatar_url": "http://example.com",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "name": "string",
    "username": "string"
  }
]
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                          |
|--------|---------------------------------------------------------|-------------|-----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | array of [codersdk.MinimalUser](schemas.md#codersdkminimaluser) |

<h3 id="get-users-available-for-workspace-creation-responseschema">Response Schema</h3>

Status Code **200**

| Name           | Type         | Required | Restrictions | Description |
|----------------|--------------|----------|--------------|-------------|
| `[array item]` | array        | false    |              |             |
| `» avatar_url` | string(uri)  | false    |              |             |
| `» id`         | string(uuid) | true     |              |             |
| `» name`       | string       | false    |              |             |
| `» username`   | string       | true     |              |             |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace metadata by user and workspace name

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacename} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/users/{user}/workspace/{workspacename}`

### Parameters

| Name              | In    | Type    | Required | Description                                                 |
|-------------------|-------|---------|----------|-------------------------------------------------------------|
| `user`            | path  | string  | true     | User ID, name, or me                                        |
| `workspacename`   | path  | string  | true     | Workspace name                                              |
| `include_deleted` | query | boolean | false    | Return data instead of HTTP 404 if the workspace is deleted |

### Example responses

> 200 Response

```json
{
  "allow_renames": true,
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "deleting_at": "2019-08-24T14:15:22Z",
  "dormant_at": "2019-08-24T14:15:22Z",
  "favorite": true,
  "health": {
    "failing_agents": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "healthy": false
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_prebuild": true,
  "last_used_at": "2019-08-24T14:15:22Z",
  "latest_app_status": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "message": "string",
    "needs_user_attention": true,
    "state": "working",
    "uri": "string",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "latest_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  },
  "name": "string",
  "next_start_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "outdated": true,
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "shared_with": [
    {
      "actor_type": "group",
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "roles": [
        "admin"
      ]
    }
  ],
  "task_id": {
    "uuid": "string",
    "valid": true
  },
  "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
  "template_allow_user_cancel_workspace_jobs": true,
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "ttl_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Workspace](schemas.md#codersdkworkspace) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Create user workspace

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/users/{user}/workspaces \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/users/{user}/workspaces`

Create a new workspace using a template. The request must
specify either the Template ID or the Template Version ID,
not both. If the Template ID is specified, the active version
of the template will be used.

> Body parameter

```json
{
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "name": "string",
  "rich_parameter_values": [
    {
      "name": "string",
      "value": "string"
    }
  ],
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
  "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
  "ttl_ms": 0
}
```

### Parameters

| Name   | In   | Type                                                                         | Required | Description              |
|--------|------|------------------------------------------------------------------------------|----------|--------------------------|
| `user` | path | string                                                                       | true     | Username, UUID, or me    |
| `body` | body | [codersdk.CreateWorkspaceRequest](schemas.md#codersdkcreateworkspacerequest) | true     | Create workspace request |

### Example responses

> 200 Response

```json
{
  "allow_renames": true,
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "deleting_at": "2019-08-24T14:15:22Z",
  "dormant_at": "2019-08-24T14:15:22Z",
  "favorite": true,
  "health": {
    "failing_agents": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "healthy": false
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_prebuild": true,
  "last_used_at": "2019-08-24T14:15:22Z",
  "latest_app_status": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "message": "string",
    "needs_user_attention": true,
    "state": "working",
    "uri": "string",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "latest_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  },
  "name": "string",
  "next_start_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "outdated": true,
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "shared_with": [
    {
      "actor_type": "group",
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "roles": [
        "admin"
      ]
    }
  ],
  "task_id": {
    "uuid": "string",
    "valid": true
  },
  "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
  "template_allow_user_cancel_workspace_jobs": true,
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "ttl_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Workspace](schemas.md#codersdkworkspace) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## List workspaces

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces`

### Parameters

| Name     | In    | Type    | Required | Description                                                                                                                                                                                 |
|----------|-------|---------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `q`      | query | string  | false    | Search query in the format `key:value`. Available keys are: owner, template, name, status, has-agent, dormant, last_used_after, last_used_before, has-ai-task, has_external_agent, healthy. |
| `limit`  | query | integer | false    | Page limit                                                                                                                                                                                  |
| `offset` | query | integer | false    | Page offset                                                                                                                                                                                 |

### Example responses

> 200 Response

```json
{
  "count": 0,
  "workspaces": [
    {
      "allow_renames": true,
      "automatic_updates": "always",
      "autostart_schedule": "string",
      "created_at": "2019-08-24T14:15:22Z",
      "deleting_at": "2019-08-24T14:15:22Z",
      "dormant_at": "2019-08-24T14:15:22Z",
      "favorite": true,
      "health": {
        "failing_agents": [
          "497f6eca-6276-4993-bfeb-53cbbbba6f08"
        ],
        "healthy": false
      },
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "is_prebuild": true,
      "last_used_at": "2019-08-24T14:15:22Z",
      "latest_app_status": {
        "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
        "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
        "created_at": "2019-08-24T14:15:22Z",
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "message": "string",
        "needs_user_attention": true,
        "state": "working",
        "uri": "string",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
      },
      "latest_build": {
        "build_number": 0,
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "deadline": "2019-08-24T14:15:22Z",
        "has_ai_task": true,
        "has_external_agent": true,
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
        "initiator_name": "string",
        "job": {
          "available_workers": [
            "497f6eca-6276-4993-bfeb-53cbbbba6f08"
          ],
          "canceled_at": "2019-08-24T14:15:22Z",
          "completed_at": "2019-08-24T14:15:22Z",
          "created_at": "2019-08-24T14:15:22Z",
          "error": "string",
          "error_code": "REQUIRED_TEMPLATE_VARIABLES",
          "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
          "input": {
            "error": "string",
            "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
            "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
          },
          "logs_overflowed": true,
          "metadata": {
            "template_display_name": "string",
            "template_icon": "string",
            "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
            "template_name": "string",
            "template_version_name": "string",
            "workspace_build_transition": "start",
            "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
            "workspace_name": "string"
          },
          "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
          "queue_position": 0,
          "queue_size": 0,
          "started_at": "2019-08-24T14:15:22Z",
          "status": "pending",
          "tags": {
            "property1": "string",
            "property2": "string"
          },
          "type": "template_version_import",
          "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
          "worker_name": "string"
        },
        "matched_provisioners": {
          "available": 0,
          "count": 0,
          "most_recently_seen": "2019-08-24T14:15:22Z"
        },
        "max_deadline": "2019-08-24T14:15:22Z",
        "reason": "initiator",
        "resources": [
          {
            "agents": [
              {
                "api_version": "string",
                "apps": [
                  {
                    "command": "string",
                    "display_name": "string",
                    "external": true,
                    "group": "string",
                    "health": "disabled",
                    "healthcheck": {},
                    "hidden": true,
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "open_in": "slim-window",
                    "sharing_level": "owner",
                    "slug": "string",
                    "statuses": [],
                    "subdomain": true,
                    "subdomain_name": "string",
                    "tooltip": "string",
                    "url": "string"
                  }
                ],
                "architecture": "string",
                "connection_timeout_seconds": 0,
                "created_at": "2019-08-24T14:15:22Z",
                "directory": "string",
                "disconnected_at": "2019-08-24T14:15:22Z",
                "display_apps": [
                  "vscode"
                ],
                "environment_variables": {
                  "property1": "string",
                  "property2": "string"
                },
                "expanded_directory": "string",
                "first_connected_at": "2019-08-24T14:15:22Z",
                "health": {
                  "healthy": false,
                  "reason": "agent has lost connection"
                },
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "instance_id": "string",
                "last_connected_at": "2019-08-24T14:15:22Z",
                "latency": {
                  "property1": {
                    "latency_ms": 0,
                    "preferred": true
                  },
                  "property2": {
                    "latency_ms": 0,
                    "preferred": true
                  }
                },
                "lifecycle_state": "created",
                "log_sources": [
                  {
                    "created_at": "2019-08-24T14:15:22Z",
                    "display_name": "string",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
                  }
                ],
                "logs_length": 0,
                "logs_overflowed": true,
                "name": "string",
                "operating_system": "string",
                "parent_id": {
                  "uuid": "string",
                  "valid": true
                },
                "ready_at": "2019-08-24T14:15:22Z",
                "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
                "scripts": [
                  {
                    "cron": "string",
                    "display_name": "string",
                    "exit_code": 0,
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "log_path": "string",
                    "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                    "run_on_start": true,
                    "run_on_stop": true,
                    "script": "string",
                    "start_blocks_login": true,
                    "status": "ok",
                    "timeout": 0
                  }
                ],
                "started_at": "2019-08-24T14:15:22Z",
                "startup_script_behavior": "blocking",
                "status": "connecting",
                "subsystems": [
                  "envbox"
                ],
                "troubleshooting_url": "string",
                "updated_at": "2019-08-24T14:15:22Z",
                "version": "string"
              }
            ],
            "created_at": "2019-08-24T14:15:22Z",
            "daily_cost": 0,
            "hide": true,
            "icon": "string",
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
            "metadata": [
              {
                "key": "string",
                "sensitive": true,
                "value": "string"
              }
            ],
            "name": "string",
            "type": "string",
            "workspace_transition": "start"
          }
        ],
        "status": "pending",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "template_version_name": "string",
        "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
        "transition": "start",
        "updated_at": "2019-08-24T14:15:22Z",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string",
        "workspace_owner_avatar_url": "string",
        "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
        "workspace_owner_name": "string"
      },
      "name": "string",
      "next_start_at": "2019-08-24T14:15:22Z",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "organization_name": "string",
      "outdated": true,
      "owner_avatar_url": "string",
      "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
      "owner_name": "string",
      "shared_with": [
        {
          "actor_type": "group",
          "avatar_url": "http://example.com",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "name": "string",
          "roles": [
            "admin"
          ]
        }
      ],
      "task_id": {
        "uuid": "string",
        "valid": true
      },
      "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
      "template_allow_user_cancel_workspace_jobs": true,
      "template_display_name": "string",
      "template_icon": "string",
      "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
      "template_name": "string",
      "template_require_active_version": true,
      "template_use_classic_parameter_flow": true,
      "ttl_ms": 0,
      "updated_at": "2019-08-24T14:15:22Z"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                               |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspacesResponse](schemas.md#codersdkworkspacesresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace metadata by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}`

### Parameters

| Name              | In    | Type         | Required | Description                                                 |
|-------------------|-------|--------------|----------|-------------------------------------------------------------|
| `workspace`       | path  | string(uuid) | true     | Workspace ID                                                |
| `include_deleted` | query | boolean      | false    | Return data instead of HTTP 404 if the workspace is deleted |

### Example responses

> 200 Response

```json
{
  "allow_renames": true,
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "deleting_at": "2019-08-24T14:15:22Z",
  "dormant_at": "2019-08-24T14:15:22Z",
  "favorite": true,
  "health": {
    "failing_agents": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "healthy": false
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_prebuild": true,
  "last_used_at": "2019-08-24T14:15:22Z",
  "latest_app_status": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "message": "string",
    "needs_user_attention": true,
    "state": "working",
    "uri": "string",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "latest_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  },
  "name": "string",
  "next_start_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "outdated": true,
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "shared_with": [
    {
      "actor_type": "group",
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "roles": [
        "admin"
      ]
    }
  ],
  "task_id": {
    "uuid": "string",
    "valid": true
  },
  "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
  "template_allow_user_cancel_workspace_jobs": true,
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "ttl_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Workspace](schemas.md#codersdkworkspace) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace metadata by ID

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/workspaces/{workspace} \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/workspaces/{workspace}`

> Body parameter

```json
{
  "name": "string"
}
```

### Parameters

| Name        | In   | Type                                                                         | Required | Description             |
|-------------|------|------------------------------------------------------------------------------|----------|-------------------------|
| `workspace` | path | string(uuid)                                                                 | true     | Workspace ID            |
| `body`      | body | [codersdk.UpdateWorkspaceRequest](schemas.md#codersdkupdateworkspacerequest) | true     | Metadata update request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace ACLs

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/acl \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/acl`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Example responses

> 200 Response

```json
{
  "group": [
    {
      "avatar_url": "http://example.com",
      "display_name": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "members": [
        {
          "avatar_url": "http://example.com",
          "created_at": "2019-08-24T14:15:22Z",
          "email": "user@example.com",
          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
          "is_service_account": true,
          "last_seen_at": "2019-08-24T14:15:22Z",
          "login_type": "",
          "name": "string",
          "status": "active",
          "theme_preference": "string",
          "updated_at": "2019-08-24T14:15:22Z",
          "username": "string"
        }
      ],
      "name": "string",
      "organization_display_name": "string",
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "organization_name": "string",
      "quota_allowance": 0,
      "role": "admin",
      "source": "user",
      "total_member_count": 0
    }
  ],
  "users": [
    {
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "role": "admin",
      "username": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                   |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceACL](schemas.md#codersdkworkspaceacl) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Completely clears the workspace's user and group ACLs

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/workspaces/{workspace}/acl \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/workspaces/{workspace}/acl`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace ACL

### Code samples

```shell
# Example request using curl
curl -X PATCH http://coder-server:8080/api/v2/workspaces/{workspace}/acl \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PATCH /api/v2/workspaces/{workspace}/acl`

> Body parameter

```json
{
  "group_roles": {
    "property1": "admin",
    "property2": "admin"
  },
  "user_roles": {
    "property1": "admin",
    "property2": "admin"
  }
}
```

### Parameters

| Name        | In   | Type                                                                 | Required | Description                  |
|-------------|------|----------------------------------------------------------------------|----------|------------------------------|
| `workspace` | path | string(uuid)                                                         | true     | Workspace ID                 |
| `body`      | body | [codersdk.UpdateWorkspaceACL](schemas.md#codersdkupdateworkspaceacl) | true     | Update workspace ACL request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace autostart schedule by ID

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/autostart \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/workspaces/{workspace}/autostart`

> Body parameter

```json
{
  "schedule": "string"
}
```

### Parameters

| Name        | In   | Type                                                                                           | Required | Description             |
|-------------|------|------------------------------------------------------------------------------------------------|----------|-------------------------|
| `workspace` | path | string(uuid)                                                                                   | true     | Workspace ID            |
| `body`      | body | [codersdk.UpdateWorkspaceAutostartRequest](schemas.md#codersdkupdateworkspaceautostartrequest) | true     | Schedule update request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace automatic updates by ID

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/autoupdates \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/workspaces/{workspace}/autoupdates`

> Body parameter

```json
{
  "automatic_updates": "always"
}
```

### Parameters

| Name        | In   | Type                                                                                                         | Required | Description               |
|-------------|------|--------------------------------------------------------------------------------------------------------------|----------|---------------------------|
| `workspace` | path | string(uuid)                                                                                                 | true     | Workspace ID              |
| `body`      | body | [codersdk.UpdateWorkspaceAutomaticUpdatesRequest](schemas.md#codersdkupdateworkspaceautomaticupdatesrequest) | true     | Automatic updates request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace dormancy status by id

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/workspaces/{workspace}/dormant`

> Body parameter

```json
{
  "dormant": true
}
```

### Parameters

| Name        | In   | Type                                                                           | Required | Description                        |
|-------------|------|--------------------------------------------------------------------------------|----------|------------------------------------|
| `workspace` | path | string(uuid)                                                                   | true     | Workspace ID                       |
| `body`      | body | [codersdk.UpdateWorkspaceDormancy](schemas.md#codersdkupdateworkspacedormancy) | true     | Make a workspace dormant or active |

### Example responses

> 200 Response

```json
{
  "allow_renames": true,
  "automatic_updates": "always",
  "autostart_schedule": "string",
  "created_at": "2019-08-24T14:15:22Z",
  "deleting_at": "2019-08-24T14:15:22Z",
  "dormant_at": "2019-08-24T14:15:22Z",
  "favorite": true,
  "health": {
    "failing_agents": [
      "497f6eca-6276-4993-bfeb-53cbbbba6f08"
    ],
    "healthy": false
  },
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "is_prebuild": true,
  "last_used_at": "2019-08-24T14:15:22Z",
  "latest_app_status": {
    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
    "created_at": "2019-08-24T14:15:22Z",
    "icon": "string",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "message": "string",
    "needs_user_attention": true,
    "state": "working",
    "uri": "string",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
  },
  "latest_build": {
    "build_number": 0,
    "created_at": "2019-08-24T14:15:22Z",
    "daily_cost": 0,
    "deadline": "2019-08-24T14:15:22Z",
    "has_ai_task": true,
    "has_external_agent": true,
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
    "initiator_name": "string",
    "job": {
      "available_workers": [
        "497f6eca-6276-4993-bfeb-53cbbbba6f08"
      ],
      "canceled_at": "2019-08-24T14:15:22Z",
      "completed_at": "2019-08-24T14:15:22Z",
      "created_at": "2019-08-24T14:15:22Z",
      "error": "string",
      "error_code": "REQUIRED_TEMPLATE_VARIABLES",
      "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "initiator_id": "06588898-9a84-4b35-ba8f-f9cbd64946f3",
      "input": {
        "error": "string",
        "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
        "workspace_build_id": "badaf2eb-96c5-4050-9f1d-db2d39ca5478"
      },
      "logs_overflowed": true,
      "metadata": {
        "template_display_name": "string",
        "template_icon": "string",
        "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
        "template_name": "string",
        "template_version_name": "string",
        "workspace_build_transition": "start",
        "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
        "workspace_name": "string"
      },
      "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
      "queue_position": 0,
      "queue_size": 0,
      "started_at": "2019-08-24T14:15:22Z",
      "status": "pending",
      "tags": {
        "property1": "string",
        "property2": "string"
      },
      "type": "template_version_import",
      "worker_id": "ae5fa6f7-c55b-40c1-b40a-b36ac467652b",
      "worker_name": "string"
    },
    "matched_provisioners": {
      "available": 0,
      "count": 0,
      "most_recently_seen": "2019-08-24T14:15:22Z"
    },
    "max_deadline": "2019-08-24T14:15:22Z",
    "reason": "initiator",
    "resources": [
      {
        "agents": [
          {
            "api_version": "string",
            "apps": [
              {
                "command": "string",
                "display_name": "string",
                "external": true,
                "group": "string",
                "health": "disabled",
                "healthcheck": {
                  "interval": 0,
                  "threshold": 0,
                  "url": "string"
                },
                "hidden": true,
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "open_in": "slim-window",
                "sharing_level": "owner",
                "slug": "string",
                "statuses": [
                  {
                    "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
                    "app_id": "affd1d10-9538-4fc8-9e0b-4594a28c1335",
                    "created_at": "2019-08-24T14:15:22Z",
                    "icon": "string",
                    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                    "message": "string",
                    "needs_user_attention": true,
                    "state": "working",
                    "uri": "string",
                    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9"
                  }
                ],
                "subdomain": true,
                "subdomain_name": "string",
                "tooltip": "string",
                "url": "string"
              }
            ],
            "architecture": "string",
            "connection_timeout_seconds": 0,
            "created_at": "2019-08-24T14:15:22Z",
            "directory": "string",
            "disconnected_at": "2019-08-24T14:15:22Z",
            "display_apps": [
              "vscode"
            ],
            "environment_variables": {
              "property1": "string",
              "property2": "string"
            },
            "expanded_directory": "string",
            "first_connected_at": "2019-08-24T14:15:22Z",
            "health": {
              "healthy": false,
              "reason": "agent has lost connection"
            },
            "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
            "instance_id": "string",
            "last_connected_at": "2019-08-24T14:15:22Z",
            "latency": {
              "property1": {
                "latency_ms": 0,
                "preferred": true
              },
              "property2": {
                "latency_ms": 0,
                "preferred": true
              }
            },
            "lifecycle_state": "created",
            "log_sources": [
              {
                "created_at": "2019-08-24T14:15:22Z",
                "display_name": "string",
                "icon": "string",
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "workspace_agent_id": "7ad2e618-fea7-4c1a-b70a-f501566a72f1"
              }
            ],
            "logs_length": 0,
            "logs_overflowed": true,
            "name": "string",
            "operating_system": "string",
            "parent_id": {
              "uuid": "string",
              "valid": true
            },
            "ready_at": "2019-08-24T14:15:22Z",
            "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
            "scripts": [
              {
                "cron": "string",
                "display_name": "string",
                "exit_code": 0,
                "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "log_path": "string",
                "log_source_id": "4197ab25-95cf-4b91-9c78-f7f2af5d353a",
                "run_on_start": true,
                "run_on_stop": true,
                "script": "string",
                "start_blocks_login": true,
                "status": "ok",
                "timeout": 0
              }
            ],
            "started_at": "2019-08-24T14:15:22Z",
            "startup_script_behavior": "blocking",
            "status": "connecting",
            "subsystems": [
              "envbox"
            ],
            "troubleshooting_url": "string",
            "updated_at": "2019-08-24T14:15:22Z",
            "version": "string"
          }
        ],
        "created_at": "2019-08-24T14:15:22Z",
        "daily_cost": 0,
        "hide": true,
        "icon": "string",
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
        "metadata": [
          {
            "key": "string",
            "sensitive": true,
            "value": "string"
          }
        ],
        "name": "string",
        "type": "string",
        "workspace_transition": "start"
      }
    ],
    "status": "pending",
    "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1",
    "template_version_name": "string",
    "template_version_preset_id": "512a53a7-30da-446e-a1fc-713c630baff1",
    "transition": "start",
    "updated_at": "2019-08-24T14:15:22Z",
    "workspace_id": "0967198e-ec7b-4c6b-b4d3-f71244cadbe9",
    "workspace_name": "string",
    "workspace_owner_avatar_url": "string",
    "workspace_owner_id": "e7078695-5279-4c86-8774-3ac2367a2fc7",
    "workspace_owner_name": "string"
  },
  "name": "string",
  "next_start_at": "2019-08-24T14:15:22Z",
  "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
  "organization_name": "string",
  "outdated": true,
  "owner_avatar_url": "string",
  "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05",
  "owner_name": "string",
  "shared_with": [
    {
      "actor_type": "group",
      "avatar_url": "http://example.com",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "name": "string",
      "roles": [
        "admin"
      ]
    }
  ],
  "task_id": {
    "uuid": "string",
    "valid": true
  },
  "template_active_version_id": "b0da9c29-67d8-4c87-888c-bafe356f7f3c",
  "template_allow_user_cancel_workspace_jobs": true,
  "template_display_name": "string",
  "template_icon": "string",
  "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
  "template_name": "string",
  "template_require_active_version": true,
  "template_use_classic_parameter_flow": true,
  "ttl_ms": 0,
  "updated_at": "2019-08-24T14:15:22Z"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Workspace](schemas.md#codersdkworkspace) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Extend workspace deadline by ID

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/extend \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/workspaces/{workspace}/extend`

> Body parameter

```json
{
  "deadline": "2019-08-24T14:15:22Z"
}
```

### Parameters

| Name        | In   | Type                                                                               | Required | Description                    |
|-------------|------|------------------------------------------------------------------------------------|----------|--------------------------------|
| `workspace` | path | string(uuid)                                                                       | true     | Workspace ID                   |
| `body`      | body | [codersdk.PutExtendWorkspaceRequest](schemas.md#codersdkputextendworkspacerequest) | true     | Extend deadline update request |

### Example responses

> 200 Response

```json
{
  "detail": "string",
  "message": "string",
  "validations": [
    {
      "detail": "string",
      "field": "string"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Favorite workspace by ID

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/favorite \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/workspaces/{workspace}/favorite`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Unfavorite workspace by ID

### Code samples

```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/workspaces/{workspace}/favorite \
  -H 'Coder-Session-Token: API_KEY'
```

`DELETE /api/v2/workspaces/{workspace}/favorite`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Resolve workspace autostart by id

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/resolve-autostart \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/resolve-autostart`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Example responses

> 200 Response

```json
{
  "parameter_mismatch": true
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                           |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ResolveAutostartResponse](schemas.md#codersdkresolveautostartresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Get workspace timings by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/timings \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/timings`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Example responses

> 200 Response

```json
{
  "agent_connection_timings": [
    {
      "ended_at": "2019-08-24T14:15:22Z",
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z",
      "workspace_agent_id": "string",
      "workspace_agent_name": "string"
    }
  ],
  "agent_script_timings": [
    {
      "display_name": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "exit_code": 0,
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z",
      "status": "string",
      "workspace_agent_id": "string",
      "workspace_agent_name": "string"
    }
  ],
  "provisioner_timings": [
    {
      "action": "string",
      "ended_at": "2019-08-24T14:15:22Z",
      "job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
      "resource": "string",
      "source": "string",
      "stage": "init",
      "started_at": "2019-08-24T14:15:22Z"
    }
  ]
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                                     |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.WorkspaceBuildTimings](schemas.md#codersdkworkspacebuildtimings) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Update workspace TTL by ID

### Code samples

```shell
# Example request using curl
curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/ttl \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`PUT /api/v2/workspaces/{workspace}/ttl`

> Body parameter

```json
{
  "ttl_ms": 0
}
```

### Parameters

| Name        | In   | Type                                                                               | Required | Description                  |
|-------------|------|------------------------------------------------------------------------------------|----------|------------------------------|
| `workspace` | path | string(uuid)                                                                       | true     | Workspace ID                 |
| `body`      | body | [codersdk.UpdateWorkspaceTTLRequest](schemas.md#codersdkupdateworkspacettlrequest) | true     | Workspace TTL update request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Post Workspace Usage by ID

### Code samples

```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/usage \
  -H 'Content-Type: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`POST /api/v2/workspaces/{workspace}/usage`

> Body parameter

```json
{
  "agent_id": "2b1e3b65-2c04-4fa2-a2d7-467901e98978",
  "app_name": "vscode"
}
```

### Parameters

| Name        | In   | Type                                                                               | Required | Description                  |
|-------------|------|------------------------------------------------------------------------------------|----------|------------------------------|
| `workspace` | path | string(uuid)                                                                       | true     | Workspace ID                 |
| `body`      | body | [codersdk.PostWorkspaceUsageRequest](schemas.md#codersdkpostworkspaceusagerequest) | false    | Post workspace usage request |

### Responses

| Status | Meaning                                                         | Description | Schema |
|--------|-----------------------------------------------------------------|-------------|--------|
| 204    | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content  |        |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Watch workspace by ID

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/watch \
  -H 'Accept: text/event-stream' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/watch`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Example responses

> 200 Response

### Responses

| Status | Meaning                                                 | Description | Schema                                           |
|--------|---------------------------------------------------------|-------------|--------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.Response](schemas.md#codersdkresponse) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

## Watch workspace by ID via WebSockets

### Code samples

```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/watch-ws \
  -H 'Accept: application/json' \
  -H 'Coder-Session-Token: API_KEY'
```

`GET /api/v2/workspaces/{workspace}/watch-ws`

### Parameters

| Name        | In   | Type         | Required | Description  |
|-------------|------|--------------|----------|--------------|
| `workspace` | path | string(uuid) | true     | Workspace ID |

### Example responses

> 200 Response

```json
{
  "data": null,
  "type": "ping"
}
```

### Responses

| Status | Meaning                                                 | Description | Schema                                                         |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [codersdk.ServerSentEvent](schemas.md#codersdkserversentevent) |

To perform this operation, you must be authenticated. [Learn more](authentication.md).

---

# Command Line

Source: https://coder.com/docs/reference/cli

<!-- DO NOT EDIT | GENERATED CONTENT -->
# coder

## Usage

```console
coder [global-flags] <subcommand>
```

## Description

```console
Coder — A tool for provisioning self-hosted development environments with Terraform.
  - Start a Coder server:

     $ coder server

  - Get started by creating a template from an example:

     $ coder templates init
```

## Subcommands

| Name                                                         | Purpose                                                                                                                      |
|--------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
| [<code>agents</code>](./agents.md)                           | Interactive terminal UI for AI agents.                                                                                       |
| [<code>completion</code>](./completion.md)                   | Install or update shell completion scripts for the detected or chosen shell.                                                 |
| [<code>dotfiles</code>](./dotfiles.md)                       | Personalize your workspace by applying a canonical dotfiles repository                                                       |
| [<code>external-auth</code>](./external-auth.md)             | Manage external authentication                                                                                               |
| [<code>login</code>](./login.md)                             | Authenticate with Coder deployment                                                                                           |
| [<code>logout</code>](./logout.md)                           | Unauthenticate your local session                                                                                            |
| [<code>netcheck</code>](./netcheck.md)                       | Print network debug information for DERP and STUN                                                                            |
| [<code>notifications</code>](./notifications.md)             | Manage Coder notifications                                                                                                   |
| [<code>organizations</code>](./organizations.md)             | Organization related commands                                                                                                |
| [<code>port-forward</code>](./port-forward.md)               | Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".                        |
| [<code>publickey</code>](./publickey.md)                     | Output your Coder public key used for Git operations                                                                         |
| [<code>reset-password</code>](./reset-password.md)           | Directly connect to the database to reset a user's password                                                                  |
| [<code>secret</code>](./secret.md)                           | Manage secrets                                                                                                               |
| [<code>state</code>](./state.md)                             | Manually manage Terraform state to fix broken workspaces                                                                     |
| [<code>task</code>](./task.md)                               | Manage tasks                                                                                                                 |
| [<code>templates</code>](./templates.md)                     | Manage templates                                                                                                             |
| [<code>tokens</code>](./tokens.md)                           | Manage personal access tokens                                                                                                |
| [<code>users</code>](./users.md)                             | Manage users                                                                                                                 |
| [<code>version</code>](./version.md)                         | Show coder version                                                                                                           |
| [<code>autoupdate</code>](./autoupdate.md)                   | Toggle auto-update policy for a workspace                                                                                    |
| [<code>config-ssh</code>](./config-ssh.md)                   | Add an SSH Host entry for your workspaces "ssh workspace.coder"                                                              |
| [<code>create</code>](./create.md)                           | Create a workspace                                                                                                           |
| [<code>delete</code>](./delete.md)                           | Delete a workspace                                                                                                           |
| [<code>favorite</code>](./favorite.md)                       | Add a workspace to your favorites                                                                                            |
| [<code>list</code>](./list.md)                               | List workspaces                                                                                                              |
| [<code>logs</code>](./logs.md)                               | View logs for a workspace                                                                                                    |
| [<code>open</code>](./open.md)                               | Open a workspace                                                                                                             |
| [<code>ping</code>](./ping.md)                               | Ping a workspace                                                                                                             |
| [<code>rename</code>](./rename.md)                           | Rename a workspace                                                                                                           |
| [<code>restart</code>](./restart.md)                         | Restart a workspace                                                                                                          |
| [<code>schedule</code>](./schedule.md)                       | Schedule automated start and stop times for workspaces                                                                       |
| [<code>show</code>](./show.md)                               | Display details of a workspace's resources and agents                                                                        |
| [<code>speedtest</code>](./speedtest.md)                     | Run upload and download tests from your machine to a workspace                                                               |
| [<code>ssh</code>](./ssh.md)                                 | Start a shell into a workspace or run a command                                                                              |
| [<code>start</code>](./start.md)                             | Start a workspace                                                                                                            |
| [<code>stat</code>](./stat.md)                               | Show resource usage for the current workspace.                                                                               |
| [<code>stop</code>](./stop.md)                               | Stop a workspace                                                                                                             |
| [<code>unfavorite</code>](./unfavorite.md)                   | Remove a workspace from your favorites                                                                                       |
| [<code>update</code>](./update.md)                           | Will update and start a given workspace if it is out of date. If the workspace is already running, it will be stopped first. |
| [<code>whoami</code>](./whoami.md)                           | Fetch authenticated user info for Coder deployment                                                                           |
| [<code>support</code>](./support.md)                         | Commands for troubleshooting issues with a Coder deployment.                                                                 |
| [<code>server</code>](./server.md)                           | Start a Coder server                                                                                                         |
| [<code>provisioner</code>](./provisioner.md)                 | View and manage provisioner daemons and jobs                                                                                 |
| [<code>boundary</code>](./boundary.md)                       | Network isolation tool for monitoring and restricting HTTP/HTTPS requests                                                    |
| [<code>features</code>](./features.md)                       | List Enterprise features                                                                                                     |
| [<code>licenses</code>](./licenses.md)                       | Add, delete, and list licenses                                                                                               |
| [<code>groups</code>](./groups.md)                           | Manage groups                                                                                                                |
| [<code>prebuilds</code>](./prebuilds.md)                     | Manage Coder prebuilds                                                                                                       |
| [<code>external-workspaces</code>](./external-workspaces.md) | Create or manage external workspaces                                                                                         |
| [<code>aibridge</code>](./aibridge.md)                       | Manage AI Bridge.                                                                                                            |

## Options

### --url

|             |                         |
|-------------|-------------------------|
| Type        | <code>url</code>        |
| Environment | <code>$CODER_URL</code> |

URL to a deployment.

### --debug-options

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Print all options, how they're set, then exit.

### --token

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>string</code>               |
| Environment | <code>$CODER_SESSION_TOKEN</code> |

Specify an authentication token. For security reasons setting CODER_SESSION_TOKEN is preferred.

### --no-version-warning

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>bool</code>                      |
| Environment | <code>$CODER_NO_VERSION_WARNING</code> |

Suppress warning when client and server versions do not match.

### --no-feature-warning

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>bool</code>                      |
| Environment | <code>$CODER_NO_FEATURE_WARNING</code> |

Suppress warnings about unlicensed features.

### --header

|             |                            |
|-------------|----------------------------|
| Type        | <code>string-array</code>  |
| Environment | <code>$CODER_HEADER</code> |

Additional HTTP headers added to all requests. Provide as key=value. Can be specified multiple times.

### --header-command

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string</code>                |
| Environment | <code>$CODER_HEADER_COMMAND</code> |

An external command that outputs additional HTTP headers added to all requests. The command must output each header as `key=value` on its own line.

### --force-tty

|             |                               |
|-------------|-------------------------------|
| Type        | <code>bool</code>             |
| Environment | <code>$CODER_FORCE_TTY</code> |

Force the use of a TTY.

### -v, --verbose

|             |                             |
|-------------|-----------------------------|
| Type        | <code>bool</code>           |
| Environment | <code>$CODER_VERBOSE</code> |

Enable verbose output.

### --disable-direct-connections

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_DISABLE_DIRECT_CONNECTIONS</code> |

Disable direct (P2P) connections to workspaces.

### --disable-network-telemetry

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>bool</code>                             |
| Environment | <code>$CODER_DISABLE_NETWORK_TELEMETRY</code> |

Disable network telemetry. Network telemetry is collected when connecting to workspaces using the CLI, and is forwarded to the server. If telemetry is also enabled on the server, it may be sent to Coder. Network telemetry is used to measure network quality and detect regressions.

### --client-tls-ca-file

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_CLIENT_TLS_CA_FILE</code> |

Path to a CA certificate file to trust for API and DERP connections.

### --client-tls-cert-file

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_CLIENT_TLS_CERT_FILE</code> |

Path to a client certificate file for mTLS authentication with API and DERP. Requires --client-tls-key-file.

### --client-tls-key-file

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_CLIENT_TLS_KEY_FILE</code> |

Path to a client private key file for mTLS authentication with API and DERP. Requires --client-tls-cert-file.

### --use-keyring

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>bool</code>               |
| Environment | <code>$CODER_USE_KEYRING</code> |
| Default     | <code>true</code>               |

Store and retrieve session tokens using the operating system keyring. This flag is ignored and file-based storage is used when --global-config is set or keyring usage is not supported on the current platform. Set to false to force file-based storage on supported platforms.

### --global-config

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_CONFIG_DIR</code> |
| Default     | <code>~/.config/coderv2</code> |

Path to the global `coder` config directory.

---

# aibridge

Source: https://coder.com/docs/reference/cli/aibridge

<!-- DO NOT EDIT | GENERATED CONTENT -->
# aibridge

Manage AI Bridge.

## Usage

```console
coder aibridge
```

## Subcommands

| Name                                                      | Purpose                         |
|-----------------------------------------------------------|---------------------------------|
| [<code>interceptions</code>](./aibridge_interceptions.md) | Manage AI Bridge interceptions. |

---

# aibridge interceptions

Source: https://coder.com/docs/reference/cli/aibridge_interceptions

<!-- DO NOT EDIT | GENERATED CONTENT -->
# aibridge interceptions

Manage AI Bridge interceptions.

## Usage

```console
coder aibridge interceptions
```

## Subcommands

| Name                                                  | Purpose                               |
|-------------------------------------------------------|---------------------------------------|
| [<code>list</code>](./aibridge_interceptions_list.md) | List AI Bridge interceptions as JSON. |

---

# aibridge interceptions list

Source: https://coder.com/docs/reference/cli/aibridge_interceptions_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# aibridge interceptions list

List AI Bridge interceptions as JSON.

## Usage

```console
coder aibridge interceptions list [flags]
```

## Options

### --initiator

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Only return interceptions initiated by this user. Accepts a user ID, username, or "me".

### --started-before

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Only return interceptions started before this time. Must be after 'started-after' if set. Accepts a time in the RFC 3339 format, e.g. "2006-01-02T15:04:05Z07:00".

### --started-after

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Only return interceptions started after this time. Must be before 'started-before' if set. Accepts a time in the RFC 3339 format, e.g. "2006-01-02T15:04:05Z07:00".

### --provider

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Only return interceptions from this provider.

### --model

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Only return interceptions from this model.

### --client

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Only return interceptions from this client.

### --after-id

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

The ID of the last result on the previous page to use as a pagination cursor.

### --limit

|         |                  |
|---------|------------------|
| Type    | <code>int</code> |
| Default | <code>100</code> |

The limit of results to return. Must be between 1 and 1000.

---

# autoupdate

Source: https://coder.com/docs/reference/cli/autoupdate

<!-- DO NOT EDIT | GENERATED CONTENT -->
# autoupdate

Toggle auto-update policy for a workspace

## Usage

```console
coder autoupdate [flags] <workspace> <always|never>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# boundary

Source: https://coder.com/docs/reference/cli/boundary

<!-- DO NOT EDIT | GENERATED CONTENT -->
# boundary

Network isolation tool for monitoring and restricting HTTP/HTTPS requests

## Usage

```console
coder boundary [flags] [args...]
```

## Description

```console
boundary creates an isolated network environment for target processes, intercepting HTTP/HTTPS traffic through a transparent proxy that enforces user-defined allow rules.
```

## Options

### --config

|             |                               |
|-------------|-------------------------------|
| Type        | <code>yaml-config-path</code> |
| Environment | <code>$BOUNDARY_CONFIG</code> |

Path to YAML config file.

### --allow

|             |                              |
|-------------|------------------------------|
| Type        | <code>string</code>          |
| Environment | <code>$BOUNDARY_ALLOW</code> |

Allow rule (repeatable). These are merged with allowlist from config file. Format: "pattern" or "METHOD[,METHOD] pattern".

### --

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |
| YAML | <code>allowlist</code>    |

Allowlist rules from config file (YAML only).

### --log-level

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$BOUNDARY_LOG_LEVEL</code> |
| YAML        | <code>log_level</code>           |
| Default     | <code>warn</code>                |

Set log level (error, warn, info, debug).

### --log-dir

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$BOUNDARY_LOG_DIR</code> |
| YAML        | <code>log_dir</code>           |

Set a directory to write logs to rather than stderr.

### --proxy-port

|             |                          |
|-------------|--------------------------|
| Type        | <code>int</code>         |
| Environment | <code>$PROXY_PORT</code> |
| YAML        | <code>proxy_port</code>  |
| Default     | <code>8080</code>        |

Set a port for HTTP proxy.

### --pprof

|             |                              |
|-------------|------------------------------|
| Type        | <code>bool</code>            |
| Environment | <code>$BOUNDARY_PPROF</code> |
| YAML        | <code>pprof_enabled</code>   |

Enable pprof profiling server.

### --pprof-port

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>int</code>                  |
| Environment | <code>$BOUNDARY_PPROF_PORT</code> |
| YAML        | <code>pprof_port</code>           |
| Default     | <code>6060</code>                 |

Set port for pprof profiling server.

### --jail-type

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$BOUNDARY_JAIL_TYPE</code> |
| YAML        | <code>jail_type</code>           |
| Default     | <code>nsjail</code>              |

Jail type to use for network isolation. Options: nsjail (default), landjail.

### --use-real-dns

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>bool</code>                   |
| Environment | <code>$BOUNDARY_USE_REAL_DNS</code> |
| YAML        | <code>use_real_dns</code>           |

Use real DNS in the jail instead of the dummy DNS (allows DNS exfiltration). Default: false.

### --no-user-namespace

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>bool</code>                        |
| Environment | <code>$BOUNDARY_NO_USER_NAMESPACE</code> |
| YAML        | <code>no_user_namespace</code>           |

Do not create a user namespace. Use in restricted environments that disallow user NS (e.g. Bottlerocket in EKS auto-mode).

### --disable-audit-logs

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>bool</code>                |
| Environment | <code>$DISABLE_AUDIT_LOGS</code> |
| YAML        | <code>disable_audit_logs</code>  |

Disable sending of audit logs to the workspace agent when set to true.

### --log-proxy-socket-path

|             |                                                          |
|-------------|----------------------------------------------------------|
| Type        | <code>string</code>                                      |
| Environment | <code>$CODER_AGENT_BOUNDARY_LOG_PROXY_SOCKET_PATH</code> |
| Default     | <code>/tmp/boundary-audit.sock</code>                    |

Path to the socket where the boundary log proxy server listens for audit logs.

### --version

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Print version information and exit.

---

# coder

Source: https://coder.com/docs/reference/cli

<!-- DO NOT EDIT | GENERATED CONTENT -->
# coder

## Usage

```console
coder [global-flags] <subcommand>
```

## Description

```console
Coder — A tool for provisioning self-hosted development environments with Terraform.
  - Start a Coder server:

     $ coder server

  - Get started by creating a template from an example:

     $ coder templates init
```

## Subcommands

| Name                                                         | Purpose                                                                                                                      |
|--------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
| [<code>agents</code>](./agents.md)                           | Interactive terminal UI for AI agents.                                                                                       |
| [<code>completion</code>](./completion.md)                   | Install or update shell completion scripts for the detected or chosen shell.                                                 |
| [<code>dotfiles</code>](./dotfiles.md)                       | Personalize your workspace by applying a canonical dotfiles repository                                                       |
| [<code>external-auth</code>](./external-auth.md)             | Manage external authentication                                                                                               |
| [<code>login</code>](./login.md)                             | Authenticate with Coder deployment                                                                                           |
| [<code>logout</code>](./logout.md)                           | Unauthenticate your local session                                                                                            |
| [<code>netcheck</code>](./netcheck.md)                       | Print network debug information for DERP and STUN                                                                            |
| [<code>notifications</code>](./notifications.md)             | Manage Coder notifications                                                                                                   |
| [<code>organizations</code>](./organizations.md)             | Organization related commands                                                                                                |
| [<code>port-forward</code>](./port-forward.md)               | Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".                        |
| [<code>publickey</code>](./publickey.md)                     | Output your Coder public key used for Git operations                                                                         |
| [<code>reset-password</code>](./reset-password.md)           | Directly connect to the database to reset a user's password                                                                  |
| [<code>secret</code>](./secret.md)                           | Manage secrets                                                                                                               |
| [<code>state</code>](./state.md)                             | Manually manage Terraform state to fix broken workspaces                                                                     |
| [<code>task</code>](./task.md)                               | Manage tasks                                                                                                                 |
| [<code>templates</code>](./templates.md)                     | Manage templates                                                                                                             |
| [<code>tokens</code>](./tokens.md)                           | Manage personal access tokens                                                                                                |
| [<code>users</code>](./users.md)                             | Manage users                                                                                                                 |
| [<code>version</code>](./version.md)                         | Show coder version                                                                                                           |
| [<code>autoupdate</code>](./autoupdate.md)                   | Toggle auto-update policy for a workspace                                                                                    |
| [<code>config-ssh</code>](./config-ssh.md)                   | Add an SSH Host entry for your workspaces "ssh workspace.coder"                                                              |
| [<code>create</code>](./create.md)                           | Create a workspace                                                                                                           |
| [<code>delete</code>](./delete.md)                           | Delete a workspace                                                                                                           |
| [<code>favorite</code>](./favorite.md)                       | Add a workspace to your favorites                                                                                            |
| [<code>list</code>](./list.md)                               | List workspaces                                                                                                              |
| [<code>logs</code>](./logs.md)                               | View logs for a workspace                                                                                                    |
| [<code>open</code>](./open.md)                               | Open a workspace                                                                                                             |
| [<code>ping</code>](./ping.md)                               | Ping a workspace                                                                                                             |
| [<code>rename</code>](./rename.md)                           | Rename a workspace                                                                                                           |
| [<code>restart</code>](./restart.md)                         | Restart a workspace                                                                                                          |
| [<code>schedule</code>](./schedule.md)                       | Schedule automated start and stop times for workspaces                                                                       |
| [<code>show</code>](./show.md)                               | Display details of a workspace's resources and agents                                                                        |
| [<code>speedtest</code>](./speedtest.md)                     | Run upload and download tests from your machine to a workspace                                                               |
| [<code>ssh</code>](./ssh.md)                                 | Start a shell into a workspace or run a command                                                                              |
| [<code>start</code>](./start.md)                             | Start a workspace                                                                                                            |
| [<code>stat</code>](./stat.md)                               | Show resource usage for the current workspace.                                                                               |
| [<code>stop</code>](./stop.md)                               | Stop a workspace                                                                                                             |
| [<code>unfavorite</code>](./unfavorite.md)                   | Remove a workspace from your favorites                                                                                       |
| [<code>update</code>](./update.md)                           | Will update and start a given workspace if it is out of date. If the workspace is already running, it will be stopped first. |
| [<code>whoami</code>](./whoami.md)                           | Fetch authenticated user info for Coder deployment                                                                           |
| [<code>support</code>](./support.md)                         | Commands for troubleshooting issues with a Coder deployment.                                                                 |
| [<code>server</code>](./server.md)                           | Start a Coder server                                                                                                         |
| [<code>provisioner</code>](./provisioner.md)                 | View and manage provisioner daemons and jobs                                                                                 |
| [<code>boundary</code>](./boundary.md)                       | Network isolation tool for monitoring and restricting HTTP/HTTPS requests                                                    |
| [<code>features</code>](./features.md)                       | List Enterprise features                                                                                                     |
| [<code>licenses</code>](./licenses.md)                       | Add, delete, and list licenses                                                                                               |
| [<code>groups</code>](./groups.md)                           | Manage groups                                                                                                                |
| [<code>prebuilds</code>](./prebuilds.md)                     | Manage Coder prebuilds                                                                                                       |
| [<code>external-workspaces</code>](./external-workspaces.md) | Create or manage external workspaces                                                                                         |
| [<code>aibridge</code>](./aibridge.md)                       | Manage AI Bridge.                                                                                                            |

## Options

### --url

|             |                         |
|-------------|-------------------------|
| Type        | <code>url</code>        |
| Environment | <code>$CODER_URL</code> |

URL to a deployment.

### --debug-options

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Print all options, how they're set, then exit.

### --token

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>string</code>               |
| Environment | <code>$CODER_SESSION_TOKEN</code> |

Specify an authentication token. For security reasons setting CODER_SESSION_TOKEN is preferred.

### --no-version-warning

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>bool</code>                      |
| Environment | <code>$CODER_NO_VERSION_WARNING</code> |

Suppress warning when client and server versions do not match.

### --no-feature-warning

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>bool</code>                      |
| Environment | <code>$CODER_NO_FEATURE_WARNING</code> |

Suppress warnings about unlicensed features.

### --header

|             |                            |
|-------------|----------------------------|
| Type        | <code>string-array</code>  |
| Environment | <code>$CODER_HEADER</code> |

Additional HTTP headers added to all requests. Provide as key=value. Can be specified multiple times.

### --header-command

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string</code>                |
| Environment | <code>$CODER_HEADER_COMMAND</code> |

An external command that outputs additional HTTP headers added to all requests. The command must output each header as `key=value` on its own line.

### --force-tty

|             |                               |
|-------------|-------------------------------|
| Type        | <code>bool</code>             |
| Environment | <code>$CODER_FORCE_TTY</code> |

Force the use of a TTY.

### -v, --verbose

|             |                             |
|-------------|-----------------------------|
| Type        | <code>bool</code>           |
| Environment | <code>$CODER_VERBOSE</code> |

Enable verbose output.

### --disable-direct-connections

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_DISABLE_DIRECT_CONNECTIONS</code> |

Disable direct (P2P) connections to workspaces.

### --disable-network-telemetry

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>bool</code>                             |
| Environment | <code>$CODER_DISABLE_NETWORK_TELEMETRY</code> |

Disable network telemetry. Network telemetry is collected when connecting to workspaces using the CLI, and is forwarded to the server. If telemetry is also enabled on the server, it may be sent to Coder. Network telemetry is used to measure network quality and detect regressions.

### --client-tls-ca-file

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_CLIENT_TLS_CA_FILE</code> |

Path to a CA certificate file to trust for API and DERP connections.

### --client-tls-cert-file

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_CLIENT_TLS_CERT_FILE</code> |

Path to a client certificate file for mTLS authentication with API and DERP. Requires --client-tls-key-file.

### --client-tls-key-file

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_CLIENT_TLS_KEY_FILE</code> |

Path to a client private key file for mTLS authentication with API and DERP. Requires --client-tls-cert-file.

### --use-keyring

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>bool</code>               |
| Environment | <code>$CODER_USE_KEYRING</code> |
| Default     | <code>true</code>               |

Store and retrieve session tokens using the operating system keyring. This flag is ignored and file-based storage is used when --global-config is set or keyring usage is not supported on the current platform. Set to false to force file-based storage on supported platforms.

### --global-config

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_CONFIG_DIR</code> |
| Default     | <code>~/.config/coderv2</code> |

Path to the global `coder` config directory.

---

# completion

Source: https://coder.com/docs/reference/cli/completion

<!-- DO NOT EDIT | GENERATED CONTENT -->
# completion

Install or update shell completion scripts for the detected or chosen shell.

## Usage

```console
coder completion [flags]
```

## Options

### -s, --shell

|      |                                          |
|------|------------------------------------------|
| Type | <code>bash\|fish\|zsh\|powershell</code> |

The shell to install completion for.

### -p, --print

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Print the completion script instead of installing it.

---

# config-ssh

Source: https://coder.com/docs/reference/cli/config-ssh

<!-- DO NOT EDIT | GENERATED CONTENT -->
# config-ssh

Add an SSH Host entry for your workspaces "ssh workspace.coder"

## Usage

```console
coder config-ssh [flags]
```

## Description

```console
  - You can use -o (or --ssh-option) so set SSH options to be used for all your
workspaces:

     $ coder config-ssh -o ForwardAgent=yes

  - You can use --dry-run (or -n) to see the changes that would be made:

     $ coder config-ssh --dry-run
```

## Options

### --ssh-config-file

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_SSH_CONFIG_FILE</code> |
| Default     | <code>~/.ssh/config</code>          |

Specifies the path to an SSH config.

### --coder-binary-path

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string</code>                        |
| Environment | <code>$CODER_SSH_CONFIG_BINARY_PATH</code> |

Optionally specify the absolute path to the coder binary used in ProxyCommand. By default, the binary invoking this command ('config ssh') is used.

### -o, --ssh-option

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string-array</code>           |
| Environment | <code>$CODER_SSH_CONFIG_OPTS</code> |

Specifies additional SSH options to embed in each host stanza.

### -n, --dry-run

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>bool</code>               |
| Environment | <code>$CODER_SSH_DRY_RUN</code> |

Perform a trial run with no changes made, showing a diff at the end.

### --use-previous-options

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>bool</code>                            |
| Environment | <code>$CODER_SSH_USE_PREVIOUS_OPTIONS</code> |

Specifies whether or not to keep options from previous run of config-ssh.

### --ssh-host-prefix

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>string</code>                           |
| Environment | <code>$CODER_CONFIGSSH_SSH_HOST_PREFIX</code> |

Override the default host prefix.

### --hostname-suffix

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>string</code>                           |
| Environment | <code>$CODER_CONFIGSSH_HOSTNAME_SUFFIX</code> |

Override the default hostname suffix.

### --wait

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>yes\|no\|auto</code>         |
| Environment | <code>$CODER_CONFIGSSH_WAIT</code> |
| Default     | <code>auto</code>                  |

Specifies whether or not to wait for the startup script to finish executing. Auto means that the agent startup script behavior configured in the workspace template is used.

### --disable-autostart

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_CONFIGSSH_DISABLE_AUTOSTART</code> |
| Default     | <code>false</code>                              |

Disable starting the workspace automatically when connecting via SSH.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# create

Source: https://coder.com/docs/reference/cli/create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# create

Create a workspace

## Usage

```console
coder create [flags] [workspace]
```

## Description

```console
  - Create a workspace for another user (if you have permission):

     $ coder create <username>/<workspace_name>
```

## Options

### -t, --template

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>string</code>               |
| Environment | <code>$CODER_TEMPLATE_NAME</code> |

Specify a template name.

### --template-version

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_TEMPLATE_VERSION</code> |

Specify a template version name.

### --preset

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string</code>             |
| Environment | <code>$CODER_PRESET_NAME</code> |

Specify the name of a template version preset. Use 'none' to explicitly indicate that no preset should be used.

### --start-at

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_WORKSPACE_START_AT</code> |

Specify the workspace autostart schedule. Check coder schedule start --help for the syntax.

### --stop-after

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>duration</code>                    |
| Environment | <code>$CODER_WORKSPACE_STOP_AFTER</code> |

Specify a duration after which the workspace should shut down (e.g. 8h).

### --automatic-updates

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string</code>                             |
| Environment | <code>$CODER_WORKSPACE_AUTOMATIC_UPDATES</code> |
| Default     | <code>never</code>                              |

Specify automatic updates setting for the workspace (accepts 'always' or 'never').

### --copy-parameters-from

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>string</code>                                |
| Environment | <code>$CODER_WORKSPACE_COPY_PARAMETERS_FROM</code> |

Specify the source workspace name to copy parameters from.

### --no-wait

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>bool</code>                  |
| Environment | <code>$CODER_CREATE_NO_WAIT</code> |

Return immediately after creating the workspace. The build will run in the background.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --parameter

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string-array</code>          |
| Environment | <code>$CODER_RICH_PARAMETER</code> |

Rich parameter value in the format "name=value".

### --rich-parameter-file

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_RICH_PARAMETER_FILE</code> |

Specify a file path with values for rich parameters defined in the template. The file should be in YAML format, containing key-value pairs for the parameters.

### --parameter-default

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string-array</code>                  |
| Environment | <code>$CODER_RICH_PARAMETER_DEFAULT</code> |

Rich parameter default values in the format "name=value".

### --use-parameter-defaults

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_WORKSPACE_USE_PARAMETER_DEFAULTS</code> |

Automatically accept parameter defaults when no value is provided.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# delete

Source: https://coder.com/docs/reference/cli/delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# delete

Delete a workspace

Aliases:

* rm

## Usage

```console
coder delete [flags] <workspace>
```

## Description

```console
  - Delete a workspace for another user (if you have permission):

     $ coder delete <username>/<workspace_name>
```

## Options

### --orphan

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Delete a workspace without deleting its resources. This can delete a workspace in a broken state, but may also lead to unaccounted cloud resources.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# dotfiles

Source: https://coder.com/docs/reference/cli/dotfiles

<!-- DO NOT EDIT | GENERATED CONTENT -->
# dotfiles

Personalize your workspace by applying a canonical dotfiles repository

## Usage

```console
coder dotfiles [flags] <git_repo_url>
```

## Description

```console
  - Check out and install a dotfiles repository without prompts:

     $ coder dotfiles --yes git@github.com:example/dotfiles.git
```

## Options

### --symlink-dir

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string</code>             |
| Environment | <code>$CODER_SYMLINK_DIR</code> |

Specifies the directory for the dotfiles symlink destinations. If empty, will use $HOME.

### -b, --branch

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specifies which branch to clone. If empty, will default to cloning the default branch or using the existing branch in the cloned repo on disk.

### --repo-dir

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string</code>                   |
| Environment | <code>$CODER_DOTFILES_REPO_DIR</code> |
| Default     | <code>dotfiles</code>                 |

Specifies the directory for the dotfiles repository, relative to global config directory.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# external-auth

Source: https://coder.com/docs/reference/cli/external-auth

<!-- DO NOT EDIT | GENERATED CONTENT -->
# external-auth

Manage external authentication

## Usage

```console
coder external-auth
```

## Description

```console
Authenticate with external services inside of a workspace.
```

## Subcommands

| Name                                                         | Purpose                             |
|--------------------------------------------------------------|-------------------------------------|
| [<code>access-token</code>](./external-auth_access-token.md) | Print auth for an external provider |

---

# external-auth access-token

Source: https://coder.com/docs/reference/cli/external-auth_access-token

<!-- DO NOT EDIT | GENERATED CONTENT -->
# external-auth access-token

Print auth for an external provider

## Usage

```console
coder external-auth access-token [flags] <provider>
```

## Description

```console
Print an access-token for an external auth provider. The access-token will be validated and sent to stdout with exit code 0. If a valid access-token cannot be obtained, the URL to authenticate will be sent to stdout with exit code 1
  - Ensure that the user is authenticated with GitHub before cloning.:

     $ #!/usr/bin/env sh

OUTPUT=$(coder external-auth access-token github)
if [ $? -eq 0 ]; then
  echo "Authenticated with GitHub"
else
  echo "Please authenticate with GitHub:"
  echo $OUTPUT
fi


  - Obtain an extra property of an access token for additional metadata.:

     $ coder external-auth access-token slack --extra "authed_user.id"
```

## Options

### --extra

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Extract a field from the "extra" properties of the OAuth token.

### --agent-token

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string</code>             |
| Environment | <code>$CODER_AGENT_TOKEN</code> |

An agent authentication token.

### --agent-token-file

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_AGENT_TOKEN_FILE</code> |

A file containing an agent authentication token.

### --agent-url

|             |                               |
|-------------|-------------------------------|
| Type        | <code>url</code>              |
| Environment | <code>$CODER_AGENT_URL</code> |

URL for an agent to access your deployment.

### --auth

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_AGENT_AUTH</code> |
| Default     | <code>token</code>             |

Specify the authentication type to use for the agent.

### --agent-name

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_AGENT_NAME</code> |

The name of the agent to authenticate as (only applicable for instance identity).

---

# external-workspaces

Source: https://coder.com/docs/reference/cli/external-workspaces

<!-- DO NOT EDIT | GENERATED CONTENT -->
# external-workspaces

Create or manage external workspaces

## Usage

```console
coder external-workspaces [flags] [subcommand]
```

## Subcommands

| Name                                                                           | Purpose                                    |
|--------------------------------------------------------------------------------|--------------------------------------------|
| [<code>create</code>](./external-workspaces_create.md)                         | Create a new external workspace            |
| [<code>agent-instructions</code>](./external-workspaces_agent-instructions.md) | Get the instructions for an external agent |
| [<code>list</code>](./external-workspaces_list.md)                             | List external workspaces                   |

## Options

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# external-workspaces agent-instructions

Source: https://coder.com/docs/reference/cli/external-workspaces_agent-instructions

<!-- DO NOT EDIT | GENERATED CONTENT -->
# external-workspaces agent-instructions

Get the instructions for an external agent

## Usage

```console
coder external-workspaces agent-instructions [flags] [user/]workspace[.agent]
```

## Options

### -o, --output

|         |                         |
|---------|-------------------------|
| Type    | <code>text\|json</code> |
| Default | <code>text</code>       |

Output format.

---

# external-workspaces create

Source: https://coder.com/docs/reference/cli/external-workspaces_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# external-workspaces create

Create a new external workspace

## Usage

```console
coder external-workspaces create [flags] [workspace]
```

## Description

```console
  - Create a workspace for another user (if you have permission):

     $ coder create <username>/<workspace_name>
```

## Options

### -t, --template

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>string</code>               |
| Environment | <code>$CODER_TEMPLATE_NAME</code> |

Specify a template name.

### --template-version

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_TEMPLATE_VERSION</code> |

Specify a template version name.

### --preset

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string</code>             |
| Environment | <code>$CODER_PRESET_NAME</code> |

Specify the name of a template version preset. Use 'none' to explicitly indicate that no preset should be used.

### --start-at

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_WORKSPACE_START_AT</code> |

Specify the workspace autostart schedule. Check coder schedule start --help for the syntax.

### --stop-after

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>duration</code>                    |
| Environment | <code>$CODER_WORKSPACE_STOP_AFTER</code> |

Specify a duration after which the workspace should shut down (e.g. 8h).

### --automatic-updates

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string</code>                             |
| Environment | <code>$CODER_WORKSPACE_AUTOMATIC_UPDATES</code> |
| Default     | <code>never</code>                              |

Specify automatic updates setting for the workspace (accepts 'always' or 'never').

### --copy-parameters-from

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>string</code>                                |
| Environment | <code>$CODER_WORKSPACE_COPY_PARAMETERS_FROM</code> |

Specify the source workspace name to copy parameters from.

### --no-wait

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>bool</code>                  |
| Environment | <code>$CODER_CREATE_NO_WAIT</code> |

Return immediately after creating the workspace. The build will run in the background.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --parameter

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string-array</code>          |
| Environment | <code>$CODER_RICH_PARAMETER</code> |

Rich parameter value in the format "name=value".

### --rich-parameter-file

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_RICH_PARAMETER_FILE</code> |

Specify a file path with values for rich parameters defined in the template. The file should be in YAML format, containing key-value pairs for the parameters.

### --parameter-default

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string-array</code>                  |
| Environment | <code>$CODER_RICH_PARAMETER_DEFAULT</code> |

Rich parameter default values in the format "name=value".

### --use-parameter-defaults

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_WORKSPACE_USE_PARAMETER_DEFAULTS</code> |

Automatically accept parameter defaults when no value is provided.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# external-workspaces list

Source: https://coder.com/docs/reference/cli/external-workspaces_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# external-workspaces list

List external workspaces

Aliases:

* ls

## Usage

```console
coder external-workspaces list [flags]
```

## Options

### -a, --all

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Specifies whether all workspaces will be listed or not.

### --search

|         |                       |
|---------|-----------------------|
| Type    | <code>string</code>   |
| Default | <code>owner:me</code> |

Search for a workspace with a query.

### -c, --column

|         |                                                                                                                                                                                                       |
|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[favorite\|workspace\|organization id\|organization name\|template\|status\|healthy\|last built\|current version\|outdated\|starts at\|starts next\|stops after\|stops next\|daily cost]</code> |
| Default | <code>workspace,template,status,healthy,last built,current version,outdated</code>                                                                                                                    |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# favorite

Source: https://coder.com/docs/reference/cli/favorite

<!-- DO NOT EDIT | GENERATED CONTENT -->
# favorite

Add a workspace to your favorites

Aliases:

* fav
* favourite

## Usage

```console
coder favorite <workspace>
```

---

# features

Source: https://coder.com/docs/reference/cli/features

<!-- DO NOT EDIT | GENERATED CONTENT -->
# features

List Enterprise features

Aliases:

* feature

## Usage

```console
coder features
```

## Subcommands

| Name                                    | Purpose |
|-----------------------------------------|---------|
| [<code>list</code>](./features_list.md) |         |

---

# features list

Source: https://coder.com/docs/reference/cli/features_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# features list

Aliases:

* ls

## Usage

```console
coder features list [flags]
```

## Options

### -c, --column

|         |                                                          |
|---------|----------------------------------------------------------|
| Type    | <code>[name\|entitlement\|enabled\|limit\|actual]</code> |
| Default | <code>name,entitlement,enabled,limit,actual</code>       |

Specify columns to filter in the table.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# groups

Source: https://coder.com/docs/reference/cli/groups

<!-- DO NOT EDIT | GENERATED CONTENT -->
# groups

Manage groups

Aliases:

* group

## Usage

```console
coder groups
```

## Subcommands

| Name                                      | Purpose             |
|-------------------------------------------|---------------------|
| [<code>create</code>](./groups_create.md) | Create a user group |
| [<code>list</code>](./groups_list.md)     | List user groups    |
| [<code>edit</code>](./groups_edit.md)     | Edit a user group   |
| [<code>delete</code>](./groups_delete.md) | Delete a user group |

---

# groups create

Source: https://coder.com/docs/reference/cli/groups_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# groups create

Create a user group

## Usage

```console
coder groups create [flags] <name>
```

## Options

### -u, --avatar-url

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_AVATAR_URL</code> |

Set an avatar for a group.

### --display-name

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_DISPLAY_NAME</code> |

Optional human friendly name for the group.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# groups delete

Source: https://coder.com/docs/reference/cli/groups_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# groups delete

Delete a user group

Aliases:

* rm

## Usage

```console
coder groups delete [flags] <name>
```

## Options

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# groups edit

Source: https://coder.com/docs/reference/cli/groups_edit

<!-- DO NOT EDIT | GENERATED CONTENT -->
# groups edit

Edit a user group

## Usage

```console
coder groups edit [flags] <name>
```

## Options

### -n, --name

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Update the group name.

### -u, --avatar-url

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Update the group avatar.

### --display-name

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_DISPLAY_NAME</code> |

Optional human friendly name for the group.

### -a, --add-users

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Add users to the group. Accepts emails or IDs.

### -r, --rm-users

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Remove users to the group. Accepts emails or IDs.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# groups list

Source: https://coder.com/docs/reference/cli/groups_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# groups list

List user groups

## Usage

```console
coder groups list [flags]
```

## Options

### -c, --column

|         |                                                                         |
|---------|-------------------------------------------------------------------------|
| Type    | <code>[name\|display name\|organization id\|members\|avatar url]</code> |
| Default | <code>name,display name,organization id,members,avatar url</code>       |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# licenses

Source: https://coder.com/docs/reference/cli/licenses

<!-- DO NOT EDIT | GENERATED CONTENT -->
# licenses

Add, delete, and list licenses

Aliases:

* license

## Usage

```console
coder licenses
```

## Subcommands

| Name                                        | Purpose                           |
|---------------------------------------------|-----------------------------------|
| [<code>add</code>](./licenses_add.md)       | Add license to Coder deployment   |
| [<code>list</code>](./licenses_list.md)     | List licenses (including expired) |
| [<code>delete</code>](./licenses_delete.md) | Delete license by ID              |

---

# licenses add

Source: https://coder.com/docs/reference/cli/licenses_add

<!-- DO NOT EDIT | GENERATED CONTENT -->
# licenses add

Add license to Coder deployment

## Usage

```console
coder licenses add [flags] [-f file | -l license]
```

## Options

### -f, --file

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Load license from file.

### -l, --license

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

License string.

### --debug

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Output license claims for debugging.

---

# licenses delete

Source: https://coder.com/docs/reference/cli/licenses_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# licenses delete

Delete license by ID

Aliases:

* del
* rm

## Usage

```console
coder licenses delete <id>
```

---

# licenses list

Source: https://coder.com/docs/reference/cli/licenses_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# licenses list

List licenses (including expired)

Aliases:

* ls

## Usage

```console
coder licenses list [flags]
```

## Options

### -c, --column

|         |                                                                   |
|---------|-------------------------------------------------------------------|
| Type    | <code>[id\|uuid\|uploaded at\|features\|expires at\|trial]</code> |
| Default | <code>ID,UUID,Expires At,Uploaded At,Features</code>              |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# list

Source: https://coder.com/docs/reference/cli/list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# list

List workspaces

Aliases:

* ls

## Usage

```console
coder list [flags]
```

## Options

### -a, --all

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Specifies whether all workspaces will be listed or not.

### --search

|         |                       |
|---------|-----------------------|
| Type    | <code>string</code>   |
| Default | <code>owner:me</code> |

Search for a workspace with a query.

### -c, --column

|         |                                                                                                                                                                                                       |
|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[favorite\|workspace\|organization id\|organization name\|template\|status\|healthy\|last built\|current version\|outdated\|starts at\|starts next\|stops after\|stops next\|daily cost]</code> |
| Default | <code>workspace,template,status,healthy,last built,current version,outdated,starts at,stops after</code>                                                                                              |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# login

Source: https://coder.com/docs/reference/cli/login

<!-- DO NOT EDIT | GENERATED CONTENT -->
# login

Authenticate with Coder deployment

## Usage

```console
coder login [flags] [<url>]
```

## Description

```console
By default, the session token is stored in the operating system keyring on macOS and Windows and a plain text file on Linux. Use the --use-keyring flag or CODER_USE_KEYRING environment variable to change the storage mechanism.
```

## Subcommands

| Name                                   | Purpose                         |
|----------------------------------------|---------------------------------|
| [<code>token</code>](./login_token.md) | Print the current session token |

## Options

### --first-user-email

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_FIRST_USER_EMAIL</code> |

Specifies an email address to use if creating the first user for the deployment.

### --first-user-username

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_FIRST_USER_USERNAME</code> |

Specifies a username to use if creating the first user for the deployment.

### --first-user-full-name

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_FIRST_USER_FULL_NAME</code> |

Specifies a human-readable name for the first user of the deployment.

### --first-user-password

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_FIRST_USER_PASSWORD</code> |

Specifies a password to use if creating the first user for the deployment.

### --first-user-trial

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>bool</code>                    |
| Environment | <code>$CODER_FIRST_USER_TRIAL</code> |

Specifies whether a trial license should be provisioned for the Coder deployment or not.

### --use-token-as-session

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

By default, the CLI will generate a new session token when logging in. This flag will instead use the provided token as the session token.

---

# login token

Source: https://coder.com/docs/reference/cli/login_token

<!-- DO NOT EDIT | GENERATED CONTENT -->
# login token

Print the current session token

## Usage

```console
coder login token
```

## Description

```console
Print the session token for use in scripts and automation.
```

---

# logout

Source: https://coder.com/docs/reference/cli/logout

<!-- DO NOT EDIT | GENERATED CONTENT -->
# logout

Unauthenticate your local session

## Usage

```console
coder logout [flags]
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# logs

Source: https://coder.com/docs/reference/cli/logs

<!-- DO NOT EDIT | GENERATED CONTENT -->
# logs

View logs for a workspace

## Usage

```console
coder logs [flags] <workspace>
```

## Description

```console
View logs for a workspace
```

## Options

### -n, --build-number

|         |                  |
|---------|------------------|
| Type    | <code>int</code> |
| Default | <code>0</code>   |

Only show logs for a specific build number. Defaults to 0, which maps to the most recent build (build numbers start at 1). Negative values are treated as offsets—for example, -1 refers to the previous build.

### -f, --follow

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Follow logs as they are emitted.

---

# netcheck

Source: https://coder.com/docs/reference/cli/netcheck

<!-- DO NOT EDIT | GENERATED CONTENT -->
# netcheck

Print network debug information for DERP and STUN

## Usage

```console
coder netcheck
```

---

# notifications

Source: https://coder.com/docs/reference/cli/notifications

<!-- DO NOT EDIT | GENERATED CONTENT -->
# notifications

Manage Coder notifications

Aliases:

* notification

## Usage

```console
coder notifications
```

## Description

```console
Administrators can use these commands to change notification settings.
  - Pause Coder notifications. Administrators can temporarily stop notifiers from
dispatching messages in case of the target outage (for example: unavailable SMTP
server or Webhook not responding):

     $ coder notifications pause

  - Resume Coder notifications:

     $ coder notifications resume

  - Send a test notification. Administrators can use this to verify the notification
target settings:

     $ coder notifications test

  - Send a custom notification to the requesting user. Sending notifications
targeting other users or groups is currently not supported:

     $ coder notifications custom "Custom Title" "Custom Message"
```

## Subcommands

| Name                                             | Purpose                    |
|--------------------------------------------------|----------------------------|
| [<code>pause</code>](./notifications_pause.md)   | Pause notifications        |
| [<code>resume</code>](./notifications_resume.md) | Resume notifications       |
| [<code>test</code>](./notifications_test.md)     | Send a test notification   |
| [<code>custom</code>](./notifications_custom.md) | Send a custom notification |

---

# notifications custom

Source: https://coder.com/docs/reference/cli/notifications_custom

<!-- DO NOT EDIT | GENERATED CONTENT -->
# notifications custom

Send a custom notification

## Usage

```console
coder notifications custom <title> <message>
```

---

# notifications pause

Source: https://coder.com/docs/reference/cli/notifications_pause

<!-- DO NOT EDIT | GENERATED CONTENT -->
# notifications pause

Pause notifications

## Usage

```console
coder notifications pause
```

---

# notifications resume

Source: https://coder.com/docs/reference/cli/notifications_resume

<!-- DO NOT EDIT | GENERATED CONTENT -->
# notifications resume

Resume notifications

## Usage

```console
coder notifications resume
```

---

# notifications test

Source: https://coder.com/docs/reference/cli/notifications_test

<!-- DO NOT EDIT | GENERATED CONTENT -->
# notifications test

Send a test notification

## Usage

```console
coder notifications test
```

---

# open

Source: https://coder.com/docs/reference/cli/open

<!-- DO NOT EDIT | GENERATED CONTENT -->
# open

Open a workspace

## Usage

```console
coder open
```

## Subcommands

| Name                                    | Purpose                             |
|-----------------------------------------|-------------------------------------|
| [<code>vscode</code>](./open_vscode.md) | Open a workspace in VS Code Desktop |
| [<code>app</code>](./open_app.md)       | Open a workspace application.       |

---

# open app

Source: https://coder.com/docs/reference/cli/open_app

<!-- DO NOT EDIT | GENERATED CONTENT -->
# open app

Open a workspace application.

## Usage

```console
coder open app [flags] <workspace> <app slug>
```

## Options

### --region

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_OPEN_APP_REGION</code> |
| Default     | <code>primary</code>                |

Region to use when opening the app. By default, the app will be opened using the main Coder deployment (a.k.a. "primary").

---

# open vscode

Source: https://coder.com/docs/reference/cli/open_vscode

<!-- DO NOT EDIT | GENERATED CONTENT -->
# open vscode

Open a workspace in VS Code Desktop

## Usage

```console
coder open vscode [flags] <workspace> [<directory in workspace>]
```

## Options

### --generate-token

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_OPEN_VSCODE_GENERATE_TOKEN</code> |

Generate an auth token and include it in the vscode:// URI. This is for automagical configuration of VS Code Desktop and not needed if already configured. This flag does not need to be specified when running this command on a local machine unless automatic open fails.

---

# organizations

Source: https://coder.com/docs/reference/cli/organizations

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations

Organization related commands

Aliases:

* organization
* org
* orgs

## Usage

```console
coder organizations [flags] [subcommand]
```

## Subcommands

| Name                                                 | Purpose                                                                                                                                                        |
|------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [<code>show</code>](./organizations_show.md)         | Show the organization. Using "selected" will show the selected organization from the "--org" flag. Using "me" will show all organizations you are a member of. |
| [<code>list</code>](./organizations_list.md)         | List all organizations                                                                                                                                         |
| [<code>create</code>](./organizations_create.md)     | Create a new organization.                                                                                                                                     |
| [<code>delete</code>](./organizations_delete.md)     | Delete an organization                                                                                                                                         |
| [<code>members</code>](./organizations_members.md)   | Manage organization members                                                                                                                                    |
| [<code>roles</code>](./organizations_roles.md)       | Manage organization roles.                                                                                                                                     |
| [<code>settings</code>](./organizations_settings.md) | Manage organization settings.                                                                                                                                  |

## Options

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# organizations create

Source: https://coder.com/docs/reference/cli/organizations_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations create

Create a new organization.

## Usage

```console
coder organizations create [flags] <organization name>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# organizations delete

Source: https://coder.com/docs/reference/cli/organizations_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations delete

Delete an organization

Aliases:

* rm

## Usage

```console
coder organizations delete [flags] <organization_name_or_id>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# organizations list

Source: https://coder.com/docs/reference/cli/organizations_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations list

List all organizations

Aliases:

* ls

## Usage

```console
coder organizations list [flags]
```

## Description

```console
List all organizations. Requires a role which grants ResourceOrganization: read.
```

## Options

### -c, --column

|         |                                                                                           |
|---------|-------------------------------------------------------------------------------------------|
| Type    | <code>[id\|name\|display name\|icon\|description\|created at\|updated at\|default]</code> |
| Default | <code>name,display name,id,default</code>                                                 |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# organizations members

Source: https://coder.com/docs/reference/cli/organizations_members

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations members

Manage organization members

Aliases:

* member

## Usage

```console
coder organizations members
```

## Subcommands

| Name                                                             | Purpose                                         |
|------------------------------------------------------------------|-------------------------------------------------|
| [<code>list</code>](./organizations_members_list.md)             | List all organization members                   |
| [<code>edit-roles</code>](./organizations_members_edit-roles.md) | Edit organization member's roles                |
| [<code>add</code>](./organizations_members_add.md)               | Add a new member to the current organization    |
| [<code>remove</code>](./organizations_members_remove.md)         | Remove a new member to the current organization |

---

# organizations members add

Source: https://coder.com/docs/reference/cli/organizations_members_add

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations members add

Add a new member to the current organization

## Usage

```console
coder organizations members add <username | user_id>
```

---

# organizations members edit-roles

Source: https://coder.com/docs/reference/cli/organizations_members_edit-roles

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations members edit-roles

Edit organization member's roles

Aliases:

* edit-role

## Usage

```console
coder organizations members edit-roles <username | user_id> [roles...]
```

---

# organizations members list

Source: https://coder.com/docs/reference/cli/organizations_members_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations members list

List all organization members

## Usage

```console
coder organizations members list [flags]
```

## Options

### -c, --column

|         |                                                                                                                                                     |
|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[username\|name\|last seen at\|user created at\|user updated at\|user id\|organization id\|created at\|updated at\|organization roles]</code> |
| Default | <code>username,organization roles</code>                                                                                                            |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# organizations members remove

Source: https://coder.com/docs/reference/cli/organizations_members_remove

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations members remove

Remove a new member to the current organization

Aliases:

* rm

## Usage

```console
coder organizations members remove <username | user_id>
```

---

# organizations roles

Source: https://coder.com/docs/reference/cli/organizations_roles

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations roles

Manage organization roles.

Aliases:

* role

## Usage

```console
coder organizations roles
```

## Subcommands

| Name                                                   | Purpose                               |
|--------------------------------------------------------|---------------------------------------|
| [<code>show</code>](./organizations_roles_show.md)     | Show role(s)                          |
| [<code>update</code>](./organizations_roles_update.md) | Update an organization custom role    |
| [<code>create</code>](./organizations_roles_create.md) | Create a new organization custom role |

---

# organizations roles create

Source: https://coder.com/docs/reference/cli/organizations_roles_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations roles create

Create a new organization custom role

## Usage

```console
coder organizations roles create [flags] <role_name>
```

## Description

```console
  - Run with an input.json file:

     $ coder organization -O <organization_name> roles create --stdin < role.json
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --dry-run

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Does all the work, but does not submit the final updated role.

### --stdin

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Reads stdin for the json role definition to upload.

---

# organizations roles show

Source: https://coder.com/docs/reference/cli/organizations_roles_show

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations roles show

Show role(s)

## Usage

```console
coder organizations roles show [flags] [role_names ...]
```

## Options

### -c, --column

|         |                                                                                                                  |
|---------|------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[name\|display name\|organization id\|site permissions\|organization permissions\|user permissions]</code> |
| Default | <code>name,display name,site permissions,organization permissions,user permissions</code>                        |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# organizations roles update

Source: https://coder.com/docs/reference/cli/organizations_roles_update

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations roles update

Update an organization custom role

## Usage

```console
coder organizations roles update [flags] <role_name>
```

## Description

```console
  - Run with an input.json file:

     $ coder roles update --stdin < role.json
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --dry-run

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Does all the work, but does not submit the final updated role.

### --stdin

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Reads stdin for the json role definition to upload.

### -c, --column

|         |                                                                                                                  |
|---------|------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[name\|display name\|organization id\|site permissions\|organization permissions\|user permissions]</code> |
| Default | <code>name,display name,site permissions,organization permissions,user permissions</code>                        |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# organizations settings

Source: https://coder.com/docs/reference/cli/organizations_settings

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings

Manage organization settings.

Aliases:

* setting

## Usage

```console
coder organizations settings
```

## Subcommands

| Name                                                  | Purpose                                 |
|-------------------------------------------------------|-----------------------------------------|
| [<code>show</code>](./organizations_settings_show.md) | Outputs specified organization setting. |
| [<code>set</code>](./organizations_settings_set.md)   | Update specified organization setting.  |

---

# organizations settings set

Source: https://coder.com/docs/reference/cli/organizations_settings_set

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings set

Update specified organization setting.

## Usage

```console
coder organizations settings set
```

## Description

```console
  - Update group sync settings.:

     $ coder organization settings set groupsync < input.json
```

## Subcommands

| Name                                                                                | Purpose                                                                  |
|-------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
| [<code>group-sync</code>](./organizations_settings_set_group-sync.md)               | Group sync settings to sync groups from an IdP.                          |
| [<code>role-sync</code>](./organizations_settings_set_role-sync.md)                 | Role sync settings to sync organization roles from an IdP.               |
| [<code>organization-sync</code>](./organizations_settings_set_organization-sync.md) | Organization sync settings to sync organization memberships from an IdP. |
| [<code>workspace-sharing</code>](./organizations_settings_set_workspace-sharing.md) | Workspace sharing settings for the organization.                         |

---

# organizations settings set group-sync

Source: https://coder.com/docs/reference/cli/organizations_settings_set_group-sync

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings set group-sync

Group sync settings to sync groups from an IdP.

Aliases:

* groupsync

## Usage

```console
coder organizations settings set group-sync
```

---

# organizations settings set organization-sync

Source: https://coder.com/docs/reference/cli/organizations_settings_set_organization-sync

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings set organization-sync

Organization sync settings to sync organization memberships from an IdP.

Aliases:

* organizationsync
* org-sync
* orgsync

## Usage

```console
coder organizations settings set organization-sync
```

---

# organizations settings set role-sync

Source: https://coder.com/docs/reference/cli/organizations_settings_set_role-sync

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings set role-sync

Role sync settings to sync organization roles from an IdP.

Aliases:

* rolesync

## Usage

```console
coder organizations settings set role-sync
```

---

# organizations settings set workspace-sharing

Source: https://coder.com/docs/reference/cli/organizations_settings_set_workspace-sharing

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings set workspace-sharing

Workspace sharing settings for the organization.

Aliases:

* workspacesharing

## Usage

```console
coder organizations settings set workspace-sharing
```

---

# organizations settings show

Source: https://coder.com/docs/reference/cli/organizations_settings_show

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings show

Outputs specified organization setting.

## Usage

```console
coder organizations settings show
```

## Description

```console
  - Output group sync settings.:

     $ coder organization settings show groupsync
```

## Subcommands

| Name                                                                                 | Purpose                                                                  |
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------|
| [<code>group-sync</code>](./organizations_settings_show_group-sync.md)               | Group sync settings to sync groups from an IdP.                          |
| [<code>role-sync</code>](./organizations_settings_show_role-sync.md)                 | Role sync settings to sync organization roles from an IdP.               |
| [<code>organization-sync</code>](./organizations_settings_show_organization-sync.md) | Organization sync settings to sync organization memberships from an IdP. |
| [<code>workspace-sharing</code>](./organizations_settings_show_workspace-sharing.md) | Workspace sharing settings for the organization.                         |

---

# organizations settings show group-sync

Source: https://coder.com/docs/reference/cli/organizations_settings_show_group-sync

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings show group-sync

Group sync settings to sync groups from an IdP.

Aliases:

* groupsync

## Usage

```console
coder organizations settings show group-sync
```

---

# organizations settings show organization-sync

Source: https://coder.com/docs/reference/cli/organizations_settings_show_organization-sync

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings show organization-sync

Organization sync settings to sync organization memberships from an IdP.

Aliases:

* organizationsync
* org-sync
* orgsync

## Usage

```console
coder organizations settings show organization-sync
```

---

# organizations settings show role-sync

Source: https://coder.com/docs/reference/cli/organizations_settings_show_role-sync

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings show role-sync

Role sync settings to sync organization roles from an IdP.

Aliases:

* rolesync

## Usage

```console
coder organizations settings show role-sync
```

---

# organizations settings show workspace-sharing

Source: https://coder.com/docs/reference/cli/organizations_settings_show_workspace-sharing

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations settings show workspace-sharing

Workspace sharing settings for the organization.

Aliases:

* workspacesharing

## Usage

```console
coder organizations settings show workspace-sharing
```

---

# organizations show

Source: https://coder.com/docs/reference/cli/organizations_show

<!-- DO NOT EDIT | GENERATED CONTENT -->
# organizations show

Show the organization. Using "selected" will show the selected organization from the "--org" flag. Using "me" will show all organizations you are a member of.

## Usage

```console
coder organizations show [flags] ["selected"|"me"|uuid|org_name]
```

## Description

```console
  - coder org show selected:

     $ Shows the organizations selected with '--org=<org_name>'. This organization is the organization used by the cli.

  - coder org show me:

     $ List of all organizations you are a member of.

  - coder org show developers:

     $ Show organization with name 'developers'

  - coder org show 90ee1875-3db5-43b3-828e-af3687522e43:

     $ Show organization with the given ID.
```

## Options

### --only-id

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Only print the organization ID.

### -c, --column

|         |                                                                                           |
|---------|-------------------------------------------------------------------------------------------|
| Type    | <code>[id\|name\|display name\|icon\|description\|created at\|updated at\|default]</code> |
| Default | <code>id,name,default</code>                                                              |

Columns to display in table output.

### -o, --output

|         |                                |
|---------|--------------------------------|
| Type    | <code>text\|table\|json</code> |
| Default | <code>text</code>              |

Output format.

---

# ping

Source: https://coder.com/docs/reference/cli/ping

<!-- DO NOT EDIT | GENERATED CONTENT -->
# ping

Ping a workspace

## Usage

```console
coder ping [flags] <workspace>
```

## Options

### --wait

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>1s</code>       |

Specifies how long to wait between pings.

### -t, --timeout

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>5s</code>       |

Specifies how long to wait for a ping to complete.

### -n, --num

|      |                  |
|------|------------------|
| Type | <code>int</code> |

Specifies the number of pings to perform. By default, pings will continue until interrupted.

### --time

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Show the response time of each pong in local time.

### --utc

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Show the response time of each pong in UTC (implies --time).

---

# port-forward

Source: https://coder.com/docs/reference/cli/port-forward

<!-- DO NOT EDIT | GENERATED CONTENT -->
# port-forward

Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".

Aliases:

* tunnel

## Usage

```console
coder port-forward [flags] <workspace>
```

## Description

```console
  - Port forward a single TCP port from 1234 in the workspace to port 5678 on your
local machine:

     $ coder port-forward <workspace> --tcp 5678:1234

  - Port forward a single UDP port from port 9000 to port 9000 on your local
machine:

     $ coder port-forward <workspace> --udp 9000

  - Port forward multiple TCP ports and a UDP port:

     $ coder port-forward <workspace> --tcp 8080:8080 --tcp 9000:3000 --udp 5353:53

  - Port forward multiple ports (TCP or UDP) in condensed syntax:

     $ coder port-forward <workspace> --tcp 8080,9000:3000,9090-9092,10000-10002:10010-10012

  - Port forward specifying the local address to bind to:

     $ coder port-forward <workspace> --tcp 1.2.3.4:8080:8080
```

## Options

### -p, --tcp

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string-array</code>            |
| Environment | <code>$CODER_PORT_FORWARD_TCP</code> |

Forward TCP port(s) from the workspace to the local machine.

### --udp

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string-array</code>            |
| Environment | <code>$CODER_PORT_FORWARD_UDP</code> |

Forward UDP port(s) from the workspace to the local machine. The UDP connection has TCP-like semantics to support stateful UDP protocols.

### --disable-autostart

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>bool</code>                         |
| Environment | <code>$CODER_SSH_DISABLE_AUTOSTART</code> |
| Default     | <code>false</code>                        |

Disable starting the workspace automatically when connecting via SSH.

---

# prebuilds

Source: https://coder.com/docs/reference/cli/prebuilds

<!-- DO NOT EDIT | GENERATED CONTENT -->
# prebuilds

Manage Coder prebuilds

Aliases:

* prebuild

## Usage

```console
coder prebuilds
```

## Description

```console
Administrators can use these commands to manage prebuilt workspace settings.
  - Pause Coder prebuilt workspace reconciliation.:

     $ coder prebuilds pause

  - Resume Coder prebuilt workspace reconciliation if it has been paused.:

     $ coder prebuilds resume
```

## Subcommands

| Name                                         | Purpose          |
|----------------------------------------------|------------------|
| [<code>pause</code>](./prebuilds_pause.md)   | Pause prebuilds  |
| [<code>resume</code>](./prebuilds_resume.md) | Resume prebuilds |

---

# prebuilds pause

Source: https://coder.com/docs/reference/cli/prebuilds_pause

<!-- DO NOT EDIT | GENERATED CONTENT -->
# prebuilds pause

Pause prebuilds

## Usage

```console
coder prebuilds pause
```

---

# prebuilds resume

Source: https://coder.com/docs/reference/cli/prebuilds_resume

<!-- DO NOT EDIT | GENERATED CONTENT -->
# prebuilds resume

Resume prebuilds

## Usage

```console
coder prebuilds resume
```

---

# provisioner

Source: https://coder.com/docs/reference/cli/provisioner

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner

View and manage provisioner daemons and jobs

Aliases:

* provisioners

## Usage

```console
coder provisioner
```

## Subcommands

| Name                                         | Purpose                                     |
|----------------------------------------------|---------------------------------------------|
| [<code>list</code>](./provisioner_list.md)   | List provisioner daemons in an organization |
| [<code>jobs</code>](./provisioner_jobs.md)   | View and manage provisioner jobs            |
| [<code>start</code>](./provisioner_start.md) | Run a provisioner daemon                    |
| [<code>keys</code>](./provisioner_keys.md)   | Manage provisioner keys                     |

---

# provisioner jobs

Source: https://coder.com/docs/reference/cli/provisioner_jobs

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner jobs

View and manage provisioner jobs

Aliases:

* job

## Usage

```console
coder provisioner jobs
```

## Subcommands

| Name                                                | Purpose                  |
|-----------------------------------------------------|--------------------------|
| [<code>cancel</code>](./provisioner_jobs_cancel.md) | Cancel a provisioner job |
| [<code>list</code>](./provisioner_jobs_list.md)     | List provisioner jobs    |

---

# provisioner jobs cancel

Source: https://coder.com/docs/reference/cli/provisioner_jobs_cancel

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner jobs cancel

Cancel a provisioner job

## Usage

```console
coder provisioner jobs cancel [flags] <job_id>
```

## Options

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# provisioner jobs list

Source: https://coder.com/docs/reference/cli/provisioner_jobs_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner jobs list

List provisioner jobs

Aliases:

* ls

## Usage

```console
coder provisioner jobs list [flags]
```

## Options

### -s, --status

|             |                                                                                  |
|-------------|----------------------------------------------------------------------------------|
| Type        | <code>[pending\|running\|succeeded\|canceling\|canceled\|failed\|unknown]</code> |
| Environment | <code>$CODER_PROVISIONER_JOB_LIST_STATUS</code>                                  |

Filter by job status.

### -l, --limit

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>int</code>                               |
| Environment | <code>$CODER_PROVISIONER_JOB_LIST_LIMIT</code> |
| Default     | <code>50</code>                                |

Limit the number of jobs returned.

### -i, --initiator

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>string</code>                                |
| Environment | <code>$CODER_PROVISIONER_JOB_LIST_INITIATOR</code> |

Filter by initiator (user ID or username).

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

### -c, --column

|         |                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[id\|created at\|started at\|completed at\|canceled at\|error\|error code\|status\|worker id\|worker name\|file id\|tags\|queue position\|queue size\|organization id\|initiator id\|template version id\|workspace build id\|type\|available workers\|template version name\|template id\|template name\|template display name\|template icon\|workspace id\|workspace name\|workspace build transition\|logs overflowed\|organization\|queue]</code> |
| Default | <code>created at,id,type,template display name,status,queue,tags</code>                                                                                                                                                                                                                                                                                                                                                                                      |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# provisioner keys

Source: https://coder.com/docs/reference/cli/provisioner_keys

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner keys

Manage provisioner keys

Aliases:

* key

## Usage

```console
coder provisioner keys
```

## Subcommands

| Name                                                | Purpose                                  |
|-----------------------------------------------------|------------------------------------------|
| [<code>create</code>](./provisioner_keys_create.md) | Create a new provisioner key             |
| [<code>list</code>](./provisioner_keys_list.md)     | List provisioner keys in an organization |
| [<code>delete</code>](./provisioner_keys_delete.md) | Delete a provisioner key                 |

---

# provisioner keys create

Source: https://coder.com/docs/reference/cli/provisioner_keys_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner keys create

Create a new provisioner key

## Usage

```console
coder provisioner keys create [flags] <name>
```

## Options

### -t, --tag

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string-array</code>             |
| Environment | <code>$CODER_PROVISIONERD_TAGS</code> |

Tags to filter provisioner jobs by.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# provisioner keys delete

Source: https://coder.com/docs/reference/cli/provisioner_keys_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner keys delete

Delete a provisioner key

Aliases:

* rm

## Usage

```console
coder provisioner keys delete [flags] <name>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# provisioner keys list

Source: https://coder.com/docs/reference/cli/provisioner_keys_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner keys list

List provisioner keys in an organization

Aliases:

* ls

## Usage

```console
coder provisioner keys list [flags]
```

## Options

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

### -c, --column

|         |                                       |
|---------|---------------------------------------|
| Type    | <code>[created at\|name\|tags]</code> |
| Default | <code>created at,name,tags</code>     |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# provisioner list

Source: https://coder.com/docs/reference/cli/provisioner_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner list

List provisioner daemons in an organization

Aliases:

* ls

## Usage

```console
coder provisioner list [flags]
```

## Options

### -l, --limit

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>int</code>                           |
| Environment | <code>$CODER_PROVISIONER_LIST_LIMIT</code> |
| Default     | <code>50</code>                            |

Limit the number of provisioners returned.

### -f, --show-offline

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>bool</code>                            |
| Environment | <code>$CODER_PROVISIONER_SHOW_OFFLINE</code> |

Show offline provisioners.

### -s, --status

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>[offline\|idle\|busy]</code>          |
| Environment | <code>$CODER_PROVISIONER_LIST_STATUS</code> |

Filter by provisioner status.

### -m, --max-age

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>duration</code>                        |
| Environment | <code>$CODER_PROVISIONER_LIST_MAX_AGE</code> |

Filter provisioners by maximum age.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

### -c, --column

|         |                                                                                                                                                                                                                                                                                                                                                                                               |
|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[id\|organization id\|created at\|last seen at\|name\|version\|api version\|tags\|key name\|status\|current job id\|current job status\|current job template name\|current job template icon\|current job template display name\|previous job id\|previous job status\|previous job template name\|previous job template icon\|previous job template display name\|organization]</code> |
| Default | <code>created at,last seen at,key name,name,version,status,tags</code>                                                                                                                                                                                                                                                                                                                        |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# provisioner start

Source: https://coder.com/docs/reference/cli/provisioner_start

<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner start

Run a provisioner daemon

## Usage

```console
coder provisioner start [flags]
```

## Options

### -c, --cache-dir

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_CACHE_DIRECTORY</code> |
| Default     | <code>~/.cache/coder</code>         |

Directory to store cached data.

### -t, --tag

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string-array</code>             |
| Environment | <code>$CODER_PROVISIONERD_TAGS</code> |

Tags to filter provisioner jobs by.

### --poll-interval

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>duration</code>                          |
| Environment | <code>$CODER_PROVISIONERD_POLL_INTERVAL</code> |
| Default     | <code>1s</code>                                |

Deprecated and ignored.

### --poll-jitter

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>duration</code>                        |
| Environment | <code>$CODER_PROVISIONERD_POLL_JITTER</code> |
| Default     | <code>100ms</code>                           |

Deprecated and ignored.

### --psk

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string</code>                        |
| Environment | <code>$CODER_PROVISIONER_DAEMON_PSK</code> |

Pre-shared key to authenticate with Coder server.

### --key

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string</code>                        |
| Environment | <code>$CODER_PROVISIONER_DAEMON_KEY</code> |

Provisioner key to authenticate with Coder server.

### --name

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_PROVISIONER_DAEMON_NAME</code> |

Name of this provisioner daemon. Defaults to the current hostname without FQDN.

### --verbose

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_PROVISIONER_DAEMON_VERBOSE</code> |
| Default     | <code>false</code>                             |

Output debug-level logs.

### --log-human

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>string</code>                                  |
| Environment | <code>$CODER_PROVISIONER_DAEMON_LOGGING_HUMAN</code> |
| Default     | <code>/dev/stderr</code>                             |

Output human-readable logs to a given file.

### --log-json

|             |                                                     |
|-------------|-----------------------------------------------------|
| Type        | <code>string</code>                                 |
| Environment | <code>$CODER_PROVISIONER_DAEMON_LOGGING_JSON</code> |

Output JSON logs to a given file.

### --log-stackdriver

|             |                                                            |
|-------------|------------------------------------------------------------|
| Type        | <code>string</code>                                        |
| Environment | <code>$CODER_PROVISIONER_DAEMON_LOGGING_STACKDRIVER</code> |

Output Stackdriver compatible logs to a given file.

### --log-filter

|             |                                                   |
|-------------|---------------------------------------------------|
| Type        | <code>string-array</code>                         |
| Environment | <code>$CODER_PROVISIONER_DAEMON_LOG_FILTER</code> |

Filter debug logs by matching against a given regex. Use .* to match all debug logs.

### --prometheus-enable

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>bool</code>                     |
| Environment | <code>$CODER_PROMETHEUS_ENABLE</code> |
| Default     | <code>false</code>                    |

Serve prometheus metrics on the address defined by prometheus address.

### --prometheus-address

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_PROMETHEUS_ADDRESS</code> |
| Default     | <code>127.0.0.1:2112</code>            |

The bind address to serve prometheus metrics.

### --experiments

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string-array</code>       |
| Environment | <code>$CODER_EXPERIMENTS</code> |
| YAML        | <code>experiments</code>        |

Enable one or more experiments. These are not ready for production. Separate multiple experiments with commas, or enter '*' to opt-in to all available experiments.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# publickey

Source: https://coder.com/docs/reference/cli/publickey

<!-- DO NOT EDIT | GENERATED CONTENT -->
# publickey

Output your Coder public key used for Git operations

Aliases:

* pubkey

## Usage

```console
coder publickey [flags]
```

## Options

### --reset

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Regenerate your public key. This will require updating the key on any services it's registered with.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# rename

Source: https://coder.com/docs/reference/cli/rename

<!-- DO NOT EDIT | GENERATED CONTENT -->
# rename

Rename a workspace

## Usage

```console
coder rename [flags] <workspace> <new name>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# reset-password

Source: https://coder.com/docs/reference/cli/reset-password

<!-- DO NOT EDIT | GENERATED CONTENT -->
# reset-password

Directly connect to the database to reset a user's password

## Usage

```console
coder reset-password [flags] <username>
```

## Options

### --postgres-url

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string</code>                   |
| Environment | <code>$CODER_PG_CONNECTION_URL</code> |

URL of a PostgreSQL database to connect to.

### --postgres-connection-auth

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>password\|awsiamrds</code>       |
| Environment | <code>$CODER_PG_CONNECTION_AUTH</code> |
| Default     | <code>password</code>                  |

Type of auth to use when connecting to postgres.

---

# restart

Source: https://coder.com/docs/reference/cli/restart

<!-- DO NOT EDIT | GENERATED CONTENT -->
# restart

Restart a workspace

## Usage

```console
coder restart [flags] <workspace>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --build-option

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string-array</code>        |
| Environment | <code>$CODER_BUILD_OPTION</code> |

Build option value in the format "name=value".

### --build-options

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Prompt for one-time build options defined with ephemeral parameters.

### --ephemeral-parameter

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string-array</code>               |
| Environment | <code>$CODER_EPHEMERAL_PARAMETER</code> |

Set the value of ephemeral parameters defined in the template. The format is "name=value".

### --prompt-ephemeral-parameters

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_PROMPT_EPHEMERAL_PARAMETERS</code> |

Prompt to set values of ephemeral parameters defined in the template. If a value has been set via --ephemeral-parameter, it will not be prompted for.

### --parameter

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string-array</code>          |
| Environment | <code>$CODER_RICH_PARAMETER</code> |

Rich parameter value in the format "name=value".

### --rich-parameter-file

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_RICH_PARAMETER_FILE</code> |

Specify a file path with values for rich parameters defined in the template. The file should be in YAML format, containing key-value pairs for the parameters.

### --parameter-default

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string-array</code>                  |
| Environment | <code>$CODER_RICH_PARAMETER_DEFAULT</code> |

Rich parameter default values in the format "name=value".

### --use-parameter-defaults

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_WORKSPACE_USE_PARAMETER_DEFAULTS</code> |

Automatically accept parameter defaults when no value is provided.

### --always-prompt

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Always prompt all parameters. Does not pull parameter values from existing workspace.

---

# schedule

Source: https://coder.com/docs/reference/cli/schedule

<!-- DO NOT EDIT | GENERATED CONTENT -->
# schedule

Schedule automated start and stop times for workspaces

## Usage

```console
coder schedule { show | start | stop | extend } <workspace>
```

## Subcommands

| Name                                        | Purpose                                                         |
|---------------------------------------------|-----------------------------------------------------------------|
| [<code>show</code>](./schedule_show.md)     | Show workspace schedules                                        |
| [<code>start</code>](./schedule_start.md)   | Edit workspace start schedule                                   |
| [<code>stop</code>](./schedule_stop.md)     | Edit workspace stop schedule                                    |
| [<code>extend</code>](./schedule_extend.md) | Extend the stop time of a currently running workspace instance. |

---

# schedule extend

Source: https://coder.com/docs/reference/cli/schedule_extend

<!-- DO NOT EDIT | GENERATED CONTENT -->
# schedule extend

Extend the stop time of a currently running workspace instance.

Aliases:

* override-stop

## Usage

```console
coder schedule extend <workspace-name> <duration from now>
```

## Description

```console
Extends the workspace deadline.
  * The new stop time is calculated from *now*.
  * The new stop time must be at least 30 minutes in the future.
  * The workspace template may restrict the maximum workspace runtime.

 $ coder schedule extend my-workspace 90m
```

---

# schedule show

Source: https://coder.com/docs/reference/cli/schedule_show

<!-- DO NOT EDIT | GENERATED CONTENT -->
# schedule show

Show workspace schedules

## Usage

```console
coder schedule show [flags] <workspace | --search <query> | --all>
```

## Description

```console
Shows the following information for the given workspace(s):
  * The automatic start schedule
  * The next scheduled start time
  * The duration after which it will stop
  * The next scheduled stop time

```

## Options

### -a, --all

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Specifies whether all workspaces will be listed or not.

### --search

|         |                       |
|---------|-----------------------|
| Type    | <code>string</code>   |
| Default | <code>owner:me</code> |

Search for a workspace with a query.

### -c, --column

|         |                                                                           |
|---------|---------------------------------------------------------------------------|
| Type    | <code>[workspace\|starts at\|starts next\|stops after\|stops next]</code> |
| Default | <code>workspace,starts at,starts next,stops after,stops next</code>       |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# schedule start

Source: https://coder.com/docs/reference/cli/schedule_start

<!-- DO NOT EDIT | GENERATED CONTENT -->
# schedule start

Edit workspace start schedule

## Usage

```console
coder schedule start <workspace-name> { <start-time> [day-of-week] [location] | manual }
```

## Description

```console
Schedules a workspace to regularly start at a specific time.
Schedule format: <start-time> [day-of-week] [location].
  * Start-time (required) is accepted either in 12-hour (hh:mm{am|pm}) format, or 24-hour format hh:mm.
  * Day-of-week (optional) allows specifying in the cron format, e.g. 1,3,5 or Mon-Fri.
    Aliases such as @daily are not supported.
    Default: * (every day)
  * Location (optional) must be a valid location in the IANA timezone database.
    If omitted, we will fall back to either the TZ environment variable or /etc/localtime.
    You can check your corresponding location by visiting https://ipinfo.io - it shows in the demo widget on the right.

  - Set the workspace to start at 9:30am (in Dublin) from Monday to Friday:

     $ coder schedule start my-workspace 9:30AM Mon-Fri Europe/Dublin
```

---

# schedule stop

Source: https://coder.com/docs/reference/cli/schedule_stop

<!-- DO NOT EDIT | GENERATED CONTENT -->
# schedule stop

Edit workspace stop schedule

## Usage

```console
coder schedule stop <workspace-name> { <duration> | manual }
```

## Description

```console
Schedules a workspace to stop after a given duration has elapsed.
  * Workspace runtime is measured from the time that the workspace build completed.
  * The minimum scheduled stop time is 1 minute.
  * The workspace template may place restrictions on the maximum shutdown time.
  * Changes to workspace schedules only take effect upon the next build of the workspace,
    and do not affect a running instance of a workspace.

When enabling scheduled stop, enter a duration in one of the following formats:
  * 3h2m (3 hours and two minutes)
  * 3h   (3 hours)
  * 2m   (2 minutes)
  * 2    (2 minutes)

 $ coder schedule stop my-workspace 2h30m
```

---

# secret

Source: https://coder.com/docs/reference/cli/secret

<!-- DO NOT EDIT | GENERATED CONTENT -->
# secret

Manage secrets

Aliases:

* secrets

## Usage

```console
coder secret
```

## Description

```console
  - Create a secret:

     $ printf %s "$MYCLI_API_KEY" | coder secret create api-key --description "API key for workspace tools" --env API_KEY --file "~/.api-key"

  - Update a secret:

     $ echo -n "$NEW_SECRET_VALUE" | coder secret update api-key --description "Rotated API key" --env API_KEY --file "~/.api-key"

  - List your secrets:

     $ coder secret list

  - Show a specific secret:

     $ coder secret list api-key

  - Delete a secret:

     $ coder secret delete api-key
```

## Subcommands

| Name                                      | Purpose                           |
|-------------------------------------------|-----------------------------------|
| [<code>create</code>](./secret_create.md) | Create a secret                   |
| [<code>update</code>](./secret_update.md) | Update a secret                   |
| [<code>list</code>](./secret_list.md)     | List secrets, or show one by name |
| [<code>delete</code>](./secret_delete.md) | Delete a secret                   |

---

# secret create

Source: https://coder.com/docs/reference/cli/secret_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# secret create

Create a secret

## Usage

```console
coder secret create [flags] <name>
```

## Description

```console
Provide the secret value with --value or non-interactive stdin (pipe or redirect).
```

## Options

### --value

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Set the secret value. For security reasons, prefer non-interactive stdin (pipe or redirect).

### --description

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Set the secret description.

### --env

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Name of the workspace environment variable that this secret will set.

### --file

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Workspace file path where this secret will be written. Must start with ~/ or /.

---

# secret update

Source: https://coder.com/docs/reference/cli/secret_update

<!-- DO NOT EDIT | GENERATED CONTENT -->
# secret update

Update a secret

## Usage

```console
coder secret update [flags] <name>
```

## Description

```console
At least one of --value, --description, --env, or --file must be specified. Provide the secret value by at most one of --value or non-interactive stdin (pipe or redirect).
```

## Options

### --value

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Update the secret value. For security reasons, prefer non-interactive stdin (pipe or redirect).

### --description

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Update the secret description. Pass an empty string to clear it.

### --env

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Name of the workspace environment variable that this secret will set. Pass an empty string to clear it.

### --file

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Workspace file path where this secret will be written. Must start with ~/ or /. Pass an empty string to clear it.

---

# secret list

Source: https://coder.com/docs/reference/cli/secret_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# secret list

List secrets, or show one by name

Aliases:

* ls

## Usage

```console
coder secret list [flags] [name]
```

## Description

```console
Secret values are omitted from the output.
```

## Options

### -c, --column

|         |                                                               |
|---------|---------------------------------------------------------------|
| Type    | <code>[created\|name\|updated\|env\|file\|description]</code> |
| Default | <code>name,created,updated,env,file,description</code>        |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# secret delete

Source: https://coder.com/docs/reference/cli/secret_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# secret delete

Delete a secret

Aliases:

* remove
* rm

## Usage

```console
coder secret delete [flags] <name>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# server

Source: https://coder.com/docs/reference/cli/server

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server

Start a Coder server

## Usage

```console
coder server [flags]
```

## Subcommands

| Name                                                                      | Purpose                                                                                                |
|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|
| [<code>create-admin-user</code>](./server_create-admin-user.md)           | Create a new admin user with the given username, email and password and adds it to every organization. |
| [<code>postgres-builtin-url</code>](./server_postgres-builtin-url.md)     | Output the connection URL for the built-in PostgreSQL deployment.                                      |
| [<code>postgres-builtin-serve</code>](./server_postgres-builtin-serve.md) | Run the built-in PostgreSQL deployment.                                                                |
| [<code>dbcrypt</code>](./server_dbcrypt.md)                               | Manage database encryption.                                                                            |

## Options

### --access-url

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>url</code>                  |
| Environment | <code>$CODER_ACCESS_URL</code>    |
| YAML        | <code>networking.accessURL</code> |

The URL that users will use to access the Coder deployment.

### --wildcard-access-url

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string</code>                       |
| Environment | <code>$CODER_WILDCARD_ACCESS_URL</code>   |
| YAML        | <code>networking.wildcardAccessURL</code> |

Specifies the wildcard hostname to use for workspace applications in the form "*.example.com".

### --docs-url

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>url</code>                    |
| Environment | <code>$CODER_DOCS_URL</code>        |
| YAML        | <code>networking.docsURL</code>     |
| Default     | <code>https://coder.com/docs</code> |

Specifies the custom docs URL.

### --redirect-to-access-url

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>bool</code>                           |
| Environment | <code>$CODER_REDIRECT_TO_ACCESS_URL</code>  |
| YAML        | <code>networking.redirectToAccessURL</code> |

Specifies whether to redirect requests that do not match the access URL host.

### --http-address

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_HTTP_ADDRESS</code>         |
| YAML        | <code>networking.http.httpAddress</code> |
| Default     | <code>127.0.0.1:3000</code>              |

HTTP bind address of the server. Unset to disable the HTTP endpoint.

### --tls-address

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>host:port</code>              |
| Environment | <code>$CODER_TLS_ADDRESS</code>     |
| YAML        | <code>networking.tls.address</code> |
| Default     | <code>127.0.0.1:3443</code>         |

HTTPS bind address of the server.

### --tls-enable

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>bool</code>                  |
| Environment | <code>$CODER_TLS_ENABLE</code>     |
| YAML        | <code>networking.tls.enable</code> |

Whether TLS will be enabled.

### --tls-cert-file

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string-array</code>             |
| Environment | <code>$CODER_TLS_CERT_FILE</code>     |
| YAML        | <code>networking.tls.certFiles</code> |

Path to each certificate for TLS. It requires a PEM-encoded file. To configure the listener to use a CA certificate, concatenate the primary certificate and the CA certificate together. The primary certificate should appear first in the combined file.

### --tls-client-ca-file

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_TLS_CLIENT_CA_FILE</code>   |
| YAML        | <code>networking.tls.clientCAFile</code> |

PEM-encoded Certificate Authority file used for checking the authenticity of client.

### --tls-client-auth

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_TLS_CLIENT_AUTH</code>    |
| YAML        | <code>networking.tls.clientAuth</code> |
| Default     | <code>none</code>                      |

Policy the server will follow for TLS Client Authentication. Accepted values are "none", "request", "require-any", "verify-if-given", or "require-and-verify".

### --tls-key-file

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string-array</code>            |
| Environment | <code>$CODER_TLS_KEY_FILE</code>     |
| YAML        | <code>networking.tls.keyFiles</code> |

Paths to the private keys for each of the certificates. It requires a PEM-encoded file.

### --tls-min-version

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_TLS_MIN_VERSION</code>    |
| YAML        | <code>networking.tls.minVersion</code> |
| Default     | <code>tls12</code>                     |

Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13".

### --tls-client-cert-file

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string</code>                        |
| Environment | <code>$CODER_TLS_CLIENT_CERT_FILE</code>   |
| YAML        | <code>networking.tls.clientCertFile</code> |

Path to certificate for client TLS authentication. It requires a PEM-encoded file.

### --tls-client-key-file

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string</code>                       |
| Environment | <code>$CODER_TLS_CLIENT_KEY_FILE</code>   |
| YAML        | <code>networking.tls.clientKeyFile</code> |

Path to key for client TLS authentication. It requires a PEM-encoded file.

### --tls-ciphers

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string-array</code>              |
| Environment | <code>$CODER_TLS_CIPHERS</code>        |
| YAML        | <code>networking.tls.tlsCiphers</code> |

Specify specific TLS ciphers that allowed to be used. See https://github.com/golang/go/blob/master/src/crypto/tls/cipher_suites.go#L53-L75.

### --tls-allow-insecure-ciphers

|             |                                                     |
|-------------|-----------------------------------------------------|
| Type        | <code>bool</code>                                   |
| Environment | <code>$CODER_TLS_ALLOW_INSECURE_CIPHERS</code>      |
| YAML        | <code>networking.tls.tlsAllowInsecureCiphers</code> |
| Default     | <code>false</code>                                  |

By default, only ciphers marked as 'secure' are allowed to be used. See https://github.com/golang/go/blob/master/src/crypto/tls/cipher_suites.go#L82-L95.

### --derp-server-enable

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>bool</code>                      |
| Environment | <code>$CODER_DERP_SERVER_ENABLE</code> |
| YAML        | <code>networking.derp.enable</code>    |
| Default     | <code>true</code>                      |

Whether to enable or disable the embedded DERP relay server.

### --derp-server-region-name

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_DERP_SERVER_REGION_NAME</code> |
| YAML        | <code>networking.derp.regionName</code>     |
| Default     | <code>Coder Embedded Relay</code>           |

Region name that for the embedded DERP server.

### --derp-server-stun-addresses

|             |                                                                                                                                          |
|-------------|------------------------------------------------------------------------------------------------------------------------------------------|
| Type        | <code>string-array</code>                                                                                                                |
| Environment | <code>$CODER_DERP_SERVER_STUN_ADDRESSES</code>                                                                                           |
| YAML        | <code>networking.derp.stunAddresses</code>                                                                                               |
| Default     | <code>stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302,stun3.l.google.com:19302,stun4.l.google.com:19302</code> |

Addresses for STUN servers to establish P2P connections. It's recommended to have at least two STUN servers to give users the best chance of connecting P2P to workspaces. Each STUN server will get it's own DERP region, with region IDs starting at `--derp-server-region-id + 1`. Use special value 'disable' to turn off STUN completely.

### --derp-server-relay-url

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>url</code>                          |
| Environment | <code>$CODER_DERP_SERVER_RELAY_URL</code> |
| YAML        | <code>networking.derp.relayURL</code>     |

An HTTP URL that is accessible by other replicas to relay DERP traffic. Required for high availability.

### --block-direct-connections

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>bool</code>                        |
| Environment | <code>$CODER_BLOCK_DIRECT</code>         |
| YAML        | <code>networking.derp.blockDirect</code> |

Block peer-to-peer (aka. direct) workspace connections. All workspace connections from the CLI will be proxied through Coder (or custom configured DERP servers) and will never be peer-to-peer when enabled. Workspaces may still reach out to STUN servers to get their address until they are restarted after this change has been made, but new connections will still be proxied regardless.

### --derp-force-websockets

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>bool</code>                            |
| Environment | <code>$CODER_DERP_FORCE_WEBSOCKETS</code>    |
| YAML        | <code>networking.derp.forceWebSockets</code> |

Force clients and agents to always use WebSocket to connect to DERP relay servers. By default, DERP uses `Upgrade: derp`, which may cause issues with some reverse proxies. Clients may automatically fallback to WebSocket if they detect an issue with `Upgrade: derp`, but this does not work in all situations.

### --derp-config-url

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_DERP_CONFIG_URL</code> |
| YAML        | <code>networking.derp.url</code>    |

URL to fetch a DERP mapping on startup. See: https://tailscale.com/kb/1118/custom-derp-servers/.

### --derp-config-path

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_DERP_CONFIG_PATH</code>    |
| YAML        | <code>networking.derp.configPath</code> |

Path to read a DERP mapping from. See: https://tailscale.com/kb/1118/custom-derp-servers/.

### --stats-collection-usage-stats-enable

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Type        | <code>bool</code>                                            |
| Environment | <code>$CODER_STATS_COLLECTION_USAGE_STATS_ENABLE</code>      |
| YAML        | <code>introspection.statsCollection.usageStats.enable</code> |
| Default     | <code>true</code>                                            |

Enable the collection of application and workspace usage along with the associated API endpoints and the template insights page. Disabling this will also disable traffic and connection insights in the deployment stats shown to admins in the bottom bar of the Coder UI, and will prevent Prometheus collection of these values.

### --prometheus-enable

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>bool</code>                            |
| Environment | <code>$CODER_PROMETHEUS_ENABLE</code>        |
| YAML        | <code>introspection.prometheus.enable</code> |

Serve prometheus metrics on the address defined by prometheus address.

### --prometheus-address

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>host:port</code>                        |
| Environment | <code>$CODER_PROMETHEUS_ADDRESS</code>        |
| YAML        | <code>introspection.prometheus.address</code> |
| Default     | <code>127.0.0.1:2112</code>                   |

The bind address to serve prometheus metrics.

### --prometheus-collect-agent-stats

|             |                                                           |
|-------------|-----------------------------------------------------------|
| Type        | <code>bool</code>                                         |
| Environment | <code>$CODER_PROMETHEUS_COLLECT_AGENT_STATS</code>        |
| YAML        | <code>introspection.prometheus.collect_agent_stats</code> |

Collect agent stats (may increase charges for metrics storage).

### --prometheus-aggregate-agent-stats-by

|             |                                                                |
|-------------|----------------------------------------------------------------|
| Type        | <code>string-array</code>                                      |
| Environment | <code>$CODER_PROMETHEUS_AGGREGATE_AGENT_STATS_BY</code>        |
| YAML        | <code>introspection.prometheus.aggregate_agent_stats_by</code> |
| Default     | <code>agent_name,template_name,username,workspace_name</code>  |

When collecting agent stats, aggregate metrics by a given set of comma-separated labels to reduce cardinality. Accepted values are agent_name, template_name, username, workspace_name.

### --prometheus-collect-db-metrics

|             |                                                          |
|-------------|----------------------------------------------------------|
| Type        | <code>bool</code>                                        |
| Environment | <code>$CODER_PROMETHEUS_COLLECT_DB_METRICS</code>        |
| YAML        | <code>introspection.prometheus.collect_db_metrics</code> |
| Default     | <code>false</code>                                       |

Collect database query metrics (may increase charges for metrics storage). If set to false, a reduced set of database metrics are still collected.

### --pprof-enable

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>bool</code>                       |
| Environment | <code>$CODER_PPROF_ENABLE</code>        |
| YAML        | <code>introspection.pprof.enable</code> |

Serve pprof metrics on the address defined by pprof address.

### --pprof-address

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>host:port</code>                   |
| Environment | <code>$CODER_PPROF_ADDRESS</code>        |
| YAML        | <code>introspection.pprof.address</code> |
| Default     | <code>127.0.0.1:6060</code>              |

The bind address to serve pprof.

### --oauth2-github-client-id

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_OAUTH2_GITHUB_CLIENT_ID</code> |
| YAML        | <code>oauth2.github.clientID</code>         |

Client ID for Login with GitHub.

### --oauth2-github-client-secret

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string</code>                             |
| Environment | <code>$CODER_OAUTH2_GITHUB_CLIENT_SECRET</code> |

Client secret for Login with GitHub.

### --oauth2-github-device-flow

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>bool</code>                             |
| Environment | <code>$CODER_OAUTH2_GITHUB_DEVICE_FLOW</code> |
| YAML        | <code>oauth2.github.deviceFlow</code>         |
| Default     | <code>false</code>                            |

Enable device flow for Login with GitHub.

### --oauth2-github-default-provider-enable

|             |                                                           |
|-------------|-----------------------------------------------------------|
| Type        | <code>bool</code>                                         |
| Environment | <code>$CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE</code> |
| YAML        | <code>oauth2.github.defaultProviderEnable</code>          |
| Default     | <code>true</code>                                         |

Enable the default GitHub OAuth2 provider managed by Coder.

### --oauth2-github-allowed-orgs

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>string-array</code>                      |
| Environment | <code>$CODER_OAUTH2_GITHUB_ALLOWED_ORGS</code> |
| YAML        | <code>oauth2.github.allowedOrgs</code>         |

Organizations the user must be a member of to Login with GitHub.

### --oauth2-github-allowed-teams

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string-array</code>                       |
| Environment | <code>$CODER_OAUTH2_GITHUB_ALLOWED_TEAMS</code> |
| YAML        | <code>oauth2.github.allowedTeams</code>         |

Teams inside organizations the user must be a member of to Login with GitHub. Structured as: <organization-name>/<team-slug>.

### --oauth2-github-allow-signups

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS</code> |
| YAML        | <code>oauth2.github.allowSignups</code>         |

Whether new users can sign up with GitHub.

### --oauth2-github-allow-everyone

|             |                                                  |
|-------------|--------------------------------------------------|
| Type        | <code>bool</code>                                |
| Environment | <code>$CODER_OAUTH2_GITHUB_ALLOW_EVERYONE</code> |
| YAML        | <code>oauth2.github.allowEveryone</code>         |

Allow all logins, setting this option means allowed orgs and teams must be empty.

### --oauth2-github-enterprise-base-url

|             |                                                       |
|-------------|-------------------------------------------------------|
| Type        | <code>string</code>                                   |
| Environment | <code>$CODER_OAUTH2_GITHUB_ENTERPRISE_BASE_URL</code> |
| YAML        | <code>oauth2.github.enterpriseBaseURL</code>          |

Base URL of a GitHub Enterprise deployment to use for Login with GitHub.

### --oidc-allow-signups

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>bool</code>                      |
| Environment | <code>$CODER_OIDC_ALLOW_SIGNUPS</code> |
| YAML        | <code>oidc.allowSignups</code>         |
| Default     | <code>true</code>                      |

Whether new users can sign up with OIDC.

### --oidc-client-id

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string</code>                |
| Environment | <code>$CODER_OIDC_CLIENT_ID</code> |
| YAML        | <code>oidc.clientID</code>         |

Client ID to use for Login with OIDC.

### --oidc-client-secret

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_OIDC_CLIENT_SECRET</code> |

Client secret to use for Login with OIDC.

### --oidc-client-key-file

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_OIDC_CLIENT_KEY_FILE</code> |
| YAML        | <code>oidc.oidcClientKeyFile</code>      |

Pem encoded RSA private key to use for oauth2 PKI/JWT authorization. This can be used instead of oidc-client-secret if your IDP supports it.

### --oidc-client-cert-file

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string</code>                       |
| Environment | <code>$CODER_OIDC_CLIENT_CERT_FILE</code> |
| YAML        | <code>oidc.oidcClientCertFile</code>      |

Pem encoded certificate file to use for oauth2 PKI/JWT authorization. The public certificate that accompanies oidc-client-key-file. A standard x509 certificate is expected.

### --oidc-email-domain

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string-array</code>             |
| Environment | <code>$CODER_OIDC_EMAIL_DOMAIN</code> |
| YAML        | <code>oidc.emailDomain</code>         |

Email domains that clients logging in with OIDC must match.

### --oidc-issuer-url

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_OIDC_ISSUER_URL</code> |
| YAML        | <code>oidc.issuerURL</code>         |

Issuer URL to use for Login with OIDC.

### --oidc-scopes

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>string-array</code>         |
| Environment | <code>$CODER_OIDC_SCOPES</code>   |
| YAML        | <code>oidc.scopes</code>          |
| Default     | <code>openid,profile,email</code> |

Scopes to grant when authenticating with OIDC.

### --oidc-ignore-email-verified

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_OIDC_IGNORE_EMAIL_VERIFIED</code> |
| YAML        | <code>oidc.ignoreEmailVerified</code>          |

Ignore the email_verified claim from the upstream provider.

### --oidc-username-field

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_OIDC_USERNAME_FIELD</code> |
| YAML        | <code>oidc.usernameField</code>         |
| Default     | <code>preferred_username</code>         |

OIDC claim field to use as the username.

### --oidc-name-field

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_OIDC_NAME_FIELD</code> |
| YAML        | <code>oidc.nameField</code>         |
| Default     | <code>name</code>                   |

OIDC claim field to use as the name.

### --oidc-email-field

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_OIDC_EMAIL_FIELD</code> |
| YAML        | <code>oidc.emailField</code>         |
| Default     | <code>email</code>                   |

OIDC claim field to use as the email.

### --oidc-auth-url-params

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>struct[map[string]string]</code>   |
| Environment | <code>$CODER_OIDC_AUTH_URL_PARAMS</code> |
| YAML        | <code>oidc.authURLParams</code>          |
| Default     | <code>{"access_type": "offline"}</code>  |

OIDC auth URL parameters to pass to the upstream provider.

### --oidc-ignore-userinfo

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>bool</code>                        |
| Environment | <code>$CODER_OIDC_IGNORE_USERINFO</code> |
| YAML        | <code>oidc.ignoreUserInfo</code>         |
| Default     | <code>false</code>                       |

Ignore the userinfo endpoint and only use the ID token for user information.

### --oidc-group-field

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_OIDC_GROUP_FIELD</code> |
| YAML        | <code>oidc.groupField</code>         |

This field must be set if using the group sync feature and the scope name is not 'groups'. Set to the claim to be used for groups.

### --oidc-group-mapping

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>struct[map[string]string]</code> |
| Environment | <code>$CODER_OIDC_GROUP_MAPPING</code> |
| YAML        | <code>oidc.groupMapping</code>         |
| Default     | <code>{}</code>                        |

A map of OIDC group IDs and the group in Coder it should map to. This is useful for when OIDC providers only return group IDs.

### --oidc-group-auto-create

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>bool</code>                          |
| Environment | <code>$CODER_OIDC_GROUP_AUTO_CREATE</code> |
| YAML        | <code>oidc.enableGroupAutoCreate</code>    |
| Default     | <code>false</code>                         |

Automatically creates missing groups from a user's groups claim.

### --oidc-group-regex-filter

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>regexp</code>                         |
| Environment | <code>$CODER_OIDC_GROUP_REGEX_FILTER</code> |
| YAML        | <code>oidc.groupRegexFilter</code>          |
| Default     | <code>.*</code>                             |

If provided any group name not matching the regex is ignored. This allows for filtering out groups that are not needed. This filter is applied after the group mapping.

### --oidc-allowed-groups

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string-array</code>               |
| Environment | <code>$CODER_OIDC_ALLOWED_GROUPS</code> |
| YAML        | <code>oidc.groupAllowed</code>          |

If provided any group name not in the list will not be allowed to authenticate. This allows for restricting access to a specific set of groups. This filter is applied after the group mapping and before the regex filter.

### --oidc-user-role-field

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_OIDC_USER_ROLE_FIELD</code> |
| YAML        | <code>oidc.userRoleField</code>          |

This field must be set if using the user roles sync feature. Set this to the name of the claim used to store the user's role. The roles should be sent as an array of strings.

### --oidc-user-role-mapping

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>struct[map[string][]string]</code>   |
| Environment | <code>$CODER_OIDC_USER_ROLE_MAPPING</code> |
| YAML        | <code>oidc.userRoleMapping</code>          |
| Default     | <code>{}</code>                            |

A map of the OIDC passed in user roles and the groups in Coder it should map to. This is useful if the group names do not match. If mapped to the empty string, the role will ignored.

### --oidc-user-role-default

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string-array</code>                  |
| Environment | <code>$CODER_OIDC_USER_ROLE_DEFAULT</code> |
| YAML        | <code>oidc.userRoleDefault</code>          |

If user role sync is enabled, these roles are always included for all authenticated users. The 'member' role is always assigned.

### --oidc-sign-in-text

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string</code>                   |
| Environment | <code>$CODER_OIDC_SIGN_IN_TEXT</code> |
| YAML        | <code>oidc.signInText</code>          |
| Default     | <code>OpenID Connect</code>           |

The text to show on the OpenID Connect sign in button.

### --oidc-icon-url

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>url</code>                  |
| Environment | <code>$CODER_OIDC_ICON_URL</code> |
| YAML        | <code>oidc.iconURL</code>         |

URL pointing to the icon to use on the OpenID Connect login button.

### --oidc-signups-disabled-text

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>string</code>                            |
| Environment | <code>$CODER_OIDC_SIGNUPS_DISABLED_TEXT</code> |
| YAML        | <code>oidc.signupsDisabledText</code>          |

The custom text to show on the error page informing about disabled OIDC signups. Markdown format is supported.

### --dangerous-oidc-skip-issuer-checks

|             |                                                       |
|-------------|-------------------------------------------------------|
| Type        | <code>bool</code>                                     |
| Environment | <code>$CODER_DANGEROUS_OIDC_SKIP_ISSUER_CHECKS</code> |
| YAML        | <code>oidc.dangerousSkipIssuerChecks</code>           |

OIDC issuer urls must match in the request, the id_token 'iss' claim, and in the well-known configuration. This flag disables that requirement, and can lead to an insecure OIDC configuration. It is not recommended to use this flag.

### --telemetry

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>bool</code>                    |
| Environment | <code>$CODER_TELEMETRY_ENABLE</code> |
| YAML        | <code>telemetry.enable</code>        |
| Default     | <code>true</code>                    |

Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product.

### --trace

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>bool</code>                         |
| Environment | <code>$CODER_TRACE_ENABLE</code>          |
| YAML        | <code>introspection.tracing.enable</code> |

Whether application tracing data is collected. It exports to a backend configured by environment variables. See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md.

### --trace-honeycomb-api-key

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_TRACE_HONEYCOMB_API_KEY</code> |

Enables trace exporting to Honeycomb.io using the provided API Key.

### --trace-logs

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_TRACE_LOGS</code>                 |
| YAML        | <code>introspection.tracing.captureLogs</code> |

Enables capturing of logs as events in traces. This is useful for debugging, but may result in a very large amount of events being sent to the tracing backend which may incur significant costs.

### --provisioner-daemons

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>int</code>                        |
| Environment | <code>$CODER_PROVISIONER_DAEMONS</code> |
| YAML        | <code>provisioning.daemons</code>       |
| Default     | <code>3</code>                          |

Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.

### --provisioner-daemon-poll-interval

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>duration</code>                                |
| Environment | <code>$CODER_PROVISIONER_DAEMON_POLL_INTERVAL</code> |
| YAML        | <code>provisioning.daemonPollInterval</code>         |
| Default     | <code>1s</code>                                      |

Deprecated and ignored.

### --provisioner-daemon-poll-jitter

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>duration</code>                              |
| Environment | <code>$CODER_PROVISIONER_DAEMON_POLL_JITTER</code> |
| YAML        | <code>provisioning.daemonPollJitter</code>         |
| Default     | <code>100ms</code>                                 |

Deprecated and ignored.

### --provisioner-force-cancel-interval

|             |                                                       |
|-------------|-------------------------------------------------------|
| Type        | <code>duration</code>                                 |
| Environment | <code>$CODER_PROVISIONER_FORCE_CANCEL_INTERVAL</code> |
| YAML        | <code>provisioning.forceCancelInterval</code>         |
| Default     | <code>10m0s</code>                                    |

Time to force cancel provisioning tasks that are stuck.

### --provisioner-daemon-psk

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string</code>                        |
| Environment | <code>$CODER_PROVISIONER_DAEMON_PSK</code> |

Pre-shared key to authenticate external provisioner daemons to Coder server.

### -l, --log-filter

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string-array</code>                 |
| Environment | <code>$CODER_LOG_FILTER</code>            |
| YAML        | <code>introspection.logging.filter</code> |

Filter debug logs by matching against a given regex. Use .* to match all debug logs.

### --log-human

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>string</code>                          |
| Environment | <code>$CODER_LOGGING_HUMAN</code>            |
| YAML        | <code>introspection.logging.humanPath</code> |
| Default     | <code>/dev/stderr</code>                     |

Output human-readable logs to a given file.

### --log-json

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_LOGGING_JSON</code>            |
| YAML        | <code>introspection.logging.jsonPath</code> |

Output JSON logs to a given file.

### --log-stackdriver

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>string</code>                                |
| Environment | <code>$CODER_LOGGING_STACKDRIVER</code>            |
| YAML        | <code>introspection.logging.stackdriverPath</code> |

Output Stackdriver compatible logs to a given file.

### --enable-terraform-debug-mode

|             |                                                             |
|-------------|-------------------------------------------------------------|
| Type        | <code>bool</code>                                           |
| Environment | <code>$CODER_ENABLE_TERRAFORM_DEBUG_MODE</code>             |
| YAML        | <code>introspection.logging.enableTerraformDebugMode</code> |
| Default     | <code>false</code>                                          |

Allow administrators to enable Terraform debug output.

### --additional-csp-policy

|             |                                                  |
|-------------|--------------------------------------------------|
| Type        | <code>string-array</code>                        |
| Environment | <code>$CODER_ADDITIONAL_CSP_POLICY</code>        |
| YAML        | <code>networking.http.additionalCSPPolicy</code> |

Coder configures a Content Security Policy (CSP) to protect against XSS attacks. This setting allows you to add additional CSP directives, which can open the attack surface of the deployment. Format matches the CSP directive format, e.g. --additional-csp-policy="script-src https://example.com".

### --dangerous-allow-path-app-sharing

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_DANGEROUS_ALLOW_PATH_APP_SHARING</code> |

Allow workspace apps that are not served from subdomains to be shared. Path-based app sharing is DISABLED by default for security purposes. Path-based apps can make requests to the Coder API and pose a security risk when the workspace serves malicious JavaScript. Path-based apps can be disabled entirely with --disable-path-apps for further security.

### --dangerous-allow-path-app-site-owner-access

|             |                                                                |
|-------------|----------------------------------------------------------------|
| Type        | <code>bool</code>                                              |
| Environment | <code>$CODER_DANGEROUS_ALLOW_PATH_APP_SITE_OWNER_ACCESS</code> |

Allow site-owners to access workspace apps from workspaces they do not own. Owners cannot access path-based apps they do not own by default. Path-based apps can make requests to the Coder API and pose a security risk when the workspace serves malicious JavaScript. Path-based apps can be disabled entirely with --disable-path-apps for further security.

### --experiments

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string-array</code>       |
| Environment | <code>$CODER_EXPERIMENTS</code> |
| YAML        | <code>experiments</code>        |

Enable one or more experiments. These are not ready for production. Separate multiple experiments with commas, or enter '*' to opt-in to all available experiments.

### --update-check

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>bool</code>                |
| Environment | <code>$CODER_UPDATE_CHECK</code> |
| YAML        | <code>updateCheck</code>         |
| Default     | <code>false</code>               |

Periodically check for new releases of Coder and inform the owner. The check is performed once per day.

### --max-token-lifetime

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>duration</code>                         |
| Environment | <code>$CODER_MAX_TOKEN_LIFETIME</code>        |
| YAML        | <code>networking.http.maxTokenLifetime</code> |
| Default     | <code>876600h0m0s</code>                      |

The maximum lifetime duration users can specify when creating an API token.

### --max-admin-token-lifetime

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>duration</code>                              |
| Environment | <code>$CODER_MAX_ADMIN_TOKEN_LIFETIME</code>       |
| YAML        | <code>networking.http.maxAdminTokenLifetime</code> |
| Default     | <code>168h0m0s</code>                              |

The maximum lifetime duration administrators can specify when creating an API token.

### --default-token-lifetime

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>duration</code>                      |
| Environment | <code>$CODER_DEFAULT_TOKEN_LIFETIME</code> |
| YAML        | <code>defaultTokenLifetime</code>          |
| Default     | <code>168h0m0s</code>                      |

The default lifetime duration for API tokens. This value is used when creating a token without specifying a duration, such as when authenticating the CLI or an IDE plugin.

### --default-oauth-refresh-lifetime

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>duration</code>                              |
| Environment | <code>$CODER_DEFAULT_OAUTH_REFRESH_LIFETIME</code> |
| YAML        | <code>defaultOAuthRefreshLifetime</code>           |
| Default     | <code>720h0m0s</code>                              |

The default lifetime duration for OAuth2 refresh tokens. This controls how long refresh tokens remain valid after issuance or rotation.

### --swagger-enable

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>bool</code>                  |
| Environment | <code>$CODER_SWAGGER_ENABLE</code> |
| YAML        | <code>enableSwagger</code>         |

Expose the swagger endpoint via /swagger.

### --proxy-trusted-headers

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string-array</code>                   |
| Environment | <code>$CODER_PROXY_TRUSTED_HEADERS</code>   |
| YAML        | <code>networking.proxyTrustedHeaders</code> |

Headers to trust for forwarding IP addresses. e.g. Cf-Connecting-Ip, True-Client-Ip, X-Forwarded-For.

### --proxy-trusted-origins

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string-array</code>                   |
| Environment | <code>$CODER_PROXY_TRUSTED_ORIGINS</code>   |
| YAML        | <code>networking.proxyTrustedOrigins</code> |

Origin addresses to respect "proxy-trusted-headers". e.g. 192.168.1.0/24.

### --cache-dir

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_CACHE_DIRECTORY</code> |
| YAML        | <code>cacheDir</code>               |
| Default     | <code>~/.cache/coder</code>         |

The directory to cache temporary files. If unspecified and $CACHE_DIRECTORY is set, it will be used for compatibility with systemd. This directory is NOT safe to be configured as a shared directory across coderd/provisionerd replicas.

### --postgres-url

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string</code>                   |
| Environment | <code>$CODER_PG_CONNECTION_URL</code> |

URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded from Maven (https://repo1.maven.org/maven2) and store all data in the config root. Access the built-in database with "coder server postgres-builtin-url". Note that any special characters in the URL must be URL-encoded.

### --postgres-auth

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>password\|awsiamrds</code> |
| Environment | <code>$CODER_PG_AUTH</code>      |
| YAML        | <code>pgAuth</code>              |
| Default     | <code>password</code>            |

Type of auth to use when connecting to postgres. For AWS RDS, using IAM authentication (awsiamrds) is recommended.

### --postgres-conn-max-open

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>int</code>                     |
| Environment | <code>$CODER_PG_CONN_MAX_OPEN</code> |
| YAML        | <code>pgConnMaxOpen</code>           |
| Default     | <code>10</code>                      |

Maximum number of open connections to the database. Defaults to 10.

### --postgres-conn-max-idle

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_PG_CONN_MAX_IDLE</code> |
| YAML        | <code>pgConnMaxIdle</code>           |
| Default     | <code>auto</code>                    |

Maximum number of idle connections to the database. Set to "auto" (the default) to use max open / 3. Value must be greater or equal to 0; 0 means explicitly no idle connections.

### --secure-auth-cookie

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>bool</code>                        |
| Environment | <code>$CODER_SECURE_AUTH_COOKIE</code>   |
| YAML        | <code>networking.secureAuthCookie</code> |

Controls if the 'Secure' property is set on browser session cookies.

### --samesite-auth-cookie

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>lax\|none</code>                     |
| Environment | <code>$CODER_SAMESITE_AUTH_COOKIE</code>   |
| YAML        | <code>networking.sameSiteAuthCookie</code> |
| Default     | <code>lax</code>                           |

Controls the 'SameSite' property is set on browser session cookies.

### --host-prefix-cookie

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>bool</code>                        |
| Environment | <code>$CODER_HOST_PREFIX_COOKIE</code>   |
| YAML        | <code>networking.hostPrefixCookie</code> |
| Default     | <code>false</code>                       |

Recommended to be enabled. Enables `__Host-` prefix for cookies to guarantee they are only set by the right domain. This change is disruptive to any workspaces built before release 2.31, requiring a workspace restart.

### --terms-of-service-url

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_TERMS_OF_SERVICE_URL</code> |
| YAML        | <code>termsOfServiceURL</code>           |

A URL to an external Terms of Service that must be accepted by users when logging in.

### --strict-transport-security

|             |                                                     |
|-------------|-----------------------------------------------------|
| Type        | <code>int</code>                                    |
| Environment | <code>$CODER_STRICT_TRANSPORT_SECURITY</code>       |
| YAML        | <code>networking.tls.strictTransportSecurity</code> |
| Default     | <code>0</code>                                      |

Controls if the 'Strict-Transport-Security' header is set on all static file responses. This header should only be set if the server is accessed via HTTPS. This value is the MaxAge in seconds of the header.

### --strict-transport-security-options

|             |                                                            |
|-------------|------------------------------------------------------------|
| Type        | <code>string-array</code>                                  |
| Environment | <code>$CODER_STRICT_TRANSPORT_SECURITY_OPTIONS</code>      |
| YAML        | <code>networking.tls.strictTransportSecurityOptions</code> |

Two optional fields can be set in the Strict-Transport-Security header; 'includeSubDomains' and 'preload'. The 'strict-transport-security' flag must be set to a non-zero value for these options to be used.

### --ssh-keygen-algorithm

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_SSH_KEYGEN_ALGORITHM</code> |
| YAML        | <code>sshKeygenAlgorithm</code>          |
| Default     | <code>ed25519</code>                     |

The algorithm to use for generating ssh keys. Accepted values are "ed25519", "ecdsa", or "rsa4096".

### --browser-only

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>bool</code>                   |
| Environment | <code>$CODER_BROWSER_ONLY</code>    |
| YAML        | <code>networking.browserOnly</code> |

Whether Coder only allows connections to workspaces via the browser.

### --scim-auth-header

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_SCIM_AUTH_HEADER</code> |

Enables SCIM and sets the authentication header for the built-in SCIM server. New users are automatically created with OIDC authentication.

### --external-token-encryption-keys

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>string-array</code>                          |
| Environment | <code>$CODER_EXTERNAL_TOKEN_ENCRYPTION_KEYS</code> |

Encrypt OIDC and Git authentication tokens with AES-256-GCM in the database. The value must be a comma-separated list of base64-encoded keys. Each key, when base64-decoded, must be exactly 32 bytes in length. The first key will be used to encrypt new values. Subsequent keys will be used as a fallback when decrypting. During normal operation it is recommended to only set one key unless you are in the process of rotating keys with the `coder server dbcrypt rotate` command.

### --disable-path-apps

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>bool</code>                     |
| Environment | <code>$CODER_DISABLE_PATH_APPS</code> |
| YAML        | <code>disablePathApps</code>          |

Disable workspace apps that are not served from subdomains. Path-based apps can make requests to the Coder API and pose a security risk when the workspace serves malicious JavaScript. This is recommended for security purposes if a --wildcard-access-url is configured.

### --disable-owner-workspace-access

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>bool</code>                                  |
| Environment | <code>$CODER_DISABLE_OWNER_WORKSPACE_ACCESS</code> |
| YAML        | <code>disableOwnerWorkspaceAccess</code>           |

Remove the permission for the 'owner' role to have workspace execution on all workspaces. This prevents the 'owner' from ssh, apps, and terminal access based on the 'owner' role. They still have their user permissions to access their own workspaces.

### --disable-workspace-sharing

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>bool</code>                             |
| Environment | <code>$CODER_DISABLE_WORKSPACE_SHARING</code> |
| YAML        | <code>disableWorkspaceSharing</code>          |

Disable workspace sharing. Workspace ACL checking is disabled and only owners can have ssh, apps and terminal access to workspaces. Access based on the 'owner' role is also allowed unless disabled via --disable-owner-workspace-access.

### --session-duration

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>duration</code>                        |
| Environment | <code>$CODER_SESSION_DURATION</code>         |
| YAML        | <code>networking.http.sessionDuration</code> |
| Default     | <code>24h0m0s</code>                         |

The token expiry duration for browser sessions. Sessions may last longer if they are actively making requests, but this functionality can be disabled via --disable-session-expiry-refresh.

### --disable-session-expiry-refresh

|             |                                                          |
|-------------|----------------------------------------------------------|
| Type        | <code>bool</code>                                        |
| Environment | <code>$CODER_DISABLE_SESSION_EXPIRY_REFRESH</code>       |
| YAML        | <code>networking.http.disableSessionExpiryRefresh</code> |

Disable automatic session expiry bumping due to activity. This forces all sessions to become invalid after the session expiry duration has been reached.

### --disable-password-auth

|             |                                                  |
|-------------|--------------------------------------------------|
| Type        | <code>bool</code>                                |
| Environment | <code>$CODER_DISABLE_PASSWORD_AUTH</code>        |
| YAML        | <code>networking.http.disablePasswordAuth</code> |

Disable password authentication. This is recommended for security purposes in production deployments that rely on an identity provider. Any user with the owner role will be able to sign in with their password regardless of this setting to avoid potential lock out. If you are locked out of your account, you can use the `coder server create-admin` command to create a new admin user directly in the database.

### -c, --config

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>yaml-config-path</code>   |
| Environment | <code>$CODER_CONFIG_PATH</code> |

Specify a YAML file to load configuration from.

### --workspace-hostname-suffix

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>string</code>                           |
| Environment | <code>$CODER_WORKSPACE_HOSTNAME_SUFFIX</code> |
| YAML        | <code>client.workspaceHostnameSuffix</code>   |
| Default     | <code>coder</code>                            |

Workspace hostnames use this suffix in SSH config and Coder Connect on Coder Desktop. By default it is coder, resulting in names like myworkspace.coder.

### --ssh-config-options

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string-array</code>              |
| Environment | <code>$CODER_SSH_CONFIG_OPTIONS</code> |
| YAML        | <code>client.sshConfigOptions</code>   |

These SSH config options will override the default SSH config options. Provide options in "key=value" or "key value" format separated by commas.Using this incorrectly can break SSH to your deployment, use cautiously.

### --cli-upgrade-message

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_CLI_UPGRADE_MESSAGE</code> |
| YAML        | <code>client.cliUpgradeMessage</code>   |

The upgrade message to display to users when a client/server mismatch is detected. By default it instructs users to update using 'curl -L https://coder.com/install.sh | sh'.

### --write-config

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

<br/>Write out the current server config as YAML to stdout.

### --support-links

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>struct[[]codersdk.LinkConfig]</code> |
| Environment | <code>$CODER_SUPPORT_LINKS</code>          |
| YAML        | <code>supportLinks</code>                  |

Support links to display in the top right drop down menu.

### --external-auth-github-default-provider-enable

|             |                                                                  |
|-------------|------------------------------------------------------------------|
| Type        | <code>bool</code>                                                |
| Environment | <code>$CODER_EXTERNAL_AUTH_GITHUB_DEFAULT_PROVIDER_ENABLE</code> |
| YAML        | <code>externalAuthGithubDefaultProviderEnable</code>             |
| Default     | <code>true</code>                                                |

Enable the default GitHub external auth provider managed by Coder.

### --proxy-health-interval

|             |                                                  |
|-------------|--------------------------------------------------|
| Type        | <code>duration</code>                            |
| Environment | <code>$CODER_PROXY_HEALTH_INTERVAL</code>        |
| YAML        | <code>networking.http.proxyHealthInterval</code> |
| Default     | <code>1m0s</code>                                |

The interval in which coderd should be checking the status of workspace proxies.

### --default-quiet-hours-schedule

|             |                                                               |
|-------------|---------------------------------------------------------------|
| Type        | <code>string</code>                                           |
| Environment | <code>$CODER_QUIET_HOURS_DEFAULT_SCHEDULE</code>              |
| YAML        | <code>userQuietHoursSchedule.defaultQuietHoursSchedule</code> |
| Default     | <code>CRON_TZ=UTC 0 0 ** *</code>                             |

The default daily cron schedule applied to users that haven't set a custom quiet hours schedule themselves. The quiet hours schedule determines when workspaces will be force stopped due to the template's autostop requirement, and will round the max deadline up to be within the user's quiet hours window (or default). The format is the same as the standard cron format, but the day-of-month, month and day-of-week must be *. Only one hour and minute can be specified (ranges or comma separated values are not supported).

### --allow-custom-quiet-hours

|             |                                                           |
|-------------|-----------------------------------------------------------|
| Type        | <code>bool</code>                                         |
| Environment | <code>$CODER_ALLOW_CUSTOM_QUIET_HOURS</code>              |
| YAML        | <code>userQuietHoursSchedule.allowCustomQuietHours</code> |
| Default     | <code>true</code>                                         |

Allow users to set their own quiet hours schedule for workspaces to stop in (depending on template autostop requirement settings). If false, users can't change their quiet hours schedule and the site default is always used.

### --web-terminal-renderer

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string</code>                       |
| Environment | <code>$CODER_WEB_TERMINAL_RENDERER</code> |
| YAML        | <code>client.webTerminalRenderer</code>   |
| Default     | <code>canvas</code>                       |

The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'.

### --allow-workspace-renames

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>bool</code>                           |
| Environment | <code>$CODER_ALLOW_WORKSPACE_RENAMES</code> |
| YAML        | <code>allowWorkspaceRenames</code>          |
| Default     | <code>false</code>                          |

Allow users to rename their workspaces. WARNING: Renaming a workspace can cause Terraform resources that depend on the workspace name to be destroyed and recreated, potentially causing data loss. Only enable this if your templates do not use workspace names in resource identifiers, or if you understand the risks.

### --health-check-refresh

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>duration</code>                          |
| Environment | <code>$CODER_HEALTH_CHECK_REFRESH</code>       |
| YAML        | <code>introspection.healthcheck.refresh</code> |
| Default     | <code>10m0s</code>                             |

Refresh interval for healthchecks.

### --health-check-threshold-database

|             |                                                          |
|-------------|----------------------------------------------------------|
| Type        | <code>duration</code>                                    |
| Environment | <code>$CODER_HEALTH_CHECK_THRESHOLD_DATABASE</code>      |
| YAML        | <code>introspection.healthcheck.thresholdDatabase</code> |
| Default     | <code>15ms</code>                                        |

The threshold for the database health check. If the median latency of the database exceeds this threshold over 5 attempts, the database is considered unhealthy. The default value is 15ms.

### --email-from

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_EMAIL_FROM</code> |
| YAML        | <code>email.from</code>        |

The sender's address to use.

### --email-smarthost

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>string</code>                 |
| Environment | <code>$CODER_EMAIL_SMARTHOST</code> |
| YAML        | <code>email.smarthost</code>        |

The intermediary SMTP host through which emails are sent.

### --email-hello

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string</code>             |
| Environment | <code>$CODER_EMAIL_HELLO</code> |
| YAML        | <code>email.hello</code>        |
| Default     | <code>localhost</code>          |

The hostname identifying the SMTP server.

### --email-force-tls

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>bool</code>                   |
| Environment | <code>$CODER_EMAIL_FORCE_TLS</code> |
| YAML        | <code>email.forceTLS</code>         |
| Default     | <code>false</code>                  |

Force a TLS connection to the configured SMTP smarthost.

### --email-auth-identity

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_EMAIL_AUTH_IDENTITY</code> |
| YAML        | <code>email.emailAuth.identity</code>   |

Identity to use with PLAIN authentication.

### --email-auth-username

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_EMAIL_AUTH_USERNAME</code> |
| YAML        | <code>email.emailAuth.username</code>   |

Username to use with PLAIN/LOGIN authentication.

### --email-auth-password

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_EMAIL_AUTH_PASSWORD</code> |

Password to use with PLAIN/LOGIN authentication.

### --email-auth-password-file

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>string</code>                          |
| Environment | <code>$CODER_EMAIL_AUTH_PASSWORD_FILE</code> |
| YAML        | <code>email.emailAuth.passwordFile</code>    |

File from which to load password for use with PLAIN/LOGIN authentication.

### --email-tls-starttls

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>bool</code>                      |
| Environment | <code>$CODER_EMAIL_TLS_STARTTLS</code> |
| YAML        | <code>email.emailTLS.startTLS</code>   |

Enable STARTTLS to upgrade insecure SMTP connections using TLS.

### --email-tls-server-name

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_EMAIL_TLS_SERVERNAME</code> |
| YAML        | <code>email.emailTLS.serverName</code>   |

Server name to verify against the target certificate.

### --email-tls-skip-verify

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_EMAIL_TLS_SKIPVERIFY</code>       |
| YAML        | <code>email.emailTLS.insecureSkipVerify</code> |

Skip verification of the target server's certificate (insecure).

### --email-tls-ca-cert-file

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_EMAIL_TLS_CACERTFILE</code> |
| YAML        | <code>email.emailTLS.caCertFile</code>   |

CA certificate file to use.

### --email-tls-cert-file

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_EMAIL_TLS_CERTFILE</code> |
| YAML        | <code>email.emailTLS.certFile</code>   |

Certificate file to use.

### --email-tls-cert-key-file

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string</code>                       |
| Environment | <code>$CODER_EMAIL_TLS_CERTKEYFILE</code> |
| YAML        | <code>email.emailTLS.certKeyFile</code>   |

Certificate key file to use.

### --notifications-method

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_NOTIFICATIONS_METHOD</code> |
| YAML        | <code>notifications.method</code>        |
| Default     | <code>smtp</code>                        |

Which delivery method to use (available options: 'smtp', 'webhook').

### --notifications-dispatch-timeout

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>duration</code>                              |
| Environment | <code>$CODER_NOTIFICATIONS_DISPATCH_TIMEOUT</code> |
| YAML        | <code>notifications.dispatchTimeout</code>         |
| Default     | <code>1m0s</code>                                  |

How long to wait while a notification is being sent before giving up.

### --notifications-email-from

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>string</code>                          |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_FROM</code> |
| YAML        | <code>notifications.email.from</code>        |

The sender's address to use.

### --notifications-email-smarthost

|             |                                                   |
|-------------|---------------------------------------------------|
| Type        | <code>string</code>                               |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_SMARTHOST</code> |
| YAML        | <code>notifications.email.smarthost</code>        |

The intermediary SMTP host through which emails are sent.

### --notifications-email-hello

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>string</code>                           |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_HELLO</code> |
| YAML        | <code>notifications.email.hello</code>        |

The hostname identifying the SMTP server.

### --notifications-email-force-tls

|             |                                                   |
|-------------|---------------------------------------------------|
| Type        | <code>bool</code>                                 |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_FORCE_TLS</code> |
| YAML        | <code>notifications.email.forceTLS</code>         |

Force a TLS connection to the configured SMTP smarthost.

### --notifications-email-auth-identity

|             |                                                       |
|-------------|-------------------------------------------------------|
| Type        | <code>string</code>                                   |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_AUTH_IDENTITY</code> |
| YAML        | <code>notifications.email.emailAuth.identity</code>   |

Identity to use with PLAIN authentication.

### --notifications-email-auth-username

|             |                                                       |
|-------------|-------------------------------------------------------|
| Type        | <code>string</code>                                   |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_AUTH_USERNAME</code> |
| YAML        | <code>notifications.email.emailAuth.username</code>   |

Username to use with PLAIN/LOGIN authentication.

### --notifications-email-auth-password

|             |                                                       |
|-------------|-------------------------------------------------------|
| Type        | <code>string</code>                                   |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_AUTH_PASSWORD</code> |

Password to use with PLAIN/LOGIN authentication.

### --notifications-email-auth-password-file

|             |                                                            |
|-------------|------------------------------------------------------------|
| Type        | <code>string</code>                                        |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_AUTH_PASSWORD_FILE</code> |
| YAML        | <code>notifications.email.emailAuth.passwordFile</code>    |

File from which to load password for use with PLAIN/LOGIN authentication.

### --notifications-email-tls-starttls

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_TLS_STARTTLS</code> |
| YAML        | <code>notifications.email.emailTLS.startTLS</code>   |

Enable STARTTLS to upgrade insecure SMTP connections using TLS.

### --notifications-email-tls-server-name

|             |                                                        |
|-------------|--------------------------------------------------------|
| Type        | <code>string</code>                                    |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_TLS_SERVERNAME</code> |
| YAML        | <code>notifications.email.emailTLS.serverName</code>   |

Server name to verify against the target certificate.

### --notifications-email-tls-skip-verify

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Type        | <code>bool</code>                                            |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_TLS_SKIPVERIFY</code>       |
| YAML        | <code>notifications.email.emailTLS.insecureSkipVerify</code> |

Skip verification of the target server's certificate (insecure).

### --notifications-email-tls-ca-cert-file

|             |                                                        |
|-------------|--------------------------------------------------------|
| Type        | <code>string</code>                                    |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_TLS_CACERTFILE</code> |
| YAML        | <code>notifications.email.emailTLS.caCertFile</code>   |

CA certificate file to use.

### --notifications-email-tls-cert-file

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>string</code>                                  |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_TLS_CERTFILE</code> |
| YAML        | <code>notifications.email.emailTLS.certFile</code>   |

Certificate file to use.

### --notifications-email-tls-cert-key-file

|             |                                                         |
|-------------|---------------------------------------------------------|
| Type        | <code>string</code>                                     |
| Environment | <code>$CODER_NOTIFICATIONS_EMAIL_TLS_CERTKEYFILE</code> |
| YAML        | <code>notifications.email.emailTLS.certKeyFile</code>   |

Certificate key file to use.

### --notifications-webhook-endpoint

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>url</code>                                   |
| Environment | <code>$CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT</code> |
| YAML        | <code>notifications.webhook.endpoint</code>        |

The endpoint to which to send webhooks.

### --notifications-inbox-enabled

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_NOTIFICATIONS_INBOX_ENABLED</code> |
| YAML        | <code>notifications.inbox.enabled</code>        |
| Default     | <code>true</code>                               |

Enable Coder Inbox.

### --notifications-max-send-attempts

|             |                                                     |
|-------------|-----------------------------------------------------|
| Type        | <code>int</code>                                    |
| Environment | <code>$CODER_NOTIFICATIONS_MAX_SEND_ATTEMPTS</code> |
| YAML        | <code>notifications.maxSendAttempts</code>          |
| Default     | <code>5</code>                                      |

The upper limit of attempts to send a notification.

### --workspace-prebuilds-reconciliation-interval

|             |                                                                 |
|-------------|-----------------------------------------------------------------|
| Type        | <code>duration</code>                                           |
| Environment | <code>$CODER_WORKSPACE_PREBUILDS_RECONCILIATION_INTERVAL</code> |
| YAML        | <code>workspace_prebuilds.reconciliation_interval</code>        |
| Default     | <code>1m0s</code>                                               |

How often to reconcile workspace prebuilds state.

### --hide-ai-tasks

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>bool</code>                 |
| Environment | <code>$CODER_HIDE_AI_TASKS</code> |
| YAML        | <code>client.hideAITasks</code>   |
| Default     | <code>false</code>                |

Hide AI tasks from the dashboard.

### --chat-debug-logging-enabled

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>bool</code>                              |
| Environment | <code>$CODER_CHAT_DEBUG_LOGGING_ENABLED</code> |
| YAML        | <code>chat.debugLoggingEnabled</code>          |
| Default     | <code>false</code>                             |

Force chat debug logging on for every chat, bypassing the runtime admin and user opt-in settings.

### --aibridge-enabled

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>bool</code>                    |
| Environment | <code>$CODER_AIBRIDGE_ENABLED</code> |
| YAML        | <code>aibridge.enabled</code>        |
| Default     | <code>false</code>                   |

Whether to start an in-memory aibridged instance.

### --aibridge-openai-base-url

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>string</code>                          |
| Environment | <code>$CODER_AIBRIDGE_OPENAI_BASE_URL</code> |
| YAML        | <code>aibridge.openai_base_url</code>        |
| Default     | <code>https://api.openai.com/v1/</code>      |

The base URL of the OpenAI API.

### --aibridge-openai-key

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_AIBRIDGE_OPENAI_KEY</code> |

The key to authenticate against the OpenAI API.

### --aibridge-anthropic-base-url

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string</code>                             |
| Environment | <code>$CODER_AIBRIDGE_ANTHROPIC_BASE_URL</code> |
| YAML        | <code>aibridge.anthropic_base_url</code>        |
| Default     | <code>https://api.anthropic.com/</code>         |

The base URL of the Anthropic API.

### --aibridge-anthropic-key

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string</code>                        |
| Environment | <code>$CODER_AIBRIDGE_ANTHROPIC_KEY</code> |

The key to authenticate against the Anthropic API.

### --aibridge-bedrock-base-url

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>string</code>                           |
| Environment | <code>$CODER_AIBRIDGE_BEDROCK_BASE_URL</code> |
| YAML        | <code>aibridge.bedrock_base_url</code>        |

The base URL to use for the AWS Bedrock API. Use this setting to specify an exact URL to use. Takes precedence over CODER_AIBRIDGE_BEDROCK_REGION.

### --aibridge-bedrock-region

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_AIBRIDGE_BEDROCK_REGION</code> |
| YAML        | <code>aibridge.bedrock_region</code>        |

The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form of 'https://bedrock-runtime.<region>.amazonaws.com'.

### --aibridge-bedrock-access-key

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string</code>                             |
| Environment | <code>$CODER_AIBRIDGE_BEDROCK_ACCESS_KEY</code> |

The access key to authenticate against the AWS Bedrock API.

### --aibridge-bedrock-access-key-secret

|             |                                                        |
|-------------|--------------------------------------------------------|
| Type        | <code>string</code>                                    |
| Environment | <code>$CODER_AIBRIDGE_BEDROCK_ACCESS_KEY_SECRET</code> |

The access key secret to use with the access key to authenticate against the AWS Bedrock API.

### --aibridge-bedrock-model

|             |                                                               |
|-------------|---------------------------------------------------------------|
| Type        | <code>string</code>                                           |
| Environment | <code>$CODER_AIBRIDGE_BEDROCK_MODEL</code>                    |
| YAML        | <code>aibridge.bedrock_model</code>                           |
| Default     | <code>global.anthropic.claude-sonnet-4-5-20250929-v1:0</code> |

The model to use when making requests to the AWS Bedrock API.

### --aibridge-bedrock-small-fastmodel

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Type        | <code>string</code>                                          |
| Environment | <code>$CODER_AIBRIDGE_BEDROCK_SMALL_FAST_MODEL</code>        |
| YAML        | <code>aibridge.bedrock_small_fast_model</code>               |
| Default     | <code>global.anthropic.claude-haiku-4-5-20251001-v1:0</code> |

The small fast model to use when making requests to the AWS Bedrock API. Claude Code uses Haiku-class models to perform background tasks. See https://docs.claude.com/en/docs/claude-code/settings#environment-variables.

### --aibridge-retention

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>duration</code>                  |
| Environment | <code>$CODER_AIBRIDGE_RETENTION</code> |
| YAML        | <code>aibridge.retention</code>        |
| Default     | <code>60d</code>                       |

Length of time to retain data such as interceptions and all related records (token, prompt, tool use).

### --aibridge-max-concurrency

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>int</code>                             |
| Environment | <code>$CODER_AIBRIDGE_MAX_CONCURRENCY</code> |
| YAML        | <code>aibridge.max_concurrency</code>        |
| Default     | <code>0</code>                               |

Maximum number of concurrent AI Bridge requests per replica. Set to 0 to disable (unlimited).

### --aibridge-rate-limit

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>int</code>                        |
| Environment | <code>$CODER_AIBRIDGE_RATE_LIMIT</code> |
| YAML        | <code>aibridge.rate_limit</code>        |
| Default     | <code>0</code>                          |

Maximum number of AI Bridge requests per second per replica. Set to 0 to disable (unlimited).

### --aibridge-structured-logging

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_AIBRIDGE_STRUCTURED_LOGGING</code> |
| YAML        | <code>aibridge.structured_logging</code>        |
| Default     | <code>false</code>                              |

Emit structured logs for AI Bridge interception records. Use this for exporting these records to external SIEM or observability systems.

### --aibridge-send-actor-headers

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_AIBRIDGE_SEND_ACTOR_HEADERS</code> |
| YAML        | <code>aibridge.send_actor_headers</code>        |
| Default     | <code>false</code>                              |

Once enabled, extra headers will be added to upstream requests to identify the user (actor) making requests to AI Bridge. This is only needed if you are using a proxy between AI Bridge and an upstream AI provider. This will send X-Ai-Bridge-Actor-Id (the ID of the user making the request) and X-Ai-Bridge-Actor-Metadata-Username (their username).

### --aibridge-allow-byok

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>bool</code>                       |
| Environment | <code>$CODER_AIBRIDGE_ALLOW_BYOK</code> |
| YAML        | <code>aibridge.allow_byok</code>        |
| Default     | <code>true</code>                       |

Allow users to provide their own LLM API keys or subscriptions. When disabled, only centralized key authentication is permitted.

### --aibridge-circuit-breaker-enabled

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_AIBRIDGE_CIRCUIT_BREAKER_ENABLED</code> |
| YAML        | <code>aibridge.circuit_breaker_enabled</code>        |
| Default     | <code>false</code>                                   |

Enable the circuit breaker to protect against cascading failures from upstream AI provider overload (503, 529).

### --aibridge-proxy-enabled

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>bool</code>                          |
| Environment | <code>$CODER_AIBRIDGE_PROXY_ENABLED</code> |
| YAML        | <code>aibridgeproxy.enabled</code>         |
| Default     | <code>false</code>                         |

Enable the AI Bridge MITM Proxy for intercepting and decrypting AI provider requests.

### --aibridge-proxy-listen-addr

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>string</code>                            |
| Environment | <code>$CODER_AIBRIDGE_PROXY_LISTEN_ADDR</code> |
| YAML        | <code>aibridgeproxy.listen_addr</code>         |
| Default     | <code>:8888</code>                             |

The address the AI Bridge Proxy will listen on.

### --aibridge-proxy-tls-cert-file

|             |                                                  |
|-------------|--------------------------------------------------|
| Type        | <code>string</code>                              |
| Environment | <code>$CODER_AIBRIDGE_PROXY_TLS_CERT_FILE</code> |
| YAML        | <code>aibridgeproxy.tls_cert_file</code>         |

Path to the TLS certificate file for the AI Bridge Proxy listener. Must be set together with AI Bridge Proxy TLS Key File.

### --aibridge-proxy-tls-key-file

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string</code>                             |
| Environment | <code>$CODER_AIBRIDGE_PROXY_TLS_KEY_FILE</code> |
| YAML        | <code>aibridgeproxy.tls_key_file</code>         |

Path to the TLS private key file for the AI Bridge Proxy listener. Must be set together with AI Bridge Proxy TLS Certificate File.

### --aibridge-proxy-cert-file

|             |                                              |
|-------------|----------------------------------------------|
| Type        | <code>string</code>                          |
| Environment | <code>$CODER_AIBRIDGE_PROXY_CERT_FILE</code> |
| YAML        | <code>aibridgeproxy.cert_file</code>         |

Path to the CA certificate file used to intercept (MITM) HTTPS traffic from AI clients. This CA must be trusted by AI clients for the proxy to decrypt their requests.

### --aibridge-proxy-key-file

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_AIBRIDGE_PROXY_KEY_FILE</code> |
| YAML        | <code>aibridgeproxy.key_file</code>         |

Path to the CA private key file used to intercept (MITM) HTTPS traffic from AI clients.

### --aibridge-proxy-upstream

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_AIBRIDGE_PROXY_UPSTREAM</code> |
| YAML        | <code>aibridgeproxy.upstream_proxy</code>   |

URL of an upstream HTTP proxy to chain tunneled (non-allowlisted) requests through. Format: http://[user:pass@]host:port or https://[user:pass@]host:port.

### --aibridge-proxy-upstream-ca

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>string</code>                            |
| Environment | <code>$CODER_AIBRIDGE_PROXY_UPSTREAM_CA</code> |
| YAML        | <code>aibridgeproxy.upstream_proxy_ca</code>   |

Path to a PEM-encoded CA certificate to trust for the upstream proxy's TLS connection. Only needed for HTTPS upstream proxies with certificates not trusted by the system. If not provided, the system certificate pool is used.

### --aibridge-proxy-allowed-private-cidrs

|             |                                                          |
|-------------|----------------------------------------------------------|
| Type        | <code>string-array</code>                                |
| Environment | <code>$CODER_AIBRIDGE_PROXY_ALLOWED_PRIVATE_CIDRS</code> |
| YAML        | <code>aibridgeproxy.allowed_private_cidrs</code>         |

Comma-separated list of CIDR ranges that are permitted even though they fall within blocked private/reserved IP ranges. By default all private ranges are blocked to prevent SSRF attacks. Use this to allow access to specific internal networks.

### --audit-logs-retention

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>duration</code>                    |
| Environment | <code>$CODER_AUDIT_LOGS_RETENTION</code> |
| YAML        | <code>retention.audit_logs</code>        |
| Default     | <code>0</code>                           |

How long audit log entries are retained. Set to 0 to disable (keep indefinitely). We advise keeping audit logs for at least a year, and in accordance with your compliance requirements.

### --connection-logs-retention

|             |                                               |
|-------------|-----------------------------------------------|
| Type        | <code>duration</code>                         |
| Environment | <code>$CODER_CONNECTION_LOGS_RETENTION</code> |
| YAML        | <code>retention.connection_logs</code>        |
| Default     | <code>0</code>                                |

How long connection log entries are retained. Set to 0 to disable (keep indefinitely).

### --api-keys-retention

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>duration</code>                  |
| Environment | <code>$CODER_API_KEYS_RETENTION</code> |
| YAML        | <code>retention.api_keys</code>        |
| Default     | <code>7d</code>                        |

How long expired API keys are retained before being deleted. Keeping expired keys allows the backend to return a more helpful error when a user tries to use an expired key. Set to 0 to disable automatic deletion of expired keys.

### --workspace-agent-logs-retention

|             |                                                    |
|-------------|----------------------------------------------------|
| Type        | <code>duration</code>                              |
| Environment | <code>$CODER_WORKSPACE_AGENT_LOGS_RETENTION</code> |
| YAML        | <code>retention.workspace_agent_logs</code>        |
| Default     | <code>7d</code>                                    |

How long workspace agent logs are retained. Logs from non-latest builds are deleted if the agent hasn't connected within this period. Logs from the latest build are always retained. Set to 0 to disable automatic deletion.

---

# server create-admin-user

Source: https://coder.com/docs/reference/cli/server_create-admin-user

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server create-admin-user

Create a new admin user with the given username, email and password and adds it to every organization.

## Usage

```console
coder server create-admin-user [flags]
```

## Options

### --postgres-url

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string</code>                   |
| Environment | <code>$CODER_PG_CONNECTION_URL</code> |

URL of a PostgreSQL database. If empty, the built-in PostgreSQL deployment will be used (Coder must not be already running in this case).

### --postgres-connection-auth

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>password\|awsiamrds</code>       |
| Environment | <code>$CODER_PG_CONNECTION_AUTH</code> |
| Default     | <code>password</code>                  |

Type of auth to use when connecting to postgres.

### --ssh-keygen-algorithm

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>string</code>                      |
| Environment | <code>$CODER_SSH_KEYGEN_ALGORITHM</code> |
| Default     | <code>ed25519</code>                     |

The algorithm to use for generating ssh keys. Accepted values are "ed25519", "ecdsa", or "rsa4096".

### --username

|             |                              |
|-------------|------------------------------|
| Type        | <code>string</code>          |
| Environment | <code>$CODER_USERNAME</code> |

The username of the new user. If not specified, you will be prompted via stdin.

### --email

|             |                           |
|-------------|---------------------------|
| Type        | <code>string</code>       |
| Environment | <code>$CODER_EMAIL</code> |

The email of the new user. If not specified, you will be prompted via stdin.

### --password

|             |                              |
|-------------|------------------------------|
| Type        | <code>string</code>          |
| Environment | <code>$CODER_PASSWORD</code> |

The password of the new user. If not specified, you will be prompted via stdin.

### --raw-url

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Output the raw connection URL instead of a psql command.

---

# server dbcrypt

Source: https://coder.com/docs/reference/cli/server_dbcrypt

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server dbcrypt

Manage database encryption.

## Usage

```console
coder server dbcrypt
```

## Subcommands

| Name                                                | Purpose                                                                       |
|-----------------------------------------------------|-------------------------------------------------------------------------------|
| [<code>decrypt</code>](./server_dbcrypt_decrypt.md) | Decrypt a previously encrypted database.                                      |
| [<code>delete</code>](./server_dbcrypt_delete.md)   | Delete all encrypted data from the database. THIS IS A DESTRUCTIVE OPERATION. |
| [<code>rotate</code>](./server_dbcrypt_rotate.md)   | Rotate database encryption keys.                                              |

---

# server dbcrypt decrypt

Source: https://coder.com/docs/reference/cli/server_dbcrypt_decrypt

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server dbcrypt decrypt

Decrypt a previously encrypted database.

## Usage

```console
coder server dbcrypt decrypt [flags]
```

## Options

### --postgres-url

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string</code>                   |
| Environment | <code>$CODER_PG_CONNECTION_URL</code> |

The connection URL for the Postgres database.

### --postgres-connection-auth

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>password\|awsiamrds</code>       |
| Environment | <code>$CODER_PG_CONNECTION_AUTH</code> |
| Default     | <code>password</code>                  |

Type of auth to use when connecting to postgres.

### --keys

|             |                                                            |
|-------------|------------------------------------------------------------|
| Type        | <code>string-array</code>                                  |
| Environment | <code>$CODER_EXTERNAL_TOKEN_ENCRYPTION_DECRYPT_KEYS</code> |

Keys required to decrypt existing data. Must be a comma-separated list of base64-encoded keys.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# server dbcrypt delete

Source: https://coder.com/docs/reference/cli/server_dbcrypt_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server dbcrypt delete

Delete all encrypted data from the database. THIS IS A DESTRUCTIVE OPERATION.

Aliases:

* rm

## Usage

```console
coder server dbcrypt delete [flags]
```

## Options

### --postgres-url

|             |                                                            |
|-------------|------------------------------------------------------------|
| Type        | <code>string</code>                                        |
| Environment | <code>$CODER_EXTERNAL_TOKEN_ENCRYPTION_POSTGRES_URL</code> |

The connection URL for the Postgres database.

### --postgres-connection-auth

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>password\|awsiamrds</code>       |
| Environment | <code>$CODER_PG_CONNECTION_AUTH</code> |
| Default     | <code>password</code>                  |

Type of auth to use when connecting to postgres.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# server dbcrypt rotate

Source: https://coder.com/docs/reference/cli/server_dbcrypt_rotate

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server dbcrypt rotate

Rotate database encryption keys.

## Usage

```console
coder server dbcrypt rotate [flags]
```

## Options

### --postgres-url

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>string</code>                   |
| Environment | <code>$CODER_PG_CONNECTION_URL</code> |

The connection URL for the Postgres database.

### --postgres-connection-auth

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>password\|awsiamrds</code>       |
| Environment | <code>$CODER_PG_CONNECTION_AUTH</code> |
| Default     | <code>password</code>                  |

Type of auth to use when connecting to postgres.

### --new-key

|             |                                                               |
|-------------|---------------------------------------------------------------|
| Type        | <code>string</code>                                           |
| Environment | <code>$CODER_EXTERNAL_TOKEN_ENCRYPTION_ENCRYPT_NEW_KEY</code> |

The new external token encryption key. Must be base64-encoded.

### --old-keys

|             |                                                                |
|-------------|----------------------------------------------------------------|
| Type        | <code>string-array</code>                                      |
| Environment | <code>$CODER_EXTERNAL_TOKEN_ENCRYPTION_ENCRYPT_OLD_KEYS</code> |

The old external token encryption keys. Must be a comma-separated list of base64-encoded keys.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# server postgres-builtin-serve

Source: https://coder.com/docs/reference/cli/server_postgres-builtin-serve

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server postgres-builtin-serve

Run the built-in PostgreSQL deployment.

## Usage

```console
coder server postgres-builtin-serve [flags]
```

## Options

### --raw-url

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Output the raw connection URL instead of a psql command.

---

# server postgres-builtin-url

Source: https://coder.com/docs/reference/cli/server_postgres-builtin-url

<!-- DO NOT EDIT | GENERATED CONTENT -->
# server postgres-builtin-url

Output the connection URL for the built-in PostgreSQL deployment.

## Usage

```console
coder server postgres-builtin-url [flags]
```

## Options

### --raw-url

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Output the raw connection URL instead of a psql command.

---

# show

Source: https://coder.com/docs/reference/cli/show

<!-- DO NOT EDIT | GENERATED CONTENT -->
# show

Display details of a workspace's resources and agents

## Usage

```console
coder show [flags] <workspace>
```

## Options

### --details

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Show full error messages and additional details.

---

# speedtest

Source: https://coder.com/docs/reference/cli/speedtest

<!-- DO NOT EDIT | GENERATED CONTENT -->
# speedtest

Run upload and download tests from your machine to a workspace

## Usage

```console
coder speedtest [flags] <workspace>
```

## Options

### -d, --direct

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Specifies whether to wait for a direct connection before testing speed.

### --direction

|         |                       |
|---------|-----------------------|
| Type    | <code>up\|down</code> |
| Default | <code>down</code>     |

Specifies whether to run in reverse mode where the client receives and the server sends.

### -t, --time

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>5s</code>       |

Specifies the duration to monitor traffic.

### --pcap-file

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specifies a file to write a network capture to.

### -c, --column

|         |                                     |
|---------|-------------------------------------|
| Type    | <code>[Interval\|Throughput]</code> |
| Default | <code>Interval,Throughput</code>    |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# ssh

Source: https://coder.com/docs/reference/cli/ssh

<!-- DO NOT EDIT | GENERATED CONTENT -->
# ssh

Start a shell into a workspace or run a command

## Usage

```console
coder ssh [flags] <workspace> [command]
```

## Description

```console
This command does not have full parity with the standard SSH command. For users who need the full functionality of SSH, create an ssh configuration with `coder config-ssh`.

  - Use `--` to separate and pass flags directly to the command executed via SSH.:

     $ coder ssh <workspace> -- ls -la
```

## Options

### --stdio

|             |                               |
|-------------|-------------------------------|
| Type        | <code>bool</code>             |
| Environment | <code>$CODER_SSH_STDIO</code> |

Specifies whether to emit SSH output over stdin/stdout.

### -t, --tty

|             |                             |
|-------------|-----------------------------|
| Type        | <code>bool</code>           |
| Environment | <code>$CODER_SSH_TTY</code> |

Request a pseudo-terminal for the SSH session. Interactive shell sessions request one by default; command sessions do not unless this flag is set.

### --ssh-host-prefix

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_SSH_SSH_HOST_PREFIX</code> |

Strip this prefix from the provided hostname to determine the workspace name. This is useful when used as part of an OpenSSH proxy command.

### --hostname-suffix

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_SSH_HOSTNAME_SUFFIX</code> |

Strip this suffix from the provided hostname to determine the workspace name. This is useful when used as part of an OpenSSH proxy command. The suffix must be specified without a leading . character.

### -A, --forward-agent

|             |                                       |
|-------------|---------------------------------------|
| Type        | <code>bool</code>                     |
| Environment | <code>$CODER_SSH_FORWARD_AGENT</code> |

Specifies whether to forward the SSH agent specified in $SSH_AUTH_SOCK.

### -G, --forward-gpg

|             |                                     |
|-------------|-------------------------------------|
| Type        | <code>bool</code>                   |
| Environment | <code>$CODER_SSH_FORWARD_GPG</code> |

Specifies whether to forward the GPG agent. Unsupported on Windows workspaces, but supports all clients. Requires gnupg (gpg, gpgconf) on both the client and workspace. The GPG agent must already be running locally and will not be started for you. If a GPG agent is already running in the workspace, it will be attempted to be killed.

### --identity-agent

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_SSH_IDENTITY_AGENT</code> |

Specifies which identity agent to use (overrides $SSH_AUTH_SOCK), forward agent must also be enabled.

### --workspace-poll-interval

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>duration</code>                       |
| Environment | <code>$CODER_WORKSPACE_POLL_INTERVAL</code> |
| Default     | <code>1m</code>                             |

Specifies how often to poll for workspace automated shutdown.

### --wait

|             |                              |
|-------------|------------------------------|
| Type        | <code>yes\|no\|auto</code>   |
| Environment | <code>$CODER_SSH_WAIT</code> |
| Default     | <code>auto</code>            |

Specifies whether or not to wait for the startup script to finish executing. Auto means that the agent startup script behavior configured in the workspace template is used.

### --no-wait

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>bool</code>               |
| Environment | <code>$CODER_SSH_NO_WAIT</code> |

Enter workspace immediately after the agent has connected. This is the default if the template has configured the agent startup script behavior as non-blocking.

### -l, --log-dir

|             |                                 |
|-------------|---------------------------------|
| Type        | <code>string</code>             |
| Environment | <code>$CODER_SSH_LOG_DIR</code> |

Specify the directory containing SSH diagnostic log files.

### -R, --remote-forward

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string-array</code>              |
| Environment | <code>$CODER_SSH_REMOTE_FORWARD</code> |

Enable remote port forwarding (remote_port:local_address:local_port).

### -e, --env

|             |                             |
|-------------|-----------------------------|
| Type        | <code>string-array</code>   |
| Environment | <code>$CODER_SSH_ENV</code> |

Set environment variable(s) for session (key1=value1,key2=value2,...).

### --network-info-dir

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specifies a directory to write network information periodically.

### --network-info-interval

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>5s</code>       |

Specifies the interval to update network information.

### --disable-autostart

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>bool</code>                         |
| Environment | <code>$CODER_SSH_DISABLE_AUTOSTART</code> |
| Default     | <code>false</code>                        |

Disable starting the workspace automatically when connecting via SSH.

---

# start

Source: https://coder.com/docs/reference/cli/start

<!-- DO NOT EDIT | GENERATED CONTENT -->
# start

Start a workspace

## Usage

```console
coder start [flags] <workspace>
```

## Options

### --no-wait

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Return immediately after starting the workspace.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --build-option

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string-array</code>        |
| Environment | <code>$CODER_BUILD_OPTION</code> |

Build option value in the format "name=value".

### --build-options

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Prompt for one-time build options defined with ephemeral parameters.

### --ephemeral-parameter

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string-array</code>               |
| Environment | <code>$CODER_EPHEMERAL_PARAMETER</code> |

Set the value of ephemeral parameters defined in the template. The format is "name=value".

### --prompt-ephemeral-parameters

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_PROMPT_EPHEMERAL_PARAMETERS</code> |

Prompt to set values of ephemeral parameters defined in the template. If a value has been set via --ephemeral-parameter, it will not be prompted for.

### --parameter

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string-array</code>          |
| Environment | <code>$CODER_RICH_PARAMETER</code> |

Rich parameter value in the format "name=value".

### --rich-parameter-file

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_RICH_PARAMETER_FILE</code> |

Specify a file path with values for rich parameters defined in the template. The file should be in YAML format, containing key-value pairs for the parameters.

### --parameter-default

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string-array</code>                  |
| Environment | <code>$CODER_RICH_PARAMETER_DEFAULT</code> |

Rich parameter default values in the format "name=value".

### --use-parameter-defaults

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_WORKSPACE_USE_PARAMETER_DEFAULTS</code> |

Automatically accept parameter defaults when no value is provided.

### --always-prompt

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Always prompt all parameters. Does not pull parameter values from existing workspace.

---

# stat

Source: https://coder.com/docs/reference/cli/stat

<!-- DO NOT EDIT | GENERATED CONTENT -->
# stat

Show resource usage for the current workspace.

## Usage

```console
coder stat [flags]
```

## Subcommands

| Name                                | Purpose                          |
|-------------------------------------|----------------------------------|
| [<code>cpu</code>](./stat_cpu.md)   | Show CPU usage, in cores.        |
| [<code>mem</code>](./stat_mem.md)   | Show memory usage, in gigabytes. |
| [<code>disk</code>](./stat_disk.md) | Show disk usage, in gigabytes.   |

## Options

### -c, --column

|         |                                                                                  |
|---------|----------------------------------------------------------------------------------|
| Type    | <code>[host cpu\|host memory\|home disk\|container cpu\|container memory]</code> |
| Default | <code>host cpu,host memory,home disk,container cpu,container memory</code>       |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# stat cpu

Source: https://coder.com/docs/reference/cli/stat_cpu

<!-- DO NOT EDIT | GENERATED CONTENT -->
# stat cpu

Show CPU usage, in cores.

## Usage

```console
coder stat cpu [flags]
```

## Options

### --host

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Force host CPU measurement.

### -o, --output

|         |                         |
|---------|-------------------------|
| Type    | <code>text\|json</code> |
| Default | <code>text</code>       |

Output format.

---

# stat disk

Source: https://coder.com/docs/reference/cli/stat_disk

<!-- DO NOT EDIT | GENERATED CONTENT -->
# stat disk

Show disk usage, in gigabytes.

## Usage

```console
coder stat disk [flags]
```

## Options

### --path

|         |                     |
|---------|---------------------|
| Type    | <code>string</code> |
| Default | <code>/</code>      |

Path for which to check disk usage.

### --prefix

|         |                             |
|---------|-----------------------------|
| Type    | <code>Ki\|Mi\|Gi\|Ti</code> |
| Default | <code>Gi</code>             |

SI Prefix for disk measurement.

### -o, --output

|         |                         |
|---------|-------------------------|
| Type    | <code>text\|json</code> |
| Default | <code>text</code>       |

Output format.

---

# stat mem

Source: https://coder.com/docs/reference/cli/stat_mem

<!-- DO NOT EDIT | GENERATED CONTENT -->
# stat mem

Show memory usage, in gigabytes.

## Usage

```console
coder stat mem [flags]
```

## Options

### --host

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Force host memory measurement.

### --prefix

|         |                             |
|---------|-----------------------------|
| Type    | <code>Ki\|Mi\|Gi\|Ti</code> |
| Default | <code>Gi</code>             |

SI Prefix for memory measurement.

### -o, --output

|         |                         |
|---------|-------------------------|
| Type    | <code>text\|json</code> |
| Default | <code>text</code>       |

Output format.

---

# state

Source: https://coder.com/docs/reference/cli/state

<!-- DO NOT EDIT | GENERATED CONTENT -->
# state

Manually manage Terraform state to fix broken workspaces

## Usage

```console
coder state
```

## Subcommands

| Name                                 | Purpose                                       |
|--------------------------------------|-----------------------------------------------|
| [<code>pull</code>](./state_pull.md) | Pull a Terraform state file from a workspace. |
| [<code>push</code>](./state_push.md) | Push a Terraform state file to a workspace.   |

---

# state pull

Source: https://coder.com/docs/reference/cli/state_pull

<!-- DO NOT EDIT | GENERATED CONTENT -->
# state pull

Pull a Terraform state file from a workspace.

## Usage

```console
coder state pull [flags] <workspace> [file]
```

## Options

### -b, --build

|      |                  |
|------|------------------|
| Type | <code>int</code> |

Specify a workspace build to target by name. Defaults to latest.

---

# state push

Source: https://coder.com/docs/reference/cli/state_push

<!-- DO NOT EDIT | GENERATED CONTENT -->
# state push

Push a Terraform state file to a workspace.

## Usage

```console
coder state push [flags] <workspace> <file>
```

## Options

### -b, --build

|      |                  |
|------|------------------|
| Type | <code>int</code> |

Specify a workspace build to target by name. Defaults to latest.

### -n, --no-build

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Update the state without triggering a workspace build. Useful for state-only migrations.

---

# stop

Source: https://coder.com/docs/reference/cli/stop

<!-- DO NOT EDIT | GENERATED CONTENT -->
# stop

Stop a workspace

## Usage

```console
coder stop [flags] <workspace>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# support

Source: https://coder.com/docs/reference/cli/support

<!-- DO NOT EDIT | GENERATED CONTENT -->
# support

Commands for troubleshooting issues with a Coder deployment.

## Usage

```console
coder support
```

## Subcommands

| Name                                       | Purpose                                                                     |
|--------------------------------------------|-----------------------------------------------------------------------------|
| [<code>bundle</code>](./support_bundle.md) | Generate a support bundle to troubleshoot issues connecting to a workspace. |

---

# support bundle

Source: https://coder.com/docs/reference/cli/support_bundle

<!-- DO NOT EDIT | GENERATED CONTENT -->
# support bundle

Generate a support bundle to troubleshoot issues connecting to a workspace.

## Usage

```console
coder support bundle [flags] [<workspace>] [<agent>]
```

## Description

```console
This command generates a file containing detailed troubleshooting information about the Coder deployment and workspace connections. You may specify a single workspace (and optionally an agent name). When run inside a workspace, the workspace and agent are inferred from the environment if not provided.
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --output-file

|             |                                                |
|-------------|------------------------------------------------|
| Type        | <code>string</code>                            |
| Environment | <code>$CODER_SUPPORT_BUNDLE_OUTPUT_FILE</code> |

File path for writing the generated support bundle. Defaults to coder-support-$(date +%s).zip.

### --url-override

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>string</code>                             |
| Environment | <code>$CODER_SUPPORT_BUNDLE_URL_OVERRIDE</code> |

Override the URL to your Coder deployment. This may be useful, for example, if you need to troubleshoot a specific Coder replica.

### --workspaces-total-cap

|             |                                                         |
|-------------|---------------------------------------------------------|
| Type        | <code>int</code>                                        |
| Environment | <code>$CODER_SUPPORT_BUNDLE_WORKSPACES_TOTAL_CAP</code> |

Maximum number of workspaces to include in the support bundle. Set to 0 or negative value to disable the cap. Defaults to 10.

### --template

|             |                                             |
|-------------|---------------------------------------------|
| Type        | <code>string</code>                         |
| Environment | <code>$CODER_SUPPORT_BUNDLE_TEMPLATE</code> |

Template name to include in the support bundle. Use org_name/template_name if template name is reused across multiple organizations.

### --pprof

|             |                                          |
|-------------|------------------------------------------|
| Type        | <code>bool</code>                        |
| Environment | <code>$CODER_SUPPORT_BUNDLE_PPROF</code> |

Collect pprof profiling data from the Coder server and agent. Requires Coder server version 2.28.0 or newer.

---

# task

Source: https://coder.com/docs/reference/cli/task

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task

Manage tasks

Aliases:

* tasks

## Usage

```console
coder task
```

## Subcommands

| Name                                    | Purpose                    |
|-----------------------------------------|----------------------------|
| [<code>create</code>](./task_create.md) | Create a task              |
| [<code>delete</code>](./task_delete.md) | Delete tasks               |
| [<code>list</code>](./task_list.md)     | List tasks                 |
| [<code>logs</code>](./task_logs.md)     | Show a task's logs         |
| [<code>pause</code>](./task_pause.md)   | Pause a task               |
| [<code>resume</code>](./task_resume.md) | Resume a task              |
| [<code>send</code>](./task_send.md)     | Send input to a task       |
| [<code>status</code>](./task_status.md) | Show the status of a task. |

---

# task create

Source: https://coder.com/docs/reference/cli/task_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task create

Create a task

## Usage

```console
coder task create [flags] [input]
```

## Description

```console
  - Create a task with direct input:

     $ coder task create "Add authentication to the user service"

  - Create a task with stdin input:

     $ echo "Add authentication to the user service" | coder task create

  - Create a task with a specific name:

     $ coder task create --name task1 "Add authentication to the user service"

  - Create a task from a specific template / preset:

     $ coder task create --template backend-dev --preset "My Preset" "Add authentication to the user service"

  - Create a task for another user (requires appropriate permissions):

     $ coder task create --owner user@example.com "Add authentication to the user service"
```

## Options

### --name

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specify the name of the task. If you do not specify one, a name will be generated for you.

### --owner

|         |                     |
|---------|---------------------|
| Type    | <code>string</code> |
| Default | <code>me</code>     |

Specify the owner of the task. Defaults to the current user.

### --template

|             |                                        |
|-------------|----------------------------------------|
| Type        | <code>string</code>                    |
| Environment | <code>$CODER_TASK_TEMPLATE_NAME</code> |

### --template-version

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string</code>                       |
| Environment | <code>$CODER_TASK_TEMPLATE_VERSION</code> |

### --preset

|             |                                      |
|-------------|--------------------------------------|
| Type        | <code>string</code>                  |
| Environment | <code>$CODER_TASK_PRESET_NAME</code> |
| Default     | <code>none</code>                    |

### --stdin

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Reads from stdin for the task input.

### -q, --quiet

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Only display the created task's ID.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# task delete

Source: https://coder.com/docs/reference/cli/task_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task delete

Delete tasks

Aliases:

* rm

## Usage

```console
coder task delete [flags] <task> [<task> ...]
```

## Description

```console
  - Delete a single task.:

     $ $ coder task delete task1

  - Delete multiple tasks.:

     $ $ coder task delete task1 task2 task3

  - Delete a task without confirmation.:

     $ $ coder task delete task4 --yes
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# task list

Source: https://coder.com/docs/reference/cli/task_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task list

List tasks

Aliases:

* ls

## Usage

```console
coder task list [flags]
```

## Description

```console
  - List tasks for the current user.:

     $ coder task list

  - List tasks for a specific user.:

     $ coder task list --user someone-else

  - List all tasks you can view.:

     $ coder task list --all

  - List all your running tasks.:

     $ coder task list --status running

  - As above, but only show IDs.:

     $ coder task list --status running --quiet
```

## Options

### --status

|      |                                                                    |
|------|--------------------------------------------------------------------|
| Type | <code>pending\|initializing\|active\|paused\|error\|unknown</code> |

Filter by task status.

### -a, --all

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

List tasks for all users you can view.

### --user

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

List tasks for the specified user (username, "me").

### -q, --quiet

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Only display task IDs.

### -c, --column

|         |                                                                                                                                                                                                                                                                                                                                                                                                                                       |
|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[id\|organization id\|owner id\|owner name\|owner avatar url\|name\|display name\|template id\|template version id\|template name\|template display name\|template icon\|workspace id\|workspace name\|workspace status\|workspace build number\|workspace agent id\|workspace agent lifecycle\|workspace agent health\|workspace app id\|initial prompt\|status\|state\|message\|created at\|updated at\|state changed]</code> |
| Default | <code>name,status,state,state changed,message</code>                                                                                                                                                                                                                                                                                                                                                                                  |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# task logs

Source: https://coder.com/docs/reference/cli/task_logs

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task logs

Show a task's logs

## Usage

```console
coder task logs [flags] <task>
```

## Description

```console
  - Show logs for a given task.:

     $ coder task logs task1
```

## Options

### -c, --column

|         |                                        |
|---------|----------------------------------------|
| Type    | <code>[id\|content\|type\|time]</code> |
| Default | <code>type,content</code>              |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# task pause

Source: https://coder.com/docs/reference/cli/task_pause

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task pause

Pause a task

## Usage

```console
coder task pause [flags] <task>
```

## Description

```console
  - Pause a task by name:

     $ coder task pause my-task

  - Pause another user's task:

     $ coder task pause alice/my-task

  - Pause a task without confirmation:

     $ coder task pause my-task --yes
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# task resume

Source: https://coder.com/docs/reference/cli/task_resume

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task resume

Resume a task

## Usage

```console
coder task resume [flags] <task>
```

## Description

```console
  - Resume a task by name:

     $ coder task resume my-task

  - Resume another user's task:

     $ coder task resume alice/my-task

  - Resume a task without confirmation:

     $ coder task resume my-task --yes
```

## Options

### --no-wait

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Return immediately after resuming the task.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

---

# task send

Source: https://coder.com/docs/reference/cli/task_send

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task send

Send input to a task

## Usage

```console
coder task send [flags] <task> [<input> | --stdin]
```

## Description

```console
Send input to a task. If the task is paused, it will be automatically resumed before input is sent. If the task is initializing, it will wait for the task to become ready.
  - Send direct input to a task:

     $ coder task send task1 "Please also add unit tests"

  - Send input from stdin to a task:

     $ echo "Please also add unit tests" | coder task send task1 --stdin
```

## Options

### --stdin

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Reads the input from stdin.

---

# task status

Source: https://coder.com/docs/reference/cli/task_status

<!-- DO NOT EDIT | GENERATED CONTENT -->
# task status

Show the status of a task.

Aliases:

* stat

## Usage

```console
coder task status [flags]
```

## Description

```console
  - Show the status of a given task.:

     $ coder task status task1

  - Watch the status of a given task until it completes (idle or stopped).:

     $ coder task status task1 --watch
```

## Options

### --watch

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Watch the task status output. This will stream updates to the terminal until the underlying workspace is stopped.

### -c, --column

|         |                                                                                                                                                                                                                                                                                                                                                                                                                                                |
|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[id\|organization id\|owner id\|owner name\|owner avatar url\|name\|display name\|template id\|template version id\|template name\|template display name\|template icon\|workspace id\|workspace name\|workspace status\|workspace build number\|workspace agent id\|workspace agent lifecycle\|workspace agent health\|workspace app id\|initial prompt\|status\|state\|message\|created at\|updated at\|state changed\|healthy]</code> |
| Default | <code>state changed,status,healthy,state,message</code>                                                                                                                                                                                                                                                                                                                                                                                        |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# templates

Source: https://coder.com/docs/reference/cli/templates

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates

Manage templates

Aliases:

* template

## Usage

```console
coder templates
```

## Description

```console
Templates are written in standard Terraform and describe the infrastructure for workspaces
  - Create or push an update to the template. Your developers can update their
workspaces:

     $ coder templates push my-template
```

## Subcommands

| Name                                             | Purpose                                                                          |
|--------------------------------------------------|----------------------------------------------------------------------------------|
| [<code>create</code>](./templates_create.md)     | DEPRECATED: Create a template from the current directory or as specified by flag |
| [<code>edit</code>](./templates_edit.md)         | Edit the metadata of a template by name.                                         |
| [<code>init</code>](./templates_init.md)         | Get started with a templated template.                                           |
| [<code>list</code>](./templates_list.md)         | List all the templates available for the organization                            |
| [<code>push</code>](./templates_push.md)         | Create or update a template from the current directory or as specified by flag   |
| [<code>versions</code>](./templates_versions.md) | Manage different versions of the specified template                              |
| [<code>presets</code>](./templates_presets.md)   | Manage presets of the specified template                                         |
| [<code>delete</code>](./templates_delete.md)     | Delete templates                                                                 |
| [<code>pull</code>](./templates_pull.md)         | Download the active, latest, or specified version of a template to a path.       |
| [<code>archive</code>](./templates_archive.md)   | Archive unused or failed template versions from a given template(s)              |

---

# templates archive

Source: https://coder.com/docs/reference/cli/templates_archive

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates archive

Archive unused or failed template versions from a given template(s)

## Usage

```console
coder templates archive [flags] [template-name...] 
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --all

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Include all unused template versions. By default, only failed template versions are archived.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# templates create

Source: https://coder.com/docs/reference/cli/templates_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates create

DEPRECATED: Create a template from the current directory or as specified by flag

## Usage

```console
coder templates create [flags] [name]
```

## Options

### --private

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Disable the default behavior of granting template access to the 'everyone' group. The template permissions must be updated to allow non-admin users to use this template.

### --variables-file

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specify a file path with values for Terraform-managed variables.

### --variable

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Specify a set of values for Terraform-managed variables.

### --var

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Alias of --variable.

### --provisioner-tag

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Specify a set of tags to target provisioner daemons.

### --default-ttl

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>24h</code>      |

Specify a default TTL for workspaces created from this template. It is the default time before shutdown - workspaces created from this template default to this value. Maps to "Default autostop" in the UI.

### --failure-ttl

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>0h</code>       |

Specify a failure TTL for workspaces created from this template. It is the amount of time after a failed "start" build before coder automatically schedules a "stop" build to cleanup.This licensed feature's default is 0h (off). Maps to "Failure cleanup"in the UI.

### --dormancy-threshold

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>0h</code>       |

Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to "Dormancy threshold" in the UI.

### --dormancy-auto-deletion

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>0h</code>       |

Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to "Dormancy Auto-Deletion" in the UI.

### --require-active-version

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Requires workspace builds to use the active template version. This setting does not apply to template admins. This is an enterprise-only feature. See https://coder.com/docs/admin/templates/managing-templates#require-automatic-updates-enterprise for more details.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

### -d, --directory

|         |                     |
|---------|---------------------|
| Type    | <code>string</code> |
| Default | <code>.</code>      |

Specify the directory to create from, use '-' to read tar from stdin.

### --ignore-lockfile

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Ignore warnings about not having a .terraform.lock.hcl file present in the template.

### -m, --message

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specify a message describing the changes in this version of the template. Messages longer than 72 characters will be displayed as truncated.

---

# templates delete

Source: https://coder.com/docs/reference/cli/templates_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates delete

Delete templates

Aliases:

* rm

## Usage

```console
coder templates delete [flags] [name...]
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# templates edit

Source: https://coder.com/docs/reference/cli/templates_edit

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates edit

Edit the metadata of a template by name.

## Usage

```console
coder templates edit [flags] <template>
```

## Options

### --name

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Edit the template name.

### --display-name

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Edit the template display name.

### --description

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Edit the template description.

### --deprecated

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Sets the template as deprecated. Must be a message explaining why the template is deprecated.

### --icon

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Edit the template icon path.

### --default-ttl

|      |                       |
|------|-----------------------|
| Type | <code>duration</code> |

Edit the template default time before shutdown - workspaces created from this template default to this value. Maps to "Default autostop" in the UI.

### --activity-bump

|      |                       |
|------|-----------------------|
| Type | <code>duration</code> |

Edit the template activity bump - workspaces created from this template will have their shutdown time bumped by this value when activity is detected. Maps to "Activity bump" in the UI.

### --autostart-requirement-weekdays

|      |                                                                                    |
|------|------------------------------------------------------------------------------------|
| Type | <code>[monday\|tuesday\|wednesday\|thursday\|friday\|saturday\|sunday\|all]</code> |

Edit the template autostart requirement weekdays - workspaces created from this template can only autostart on the given weekdays. To unset this value for the template (and allow autostart on all days), pass 'all'.

### --autostop-requirement-weekdays

|      |                                                                                     |
|------|-------------------------------------------------------------------------------------|
| Type | <code>[monday\|tuesday\|wednesday\|thursday\|friday\|saturday\|sunday\|none]</code> |

Edit the template autostop requirement weekdays - workspaces created from this template must be restarted on the given weekdays. To unset this value for the template (and disable the autostop requirement for the template), pass 'none'.

### --autostop-requirement-weeks

|      |                  |
|------|------------------|
| Type | <code>int</code> |

Edit the template autostop requirement weeks - workspaces created from this template must be restarted on an n-weekly basis.

### --failure-ttl

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>0h</code>       |

Specify a failure TTL for workspaces created from this template. It is the amount of time after a failed "start" build before coder automatically schedules a "stop" build to cleanup.This licensed feature's default is 0h (off). Maps to "Failure cleanup" in the UI.

### --dormancy-threshold

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>0h</code>       |

Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to "Dormancy threshold" in the UI.

### --dormancy-auto-deletion

|         |                       |
|---------|-----------------------|
| Type    | <code>duration</code> |
| Default | <code>0h</code>       |

Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to "Dormancy Auto-Deletion" in the UI.

### --allow-user-cancel-workspace-jobs

|         |                   |
|---------|-------------------|
| Type    | <code>bool</code> |
| Default | <code>true</code> |

Allow users to cancel in-progress workspace jobs.

### --allow-user-autostart

|         |                   |
|---------|-------------------|
| Type    | <code>bool</code> |
| Default | <code>true</code> |

Allow users to configure autostart for workspaces on this template. This can only be disabled in enterprise.

### --allow-user-autostop

|         |                   |
|---------|-------------------|
| Type    | <code>bool</code> |
| Default | <code>true</code> |

Allow users to customize the autostop TTL for workspaces on this template. This can only be disabled in enterprise.

### --require-active-version

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Requires workspace builds to use the active template version. This setting does not apply to template admins. This is an enterprise-only feature. See https://coder.com/docs/admin/templates/managing-templates#require-automatic-updates-enterprise for more details.

### --private

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Disable the default behavior of granting template access to the 'everyone' group. The template permissions must be updated to allow non-admin users to use this template.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# templates init

Source: https://coder.com/docs/reference/cli/templates_init

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates init

Get started with a templated template.

## Usage

```console
coder templates init [flags] [directory]
```

## Options

### --id

|      |                                                                                                                                                                                                                                                                                                 |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type | <code>aws-devcontainer\|aws-linux\|aws-windows\|azure-linux\|digitalocean-linux\|docker\|docker-devcontainer\|docker-envbuilder\|gcp-devcontainer\|gcp-linux\|gcp-vm-container\|gcp-windows\|incus\|kubernetes\|kubernetes-devcontainer\|nomad-docker\|quickstart\|scratch\|tasks-docker</code> |

Specify a given example template by ID.

---

# templates list

Source: https://coder.com/docs/reference/cli/templates_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates list

List all the templates available for the organization

Aliases:

* ls

## Usage

```console
coder templates list [flags]
```

## Options

### -c, --column

|         |                                                                                                                                         |
|---------|-----------------------------------------------------------------------------------------------------------------------------------------|
| Type    | <code>[name\|created at\|last updated\|organization id\|organization name\|provisioner\|active version id\|used by\|default ttl]</code> |
| Default | <code>name,organization name,last updated,used by</code>                                                                                |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# templates presets

Source: https://coder.com/docs/reference/cli/templates_presets

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates presets

Manage presets of the specified template

Aliases:

* preset

## Usage

```console
coder templates presets
```

## Description

```console
  - List presets for the active version of a template:

     $ coder templates presets list my-template

  - List presets for a specific version of a template:

     $ coder templates presets list my-template --template-version my-template-version
```

## Subcommands

| Name                                             | Purpose                                                                              |
|--------------------------------------------------|--------------------------------------------------------------------------------------|
| [<code>list</code>](./templates_presets_list.md) | List all presets of the specified template. Defaults to the active template version. |

---

# templates presets list

Source: https://coder.com/docs/reference/cli/templates_presets_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates presets list

List all presets of the specified template. Defaults to the active template version.

## Usage

```console
coder templates presets list [flags] <template>
```

## Options

### --template-version

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specify a template version to list presets for. Defaults to the active version.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

### -c, --column

|         |                                                                                   |
|---------|-----------------------------------------------------------------------------------|
| Type    | <code>[name\|description\|parameters\|default\|desired prebuild instances]</code> |
| Default | <code>name,description,parameters,default,desired prebuild instances</code>       |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# templates pull

Source: https://coder.com/docs/reference/cli/templates_pull

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates pull

Download the active, latest, or specified version of a template to a path.

## Usage

```console
coder templates pull [flags] <name> [destination]
```

## Options

### --tar

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Output the template as a tar archive to stdout.

### --zip

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Output the template as a zip archive to stdout.

### --version

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

The name of the template version to pull. Use 'active' to pull the active version, 'latest' to pull the latest version, or the name of the template version to pull.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# templates push

Source: https://coder.com/docs/reference/cli/templates_push

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates push

Create or update a template from the current directory or as specified by flag

## Usage

```console
coder templates push [flags] [template]
```

## Options

### --variables-file

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specify a file path with values for Terraform-managed variables.

### --variable

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Specify a set of values for Terraform-managed variables.

### --var

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Alias of --variable.

### --provisioner-tag

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Specify a set of tags to target provisioner daemons. If you do not specify any tags, the tags from the active template version will be reused, if available. To remove existing tags, use --provisioner-tag="-".

### --name

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specify a name for the new template version. It will be automatically generated if not provided.

### --always-prompt

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Always prompt all parameters. Does not pull parameter values from active template version.

### --activate

|         |                   |
|---------|-------------------|
| Type    | <code>bool</code> |
| Default | <code>true</code> |

Whether the new template will be marked active.

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -d, --directory

|         |                     |
|---------|---------------------|
| Type    | <code>string</code> |
| Default | <code>.</code>      |

Specify the directory to create from, use '-' to read tar from stdin.

### --ignore-lockfile

|         |                    |
|---------|--------------------|
| Type    | <code>bool</code>  |
| Default | <code>false</code> |

Ignore warnings about not having a .terraform.lock.hcl file present in the template.

### -m, --message

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specify a message describing the changes in this version of the template. Messages longer than 72 characters will be displayed as truncated.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# templates versions

Source: https://coder.com/docs/reference/cli/templates_versions

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates versions

Manage different versions of the specified template

Aliases:

* version

## Usage

```console
coder templates versions
```

## Description

```console
  - List versions of a specific template:

     $ coder templates versions list my-template
```

## Subcommands

| Name                                                        | Purpose                                         |
|-------------------------------------------------------------|-------------------------------------------------|
| [<code>list</code>](./templates_versions_list.md)           | List all the versions of the specified template |
| [<code>archive</code>](./templates_versions_archive.md)     | Archive a template version(s).                  |
| [<code>unarchive</code>](./templates_versions_unarchive.md) | Unarchive a template version(s).                |
| [<code>promote</code>](./templates_versions_promote.md)     | Promote a template version to active.           |

---

# templates versions archive

Source: https://coder.com/docs/reference/cli/templates_versions_archive

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates versions archive

Archive a template version(s).

## Usage

```console
coder templates versions archive [flags] <template-name> [template-version-names...] 
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# templates versions list

Source: https://coder.com/docs/reference/cli/templates_versions_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates versions list

List all the versions of the specified template

## Usage

```console
coder templates versions list [flags] <template>
```

## Options

### --include-archived

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Include archived versions in the result list.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

### -c, --column

|         |                                                                           |
|---------|---------------------------------------------------------------------------|
| Type    | <code>[id\|name\|created at\|created by\|status\|active\|archived]</code> |
| Default | <code>name,created at,created by,status,active</code>                     |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# templates versions promote

Source: https://coder.com/docs/reference/cli/templates_versions_promote

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates versions promote

Promote a template version to active.

## Usage

```console
coder templates versions promote [flags] --template=<template_name> --template-version=<template_version_name>
```

## Description

```console
Promote an existing template version to be the active version for the specified template.
```

## Options

### -t, --template

|             |                                   |
|-------------|-----------------------------------|
| Type        | <code>string</code>               |
| Environment | <code>$CODER_TEMPLATE_NAME</code> |

Specify the template name.

### --template-version

|             |                                           |
|-------------|-------------------------------------------|
| Type        | <code>string</code>                       |
| Environment | <code>$CODER_TEMPLATE_VERSION_NAME</code> |

Specify the template version name to promote.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# templates versions unarchive

Source: https://coder.com/docs/reference/cli/templates_versions_unarchive

<!-- DO NOT EDIT | GENERATED CONTENT -->
# templates versions unarchive

Unarchive a template version(s).

## Usage

```console
coder templates versions unarchive [flags] <template-name> [template-version-names...] 
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# tokens

Source: https://coder.com/docs/reference/cli/tokens

<!-- DO NOT EDIT | GENERATED CONTENT -->
# tokens

Manage personal access tokens

Aliases:

* token

## Usage

```console
coder tokens
```

## Description

```console
Tokens are used to authenticate automated clients to Coder.
  - Create a token for automation:

     $ coder tokens create

  - List your tokens:

     $ coder tokens ls

  - Create a scoped token:

     $ coder tokens create --scope workspace:read --allow workspace:<uuid>

  - Remove a token by ID:

     $ coder tokens rm WuoWs4ZsMX
```

## Subcommands

| Name                                      | Purpose                                    |
|-------------------------------------------|--------------------------------------------|
| [<code>create</code>](./tokens_create.md) | Create a token                             |
| [<code>list</code>](./tokens_list.md)     | List tokens                                |
| [<code>view</code>](./tokens_view.md)     | Display detailed information about a token |
| [<code>remove</code>](./tokens_remove.md) | Expire or delete a token                   |

---

# tokens create

Source: https://coder.com/docs/reference/cli/tokens_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# tokens create

Create a token

## Usage

```console
coder tokens create [flags]
```

## Options

### --lifetime

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string</code>                |
| Environment | <code>$CODER_TOKEN_LIFETIME</code> |

Duration for the token lifetime. Supports standard Go duration units (ns, us, ms, s, m, h) plus d (days) and y (years). Examples: 8h, 30d, 1y, 1d12h30m.

### -n, --name

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_TOKEN_NAME</code> |

Specify a human-readable name.

### -u, --user

|             |                                |
|-------------|--------------------------------|
| Type        | <code>string</code>            |
| Environment | <code>$CODER_TOKEN_USER</code> |

Specify the user to create the token for (Only works if logged in user is admin).

### --scope

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

Repeatable scope to attach to the token (e.g. workspace:read).

### --allow

|      |                         |
|------|-------------------------|
| Type | <code>allow-list</code> |

Repeatable allow-list entry (<type>:<uuid>, e.g. workspace:1234-...).

---

# tokens list

Source: https://coder.com/docs/reference/cli/tokens_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# tokens list

List tokens

Aliases:

* ls

## Usage

```console
coder tokens list [flags]
```

## Options

### -a, --all

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Specifies whether all users' tokens will be listed or not (must have Owner role to see all tokens).

### --include-expired

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Include expired tokens in the output. By default, expired tokens are hidden.

### -c, --column

|         |                                                                                       |
|---------|---------------------------------------------------------------------------------------|
| Type    | <code>[id\|name\|scopes\|allow list\|last used\|expires at\|created at\|owner]</code> |
| Default | <code>id,name,scopes,allow list,last used,expires at,created at</code>                |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# tokens remove

Source: https://coder.com/docs/reference/cli/tokens_remove

<!-- DO NOT EDIT | GENERATED CONTENT -->
# tokens remove

Expire or delete a token

Aliases:

* delete
* rm

## Usage

```console
coder tokens remove [flags] <name|id|token>
```

## Description

```console
Remove a token by expiring it. Use --delete to permanently hard-delete the token instead.
```

## Options

### --delete

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Permanently delete the token instead of expiring it. This removes the audit trail.

---

# tokens view

Source: https://coder.com/docs/reference/cli/tokens_view

<!-- DO NOT EDIT | GENERATED CONTENT -->
# tokens view

Display detailed information about a token

## Usage

```console
coder tokens view [flags] <name|id>
```

## Options

### -c, --column

|         |                                                                                       |
|---------|---------------------------------------------------------------------------------------|
| Type    | <code>[id\|name\|scopes\|allow list\|last used\|expires at\|created at\|owner]</code> |
| Default | <code>id,name,scopes,allow list,last used,expires at,created at,owner</code>          |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# unfavorite

Source: https://coder.com/docs/reference/cli/unfavorite

<!-- DO NOT EDIT | GENERATED CONTENT -->
# unfavorite

Remove a workspace from your favorites

Aliases:

* unfav
* unfavourite

## Usage

```console
coder unfavorite <workspace>
```

---

# update

Source: https://coder.com/docs/reference/cli/update

<!-- DO NOT EDIT | GENERATED CONTENT -->
# update

Will update and start a given workspace if it is out of date. If the workspace is already running, it will be stopped first.

## Usage

```console
coder update [flags] <workspace>
```

## Description

```console
Use --always-prompt to change the parameter values of the workspace.
```

## Options

### --build-option

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string-array</code>        |
| Environment | <code>$CODER_BUILD_OPTION</code> |

Build option value in the format "name=value".

### --build-options

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Prompt for one-time build options defined with ephemeral parameters.

### --ephemeral-parameter

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string-array</code>               |
| Environment | <code>$CODER_EPHEMERAL_PARAMETER</code> |

Set the value of ephemeral parameters defined in the template. The format is "name=value".

### --prompt-ephemeral-parameters

|             |                                                 |
|-------------|-------------------------------------------------|
| Type        | <code>bool</code>                               |
| Environment | <code>$CODER_PROMPT_EPHEMERAL_PARAMETERS</code> |

Prompt to set values of ephemeral parameters defined in the template. If a value has been set via --ephemeral-parameter, it will not be prompted for.

### --parameter

|             |                                    |
|-------------|------------------------------------|
| Type        | <code>string-array</code>          |
| Environment | <code>$CODER_RICH_PARAMETER</code> |

Rich parameter value in the format "name=value".

### --rich-parameter-file

|             |                                         |
|-------------|-----------------------------------------|
| Type        | <code>string</code>                     |
| Environment | <code>$CODER_RICH_PARAMETER_FILE</code> |

Specify a file path with values for rich parameters defined in the template. The file should be in YAML format, containing key-value pairs for the parameters.

### --parameter-default

|             |                                            |
|-------------|--------------------------------------------|
| Type        | <code>string-array</code>                  |
| Environment | <code>$CODER_RICH_PARAMETER_DEFAULT</code> |

Rich parameter default values in the format "name=value".

### --use-parameter-defaults

|             |                                                      |
|-------------|------------------------------------------------------|
| Type        | <code>bool</code>                                    |
| Environment | <code>$CODER_WORKSPACE_USE_PARAMETER_DEFAULTS</code> |

Automatically accept parameter defaults when no value is provided.

### --always-prompt

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Always prompt all parameters. Does not pull parameter values from existing workspace.

---

# users

Source: https://coder.com/docs/reference/cli/users

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users

Manage users

Aliases:

* user

## Usage

```console
coder users [subcommand]
```

## Subcommands

| Name                                               | Purpose                                                                               |
|----------------------------------------------------|---------------------------------------------------------------------------------------|
| [<code>create</code>](./users_create.md)           | Create a new user.                                                                    |
| [<code>list</code>](./users_list.md)               | Prints the list of users.                                                             |
| [<code>show</code>](./users_show.md)               | Show a single user. Use 'me' to indicate the currently authenticated user.            |
| [<code>delete</code>](./users_delete.md)           | Delete a user by username or user_id.                                                 |
| [<code>edit-roles</code>](./users_edit-roles.md)   | Edit a user's roles by username or id                                                 |
| [<code>oidc-claims</code>](./users_oidc-claims.md) | Display the OIDC claims for the authenticated user.                                   |
| [<code>activate</code>](./users_activate.md)       | Update a user's status to 'active'. Active users can fully interact with the platform |
| [<code>suspend</code>](./users_suspend.md)         | Update a user's status to 'suspended'. A suspended user cannot log into the platform  |

---

# users activate

Source: https://coder.com/docs/reference/cli/users_activate

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users activate

Update a user's status to 'active'. Active users can fully interact with the platform

Aliases:

* active

## Usage

```console
coder users activate [flags] <username|user_id>
```

## Description

```console
 coder users activate example_user
```

## Options

### -c, --column

|         |                                                    |
|---------|----------------------------------------------------|
| Type    | <code>[username\|email\|created at\|status]</code> |
| Default | <code>username,email,created at,status</code>      |

Specify a column to filter in the table.

---

# users create

Source: https://coder.com/docs/reference/cli/users_create

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users create

Create a new user.

## Usage

```console
coder users create [flags]
```

## Options

### -e, --email

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specifies an email address for the new user.

### -u, --username

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specifies a username for the new user.

### -n, --full-name

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specifies an optional human-readable name for the new user.

### -p, --password

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Specifies a password for the new user.

### --login-type

|      |                     |
|------|---------------------|
| Type | <code>string</code> |

Optionally specify the login type for the user. Valid values are: password, none, github, oidc. Using 'none' prevents the user from authenticating and requires an API key/token to be generated by an admin. Deprecated: 'none' is deprecated. Use service accounts (requires Premium) for machine-to-machine access, or password/github/oidc login types for regular user accounts.

### --service-account

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Create a user account intended to be used by a service or as an intermediary rather than by a human.

### -O, --org

|             |                                  |
|-------------|----------------------------------|
| Type        | <code>string</code>              |
| Environment | <code>$CODER_ORGANIZATION</code> |

Select which organization (uuid or name) to use.

---

# users delete

Source: https://coder.com/docs/reference/cli/users_delete

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users delete

Delete a user by username or user_id.

Aliases:

* rm

## Usage

```console
coder users delete <username|user_id>
```

---

# users edit-roles

Source: https://coder.com/docs/reference/cli/users_edit-roles

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users edit-roles

Edit a user's roles by username or id

## Usage

```console
coder users edit-roles [flags] <username|user_id>
```

## Options

### -y, --yes

|      |                   |
|------|-------------------|
| Type | <code>bool</code> |

Bypass confirmation prompts.

### --roles

|      |                           |
|------|---------------------------|
| Type | <code>string-array</code> |

A list of roles to give to the user. This removes any existing roles the user may have.

---

# users list

Source: https://coder.com/docs/reference/cli/users_list

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users list

Prints the list of users.

Aliases:

* ls

## Usage

```console
coder users list [flags]
```

## Options

### --github-user-id

|      |                  |
|------|------------------|
| Type | <code>int</code> |

Filter users by their GitHub user ID.

### -c, --column

|         |                                                                          |
|---------|--------------------------------------------------------------------------|
| Type    | <code>[id\|username\|name\|email\|created at\|updated at\|status]</code> |
| Default | <code>username,email,created at,status</code>                            |

Columns to display in table output.

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# users show

Source: https://coder.com/docs/reference/cli/users_show

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users show

Show a single user. Use 'me' to indicate the currently authenticated user.

## Usage

```console
coder users show [flags] <username|user_id|'me'>
```

## Description

```console
 coder users show me
```

## Options

### -o, --output

|         |                          |
|---------|--------------------------|
| Type    | <code>table\|json</code> |
| Default | <code>table</code>       |

Output format.

---

# users suspend

Source: https://coder.com/docs/reference/cli/users_suspend

<!-- DO NOT EDIT | GENERATED CONTENT -->
# users suspend

Update a user's status to 'suspended'. A suspended user cannot log into the platform

## Usage

```console
coder users suspend [flags] <username|user_id>
```

## Description

```console
 coder users suspend example_user
```

## Options

### -c, --column

|         |                                                    |
|---------|----------------------------------------------------|
| Type    | <code>[username\|email\|created at\|status]</code> |
| Default | <code>username,email,created at,status</code>      |

Specify a column to filter in the table.

---

# version

Source: https://coder.com/docs/reference/cli/version

<!-- DO NOT EDIT | GENERATED CONTENT -->
# version

Show coder version

## Usage

```console
coder version [flags]
```

## Options

### -o, --output

|         |                         |
|---------|-------------------------|
| Type    | <code>text\|json</code> |
| Default | <code>text</code>       |

Output format.

---

# whoami

Source: https://coder.com/docs/reference/cli/whoami

<!-- DO NOT EDIT | GENERATED CONTENT -->
# whoami

Fetch authenticated user info for Coder deployment

## Usage

```console
coder whoami [flags]
```

## Options

### -c, --column

|         |                                               |
|---------|-----------------------------------------------|
| Type    | <code>[URL\|Username\|ID\|Orgs\|Roles]</code> |
| Default | <code>url,username,id</code>                  |

Columns to display in table output.

### -o, --output

|         |                                |
|---------|--------------------------------|
| Type    | <code>text\|json\|table</code> |
| Default | <code>text</code>              |

Output format.

---

# Agent API

Source: https://coder.com/docs/reference/agent-api

# Sections

<children>
  This page is rendered on https://coder.com/docs/reference/agent-api. Refer to the other documents in the `agent-api/` directory.
</children>

---

# Debug

Source: https://coder.com/docs/reference/agent-api/debug

# Debug

## Get debug logs

### Code samples

```shell
curl $CODER_AGENT_DEBUG_ADDRESS/debug/logs
```

`GET /debug/logs`

Get the first 10MiB of data from `$CODER_AGENT_LOG_DIR/coder-agent.log`.

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

## Get debug info for magicsock

### Code samples

```shell
curl $CODER_AGENT_DEBUG_ADDRESS/debug/magicsock
```

`GET /debug/magicsock`

See
[Tailscale's documentation](https://pkg.go.dev/tailscale.com/wgengine/magicsock#Conn.ServeHTTPDebug).

## Toggle debug logging for magicsock

### Code samples

```shell
curl $CODER_AGENT_DEBUG_ADDRESS/debug/magicsock/debug-logging/true
```

`GET /debug/magicsock/debug-logging/{state}`

Set whether debug logging is enabled. See
[Tailscale's documentation](https://pkg.go.dev/tailscale.com/wgengine/magicsock#Conn.SetDebugLoggingEnabled)
for more information.

### Parameters

| Name    | In   | Type    | Required | Description         |
|---------|------|---------|----------|---------------------|
| `state` | path | boolean | true     | Debug logging state |

### Responses

| Status | Meaning                                                 | Description | Schema |
|--------|---------------------------------------------------------|-------------|--------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          |        |

## Get debug manifest

### Code samples

```shell
curl $CODER_AGENT_DEBUG_ADDRESS/debug/manifest
```

`GET /debug/manifest`

Get the manifest the agent fetched from `coderd` upon startup.

### Responses

| Status | Meaning                                                 | Description | Schema                                             |
|--------|---------------------------------------------------------|-------------|----------------------------------------------------|
| 200    | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK          | [agentsdk.Manifest](./schemas.md#agentsdkmanifest) |

---

# Schemas

Source: https://coder.com/docs/reference/agent-api/schemas

# Schemas

## agentsdk.Manifest

```json
{
    "agent_id": "151321db-0713-473c-ab42-2cc6ddeab1a4",
    "agent_name": "string",
    "owner_name": "string",
    "workspace_id": "8ef13a0d-a5c9-4fb4-abf2-f8f65c3830fb",
    "workspace_name": "string",
    "git_auth_configs": 1,
    "vscode_port_proxy_uri": "string",
    "apps": [
        {
            "id": "c488c933-688a-444e-a55d-f1e88ecc78f5",
            "url": "string",
            "external": false,
            "slug": "string",
            "display_name": "string",
            "icon": "string",
            "subdomain": false,
            "sharing_level": "owner",
            "healthcheck": {
                "url": "string",
                "interval": 5,
                "threshold": 6
            },
            "health": "initializing"
        }
    ],
    "derpmap": {
        "HomeParams": {},
        "Regions": {
            "1000": {
                "EmbeddedRelay": false,
                "RegionID": 1000,
                "RegionCode": "string",
                "RegionName": "string",
                "Nodes": [
                    {
                        "Name": "string",
                        "RegionID": 1000,
                        "HostName": "string",
                        "STUNPort": 19302,
                        "STUNOnly": true
                    }
                ]
            }
        }
    },
    "derp_force_websockets": false,
    "environment_variables": {
        "OIDC_TOKEN": "string"
    },
    "directory": "string",
    "motd_file": "string",
    "disable_direct_connections": false,
    "metadata": [
        {
            "display_name": "string",
            "key": "string",
            "script": "string",
            "interval": 10,
            "timeout": 1
        }
    ],
    "scripts": [
        {
            "log_source_id": "3e79c8da-08ae-48f4-b73e-11e194cdea06",
            "log_path": "string",
            "script": "string",
            "cron": "string",
            "run_on_start": true,
            "run_on_stop": false,
            "start_blocks_login": true,
            "timeout": 0
        }
    ]
}
```

### Properties

| Name                         | Type                                                                                              | Required | Restrictions | Description |
|------------------------------|---------------------------------------------------------------------------------------------------|----------|--------------|-------------|
| `agent_id`                   | string                                                                                            | true     |              |             |
| `agent_name`                 | string                                                                                            | true     |              |             |
| `owner_name`                 | string                                                                                            | true     |              |             |
| `workspace_id`               | string                                                                                            | true     |              |             |
| `workspace_name`             | string                                                                                            | true     |              |             |
| `git_auth_configs`           | int                                                                                               | true     |              |             |
| `vscode_port_proxy_uri`      | string                                                                                            | true     |              |             |
| `apps`                       | array of [codersdk.WorkspaceApp](../api/schemas.md#codersdkworkspaceapp)                          | true     |              |             |
| `derpmap`                    | [tailcfg.DERPMap](../api/schemas.md#tailcfgderpmap)                                               | true     |              |             |
| `derp_force_websockets`      | boolean                                                                                           | true     |              |             |
| `environment_variables`      | object                                                                                            | true     |              |             |
| `directory`                  | string                                                                                            | true     |              |             |
| `motd_file`                  | string                                                                                            | true     |              |             |
| `disable_direct_connections` | boolean                                                                                           | true     |              |             |
| `metadata`                   | array of [codersdk.WorkspaceAgentMetadataDescription](#codersdkworkspaceagentmetadatadescription) | true     |              |             |
| `scripts`                    | array of [codersdk.WorkspaceAgentScript](../api/schemas.md#codersdkworkspaceagentscript)          | true     |              |             |

## codersdk.WorkspaceAgentMetadataDescription

```json
{
    "display_name": "string",
    "key": "string",
    "script": "string",
    "interval": 10,
    "timeout": 1
}
```

### Properties

| Name           | Type    | Required | Restrictions | Description |
|----------------|---------|----------|--------------|-------------|
| `display_name` | string  | true     |              |             |
| `key`          | string  | true     |              |             |
| `script`       | string  | true     |              |             |
| `interval`     | integer | true     |              |             |
| `timeout`      | integer | true     |              |             |

---

