A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Terraform Cloud API is how an app or AI agent works with an organization's infrastructure: listing and locking workspaces, queuing a run, applying or cancelling it, reading state versions, and managing variables and projects. Access is granted through an API token, where the token type and the team permissions behind it decide what each call can read or write, and an organization token is barred from running plans or applies at all. There is one stable v2 API, and a workspace can send run events outward to a chosen destination so an integration learns about activity without polling.
How an app or AI agent connects to Terraform Cloud determines what it can reach. There is a route for making calls, a server that exposes Terraform tools to agents, and notification configurations that send events outward, each governed by the token behind it and the team permissions that token carries.
The v2 API answers at app.terraform.io under /api/v2 and follows the JSON:API specification, so requests and responses use the application/vnd.api+json media type with a top-level data object. A call authenticates with a Bearer API token.
HashiCorp's official Terraform MCP server lets an agent call Terraform through the Model Context Protocol. It exposes Terraform Registry provider docs, modules, and Sentinel policies, and connects to HCP Terraform to list organizations and projects and to create, update, and delete workspaces with variables, tags, and run management. It supports the stdio and streamable HTTP transports, is at v1.0, and the source is at github.com/hashicorp/terraform-mcp-server.
A notification configuration on a workspace POSTs a payload to a chosen destination, a generic webhook, email, Slack, or Microsoft Teams, when a run or assessment event it is subscribed to fires. This lets an integration learn about run activity without polling.
A user token acts as that individual and carries every permission the user has across their teams and organizations. It is the only token type, alongside team tokens, that can create runs, apply, discard, cancel runs, and read the JSON execution plan.
A team token acts as the team and carries that team's permissions, which is the recommended choice for CI and pipeline automation. Like a user token, it can queue and apply runs.
An organization token is one per organization, for automating teams and workspaces. It cannot execute plans or applies, so it cannot create, apply, discard, or cancel a run, and it cannot read the JSON execution plan.
An audit trails token is an organization-specific token used only to read the organization's audit trail of events. It does not grant access to the rest of the v2 API.
The Terraform Cloud API is split into areas an agent can act on, such as workspaces, runs, state versions, variables, and projects. Each area has its own methods and its own permission setting, and a write here can queue, apply, or cancel real infrastructure changes.
List, read, create, and update workspaces, lock and unlock them, force-unlock, and delete them.
Create a run, list and read runs, and apply, discard, cancel, or force-cancel a run.
Read a plan, read an apply, and retrieve the JSON execution plan for a run.
List state versions, read a state version, read the current state version, and create a new state version.
List and read configuration versions and create a new one to upload Terraform configuration.
List, create, update, and delete a workspace's Terraform and environment variables.
List, read, create, update, and delete projects that group workspaces.
List organizations, read one, and update or destroy an organization.
List teams, read a team, and create, update, or delete a team.
List, read, create, update, verify, and delete a workspace's run notification configurations.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
WorkspacesList, read, create, and update workspaces, lock and unlock them, force-unlock, and delete them.7 | ||||||
| GET | /organizations/:organization_name/workspaces | List the workspaces in an organization. | read | read runs | Current | |
Returns the workspaces the token's team can view. A 404 is returned for workspaces the token cannot access. Acts onworkspace Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /organizations/:organization_name/workspaces/:name | Show a workspace by name. | read | read runs | Current | |
A workspace can also be read by ID at /workspaces/:workspace_id. Acts onworkspace Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /organizations/:organization_name/workspaces | Create a workspace in an organization. | write | admin | Current | |
Needs the Manage all workspaces organization permission or an organization token. Acts onworkspace Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /workspaces/:workspace_id | Update a workspace's settings by ID. | write | admin | Current | |
Updating settings needs admin access to the workspace. A workspace can also be updated by name. Acts onworkspace Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /workspaces/:workspace_id/actions/lock | Lock a workspace so no run can start. | write | lock/unlock | Current | |
Needs the lock/unlock workspace permission. Acts onworkspace Permission (capability) lock/unlockVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /workspaces/:workspace_id/actions/unlock | Unlock a workspace. | write | lock/unlock | Current | |
Needs the lock/unlock workspace permission. Force-unlock, at the force-unlock action, needs admin access. Acts onworkspace Permission (capability) lock/unlockVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /workspaces/:workspace_id | Force-delete a workspace and the resources it manages. | write | admin | Current | |
Needs admin access. A safe-delete action refuses to delete a workspace that still manages resources. Acts onworkspace Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
RunsCreate a run, list and read runs, and apply, discard, cancel, or force-cancel a run.6 | ||||||
| POST | /runs | Queue a new run (a plan, and an apply if confirmed) on a workspace. | write | queue plans | Current | |
Needs the queue plans permission. This action cannot use an organization token, only a user or team token. Acts onrun Permission (capability) queue plansVersionAvailable since the API’s base version Webhook event run:createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /workspaces/:workspace_id/runs | List the runs in a workspace. | read | read runs | Current | |
Runs can also be listed across an organization at /organizations/:organization_name/runs. Acts onrun Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /runs/:run_id | Get the details of a run. | read | read runs | Current | |
The run object's relationships point to its plan and apply IDs. Acts onrun Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /runs/:run_id/actions/apply | Apply a run that is paused awaiting confirmation. | write | apply runs | Current | |
Needs the apply runs permission. Cannot use an organization token. This is the action that changes real infrastructure. Acts onrun Permission (capability) apply runsVersionAvailable since the API’s base version Webhook event run:applyingRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /runs/:run_id/actions/discard | Discard a run that is paused, skipping any remaining work. | write | apply runs | Current | |
Needs the apply runs permission. Cannot use an organization token. Acts onrun Permission (capability) apply runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /runs/:run_id/actions/cancel | Cancel a run that is currently planning or applying. | write | apply runs | Current | |
Needs the apply runs permission. Force-cancel, at the force-cancel action, needs admin access to the workspace. Acts onrun Permission (capability) apply runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Plans & appliesRead a plan, read an apply, and retrieve the JSON execution plan for a run.3 | ||||||
| GET | /plans/:id | Show a plan, including its status and resource change counts. | read | read runs | Current | |
A plan ID comes from a run's relationships. Acts onplan Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /plans/:id/json-output | Retrieve the machine-readable JSON execution plan. | read | admin | Current | |
Cannot use an organization token. Needs a user or team token with admin access to the workspace. Acts onplan Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /applies/:id | Show an apply, including its status and logs. | read | read runs | Current | |
There is no endpoint to list applies; an apply ID comes from a run's relationships. Acts onapply Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
State versionsList state versions, read a state version, read the current state version, and create a new state version.4 | ||||||
| GET | /state-versions | List the state versions for a workspace, filtered by organization and workspace. | read | read state versions | Current | |
Needs the read state versions permission for the workspace. Acts onstate version Permission (capability) read state versionsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /workspaces/:workspace_id/current-state-version | Fetch the current state version, the input for the next Terraform operation. | read | read state versions | Current | |
Needs the read state versions permission for the workspace. Acts onstate version Permission (capability) read state versionsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /state-versions/:state_version_id | Show a single state version by ID. | read | read state versions | Current | |
Needs the read state versions permission for the workspace. Acts onstate version Permission (capability) read state versionsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /workspaces/:workspace_id/state-versions | Create a state version and set it as the workspace's current state. | write | write state versions | Current | |
Needs the read and write state versions permission, and the workspace must be locked by the calling token. Acts onstate version Permission (capability) write state versionsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Configuration versionsList and read configuration versions and create a new one to upload Terraform configuration.3 | ||||||
| GET | /workspaces/:workspace_id/configuration-versions | List the configuration versions for a workspace. | read | read runs | Current | |
Needs the read runs permission. Acts onconfiguration version Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /configuration-versions/:configuration_id | Show a single configuration version by ID. | read | read runs | Current | |
Needs the read runs permission. Acts onconfiguration version Permission (capability) read runsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /workspaces/:workspace_id/configuration-versions | Create a configuration version to upload Terraform configuration for a run. | write | queue plans | Current | |
Needs the queue plans permission. The response returns an upload URL, and the configuration archive is then uploaded to that URL with a separate PUT. Acts onconfiguration version Permission (capability) queue plansVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
VariablesList, create, update, and delete a workspace's Terraform and environment variables.4 | ||||||
| GET | /workspaces/:workspace_id/vars | List a workspace's Terraform and environment variables. | read | read variables | Current | |
Needs the read variables permission. A sensitive variable's value is write-once and is never returned. Acts onvariable Permission (capability) read variablesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /workspaces/:workspace_id/vars | Create a variable in a workspace. | write | write variables | Current | |
Needs the read and write variables permission. Acts onvariable Permission (capability) write variablesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /workspaces/:workspace_id/vars/:variable_id | Update a workspace variable's value or settings. | write | write variables | Current | |
Needs the read and write variables permission. Acts onvariable Permission (capability) write variablesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /workspaces/:workspace_id/vars/:variable_id | Delete a variable from a workspace. | write | write variables | Current | |
Needs the read and write variables permission. Acts onvariable Permission (capability) write variablesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ProjectsList, read, create, update, and delete projects that group workspaces.5 | ||||||
| GET | /organizations/:organization_name/projects | List the projects in an organization. | read | — | Current | |
Returns the projects the token's team can view. Acts onproject Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /projects/:project_id | Show a project by ID. | read | — | Current | |
Returns the project if the token's team can view it. Acts onproject Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /organizations/:organization_name/projects | Create a project to group workspaces. | write | Manage projects | Current | |
Needs the Owners or Manage projects team permission, or an organization token. Acts onproject Permission (capability) Manage projectsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /projects/:project_id | Update a project's name or settings. | write | Manage projects | Current | |
Needs the Owners or Manage projects team permission, or an organization token. Acts onproject Permission (capability) Manage projectsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /projects/:project_id | Delete a project. | write | Manage projects | Current | |
Needs the Owners or Manage projects team permission. A project must be empty before it can be deleted. Acts onproject Permission (capability) Manage projectsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
OrganizationsList organizations, read one, and update or destroy an organization.3 | ||||||
| GET | /organizations | List the organizations the token can access. | read | — | Current | |
Returns the organizations visible to the token. Acts onorganization Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /organizations/:organization_name | Show an organization's details. | read | — | Current | |
Returns the organization if the token can view it. Acts onorganization Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /organizations/:organization_name | Update an organization's settings. | write | admin | Current | |
Needs organization owner access. Acts onorganization Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TeamsList teams, read a team, and create, update, or delete a team.3 | ||||||
| GET | /organizations/:organization_name/teams | List the teams in an organization. | read | — | Current | |
Any member can view visible teams; only owners see the full set of secret teams. Acts onteam Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /organizations/:organization_name/teams | Create a team in an organization. | write | admin | Current | |
Only organization owners, or an owners team token, can create or modify teams. Acts onteam Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /teams/:team_id | Delete a team. | write | admin | Current | |
Only organization owners can delete a team. Teams can also be read by ID and updated with PATCH. Acts onteam Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Notification configurationsList, read, create, update, verify, and delete a workspace's run notification configurations.3 | ||||||
| GET | /workspaces/:workspace_id/notification-configurations | List a workspace's notification configurations. | read | admin | Current | |
Interacting with notification configurations needs admin access to the workspace. Acts onnotification configuration Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /workspaces/:workspace_id/notification-configurations | Create a notification configuration that sends run events to a destination. | write | admin | Current | |
Needs admin access. The destination can be a generic webhook, email, Slack, or Microsoft Teams, and it subscribes to chosen run and assessment triggers. Acts onnotification configuration Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /notification-configurations/:notification_configuration_id/actions/verify | Send a test message to verify a notification configuration's destination. | write | admin | Current | |
Needs admin access. A configuration can also be read with GET, updated with PATCH, and deleted with DELETE by ID. Acts onnotification configuration Permission (capability) adminVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Terraform Cloud can notify an app or AI agent when a run changes state, instead of the app repeatedly asking. A notification configuration on a workspace sends a payload to a chosen destination for the run and assessment events it is subscribed to.
| Event | What it signals | Triggered by |
|---|---|---|
run:created | Fires when a run enters the pending stage, after it has been queued. | /runs |
run:planning | Fires when a run acquires the workspace lock and begins planning. | /runs |
run:needs_attention | Fires when a plan has changes and the run is paused awaiting confirmation. | /runs |
run:applying | Fires when a run enters the apply stage and begins changing infrastructure. | /runs/:run_id/actions/apply |
run:completed | Fires when a run completes successfully. | /runs/:run_id/actions/apply |
run:errored | Fires when a run ends because of an error or a cancellation. | /runs/runs/:run_id/actions/apply |
assessment:drifted | Fires when a health assessment detects drift between real infrastructure and the recorded state. | In-app only |
assessment:check_failure | Fires when continuous validation checks fail during a health assessment. | In-app only |
assessment:failed | Fires when a health assessment itself fails to run. | In-app only |
Terraform Cloud limits how fast an app or AI agent can call, through a per-second request rate that is counted per user or per IP address rather than per token.
Terraform Cloud allows up to 30 requests per second to most endpoints, whether a request is authenticated or not. The limit is counted per user, or per IP address for unauthenticated calls, rather than per token, so several tokens belonging to the same user share one budget. Going over returns HTTP 429 with a JSON:API error. A few endpoints have their own lower thresholds, such as SMS operations at 5 requests per minute.
List endpoints take page[number] and page[size] query parameters. The page size defaults to 20 and tops out at 100. Each response carries a links object with first, prev, next, and last URLs where they apply, and a meta.pagination object with the current page, page size, and total counts.
Responses are JSON:API documents using the application/vnd.api+json media type. Pages return at most 100 records. Configuration is uploaded as a .tar.gz archive to a separate upload URL returned when a configuration version is created, rather than in the JSON body.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | Unauthorized | The API token is absent or invalid. | Send a valid Bearer token in the Authorization header. |
| 404 | Not Found | The resource does not exist, or the token's team cannot see it. Terraform Cloud returns 404 rather than 403 for resources a user cannot access, so it does not confirm a hidden resource exists. | Confirm the path is correct and that the token's team has permission to reach the resource. |
| 422 | Unprocessable Entity | The request was understood but failed validation, such as a malformed JSON:API body or an invalid attribute. The JSON:API errors array names what failed. | Read the errors array, correct the named field, and resend. |
| 429 | Too Many Requests | The rate limit was exceeded. Limits are counted per user, or per IP address for unauthenticated calls, not per token. | Slow the request rate to within 30 requests per second and retry. |
Terraform Cloud serves a single v2 API and ships dated changes through a public API changelog rather than minting new version numbers.
Terraform Cloud serves a single v2 API and ships changes through a public, dated API changelog rather than minting new version numbers. The entries below are recent notable changes from that changelog.
Documented new /registry-components endpoints for reading, publishing, updating, and deleting Stack component configurations in an organization's private registry.
Updated workspace defaults to match project settings rather than the organization default, and extended agent pool scoping with allowed projects and workspace exclusions.
Documented support for multiple team tokens per team, distinguished from the single legacy team token.
The v2 API is stable, and notable additions and changes are published with dates in the changelog.
HCP Terraform API changelog ↗Bollard AI sits between a team's AI agents and Terraform Cloud. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.