- Terraform Enterprise
- 2.1.x (latest)
- 2.0.x
- 1.2.x
- 1.1.x
- 1.0.x
- v202507-1
- v202506-1
- v202505-1
- v202504-1
- v202503-1
- v202502-2
- v202502-1
- v202501-1
- v202411-2
- v202411-1
- v202410-1
- v202409-3
- v202409-2
- v202409-1
- v202408-1
- No versions of this document exist before v202408-1. Click below to redirect to the version homepage.
- v202407-1
- v202406-1
- v202405-1
- v202404-2
- v202404-1
- v202402-2
- v202402-1
- v202401-2
- v202401-1
- v202312-1
- v202311-1
- v202310-1
- v202309-1
- v202308-1
- v202307-1
- v202306-1
- v202305-2
- v202305-1
- v202304-1
- v202303-1
- v202302-1
- v202301-2
- v202301-1
- v202212-2
- v202212-1
- v202211-1
- v202210-1
- v202209-2
- v202209-1
- v202208-3
- v202208-2
- v202208-1
- v202207-2
- v202207-1
- v202206-1
Node drain status API reference
The node drain status endpoints report whether a Terraform Enterprise node is actively running Terraform tasks and whether it is safe to terminate.
Node status values
Endpoints report one of the following status values for each node.
| Status | Description |
|---|---|
ok | The node is healthy and accepting work. No drain has been initiated. |
draining | A drain has been initiated and the node is still running one or more tasks. The node is not safe to terminate. |
standby | The node has finished draining and is no longer running tasks. The node is safe to terminate. |
error | The drain status could not be determined for this node. active_tasks_count is null and active_tasks is an empty array. |
Get local node drain status
This endpoint returns the drain status of the individual node that receives the request. Because this endpoint targets the local node, send the request directly to that node instead of through a load balancer. Authentication is required to use this endpoint.
GET /api/v1/nodes/self/drain-status
Sample request
curl \
--header "Authorization: Bearer $TOKEN" \
--request GET \
"https://tfe.example.com:8443/api/v1/nodes/self/drain-status"
Sample response
The following response shows a node that has finished draining and is safe to terminate. Because the drain is complete, status is standby, is_safe_to_terminate is true, active_tasks is empty, both drain_started_at and force_terminate_at are populated, and force_terminate_at is exactly drain_started_at plus 24 hours.
{
"hostname": "tfe-1",
"status": "standby",
"is_safe_to_terminate": true,
"active_tasks_count": 0,
"active_tasks": [],
"drain_started_at": "2026-06-09T14:32:00Z",
"force_terminate_at": "2026-06-10T14:32:00Z"
}
When the drain status cannot be determined, status is error, active_tasks_count is null, and active_tasks is empty. The request still returns 200.
{
"hostname": "tfe-1",
"status": "error",
"is_safe_to_terminate": false,
"active_tasks_count": null,
"active_tasks": []
}
Response codes
| Status | Response | Reason |
|---|---|---|
| 200 | Node drain status object | Request successful |
| 401 | JSON API error object | Authentication required |
| 429 | JSON API error object | Too many requests. Wait before retrying. |
| 500 | JSON API error object | Internal server error |
Get cluster drain status
This endpoint returns a collection with the drain status of every node in the Terraform Enterprise deployment, sorted by hostname. It fans the drain status check out to all live nodes and returns one resource per node, so you do not need to query each node individually. A node that cannot be reached still appears in the collection with status: error, and the request stays 200. Use the filter[nodes] parameter to scope the collection to specific nodes by hostname. Authentication is required to use this endpoint.
GET /api/v1/nodes/drain-status
Query parameters
| Parameter | Type | Description |
|---|---|---|
filter[nodes] | array of strings | Optional. Restrict the collection to the given node hostnames. Use tfectl node list to view node hostnames. If omitted, the response includes all nodes in the deployment. |
Sample request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request GET \
"https://tfe.example.com:8443/api/v1/nodes/drain-status?filter[nodes]=tfe-1"
Sample response
The following response includes one node. The node tfe-1 is draining and reports one active agent-run task. Each resource's links.self is a relative path that scopes the collection to that node.
{
"data": [
{
"id": "tfe-1",
"type": "node-drain-status",
"attributes": {
"hostname": "tfe-1",
"status": "draining",
"is_safe_to_terminate": false,
"active_tasks_count": 1,
"active_tasks": [
{
"name": "agent-run",
"started_at": "2026-06-09T14:40:11Z",
"metadata": {
"run_id": "run-CkszD4iCEaxnYMkh",
"workload_id": "plan-pJ5bfP4pFxQVHDkT",
"workload_type": "Plan",
"workspace_name": "my-app-prod",
"organization_name": "acme-corp",
"organization_id": "org-bright-raven-404724",
"image_tag": "1.28.8",
"tfc_address": "https://tfe.example.com",
"terraform_download_url": "https://releases.hashicorp.com/terraform/1.9.5/terraform_1.9.5_linux_amd64.zip",
"terraform_checksum": "9f3ca38a6d2a6b1c0f4e3d2c1b0a9988776655443322110aabbccddeeff0011"
}
}
],
"drain_started_at": "2026-06-09T14:32:00Z",
"force_terminate_at": "2026-06-10T14:32:00Z"
},
"links": {
"self": "/api/v1/nodes/drain-status?filter[nodes]=tfe-1"
}
}
],
"meta": {
"partial": false
}
}
Collection meta block
The top-level document contains a data array and a meta block. The meta block reports whether the snapshot is complete.
| Attribute | Type | Description |
|---|---|---|
meta.partial | boolean | true when Terraform Enterprise could not enumerate all intended nodes, such as when the database is unavailable and only the local node could be queried. When partial is true, the request returns 503. false when the collection reflects every node in the deployment. |
meta.warnings | array of strings | Non-fatal issues encountered during the run, such as the database being unavailable. This field is omitted when there are no warnings. |
Response codes
| Status | Response | Reason |
|---|---|---|
| 200 | JSON API document | Request successful. Unreachable nodes appear as error resources and still return 200. |
| 400 | JSON API error object | A filter[nodes] entry is blank |
| 401 | JSON API error object | Authentication required |
| 404 | JSON API error object | A hostname in filter[nodes] does not exist |
| 429 | JSON API error object | Too many requests. Wait before retrying. |
| 500 | JSON API error object | Internal server error |
| 503 | JSON API document | The database is unavailable. The response is partial, with meta.partial set to true. |
Response schema
The endpoints describe each node with the same fields. The local endpoint returns these fields at the top level of a flat JSON object, and the cluster endpoint nests them under attributes in each node-drain-status resource.
| Field | Type | Nullable | Description |
|---|---|---|---|
hostname | string | no | Node hostname. Use tfectl node list to view node hostnames. |
status | string enum | no | One of ok, draining, standby, or error. |
is_safe_to_terminate | boolean | no | true only when status is standby. |
active_tasks_count | integer | yes | Number of tasks currently executing on the node. null when status is error. |
active_tasks | array of objects | no | Per-task detail. Empty array when the count is 0 or when status is error. |
drain_started_at | timestamp | yes | When a drain was initiated. Omitted when no drain has been initiated. |
force_terminate_at | timestamp | yes | drain_started_at plus 24 hours. Omitted when no drain has been initiated. |
Per-task fields
Each element of active_tasks describes one task that is currently executing on the node. The task-level name and started_at fields are at the top level of the task object, and the remaining fields are nested under the metadata object. Terraform Enterprise omits any metadata field that has no value, and it never includes sensitive fields such as tokens.
| Field | Type | Nullable | Description |
|---|---|---|---|
name | string | no | Task name. One of agent-run, vcs-ingress, sentinel, cost-estimation, or plan-export-worker. |
started_at | timestamp | no | When the task began executing. |
metadata | object | no | Per-task metadata. The fields listed below are nested under this object. |
metadata.run_id | string | yes | Present for agent-run workspace runs (Plan, Apply, Assessment, TestRun, and TestRunCleanup). Absent for stack runs, vcs-ingress, and other types. |
metadata.workload_id | string | yes | Present for all agent-run and vcs-ingress tasks. Absent for sentinel, cost-estimation, and plan-export-worker. |
metadata.workload_type | string | yes | The type of workload, for example Apply, Stacks::Operations::Plan, or SourceBundle. Populated under the same conditions as workload_id. |
metadata.workspace_name | string | yes | Present for agent-run workspace runs. Absent otherwise. |
metadata.stack_name | string | yes | Present for agent-run stack operations (Stacks::Operations::Plan and Stacks::Operations::Apply). Absent otherwise. |
metadata.organization_name | string | yes | Present for agent-run workspace runs and conditional for stack operations. Absent for vcs-ingress. |
metadata.organization_id | string | yes | Present for all agent-run and vcs-ingress tasks. Absent for sentinel, cost-estimation, and plan-export-worker. |
metadata.image_tag | string | yes | Agent image tag, normalized upstream with any leading colon stripped, for example 1.28.8. |
metadata.tfc_address | string | yes | The Terraform Enterprise address used for this run. |
metadata.terraform_download_url | string | yes | The Terraform binary download URL. |
metadata.terraform_checksum | string | yes | The Terraform binary checksum. |
metadata.payload_url | string | yes | Present for sentinel tasks. |
System API Overview
Terraform Enterprise Only: The System API is exclusive to Terraform Enterprise. It enables access to deployment configuration and data.
This API is distinct from the regular Admin API and the Backup and Restore API, with its own authentication mechanism.
Authentication
All system API endpoints require authentication with a bearer token generated using the tfectl admin api-token generate command. For more information on token creation and management, refer to the tfectl documentation.
Use the HTTP Header Authorization with the value Bearer <token>.
Rate Limiting
All System API endpoints are rate limited to 1 request per second per authentication token.
Network and port configuration
Access to the System API depends on the TFE_ADMIN_CONSOLE_ACCESS_MODE setting:
| Access mode | Port | Base path | Example (/ping) |
|---|---|---|---|
port (default) | Dedicated admin port (configured by TFE_ADMIN_HTTPS_PORT, defaults to 8443) | /api/v1 | https://<TFE_HOSTNAME>:8443/api/v1/ping |
path | Standard HTTPS port (configured by TFE_HTTPS_PORT, defaults to 443) | /platform/admin/api/v1 | https://<TFE_HOSTNAME>/platform/admin/api/v1/ping |
both | Either dedicated admin port or standard HTTPS port | /api/v1 (port) or /platform/admin/api/v1 (path) | Accessible via both endpoints |
Important: When TFE_ADMIN_CONSOLE_ACCESS_MODE is set to path, Terraform Enterprise does not expose System API routes through the dedicated admin port. You must send System API requests over standard HTTPS using the /platform/admin/api/v1 prefix.
Refer to Network settings in the configuration reference for more information about network configuration.
Versioning
The System API is versioned under the /api/v1 prefix (or /platform/admin/api/v1 when using path mode) and is separate from the main Terraform Enterprise API.
For example, if the API endpoint documentation defines the path /ping, the full endpoint path is /api/v1/ping on the dedicated admin port, or /platform/admin/api/v1/ping when using path or both access mode.