Skip to content

Documentation · API reference

The Terraform API

We implement much of the Terraform Enterprise API. This is where we differ from it, including the endpoint that answers 501 on purpose.

We implement much of the Terraform Enterprise API, which is what lets the terraform and tofu CLIs, the tfe provider and go-tfe work against us unmodified.

The base URL is https://tf.runners.io. Authenticate with a bearer token — see API tokens.

HashiCorp's own documentation is therefore the reference for request and response shapes. This page records only where we differ, because that is the part their documentation cannot tell you.

The host answers the API paths and turns everything else away. There is no web interface there — the dashboard at runners.io is the place with screens, and the engine's own interface is deliberately unreachable.

One consequence worth knowing before you spend an afternoon on it: service discovery advertises a login.v1 block, but terraform login tf.runners.io cannot complete, because the browser step of that flow is on a path the host does not serve. Tokens come from the dashboard.

Their docs. This is the API for what both products call VCS providers.

The create endpoint documents two parameters, http-url and api-url. We use only http-url — the homepage or base URL of your VCS provider — and infer the API URL from it. For public GitHub, http-url is https://github.com and the API URL is derived as https://api.github.com.

service-provider accepts the documented values, and we use it to work out which kind of provider to create. We make no distinction between sub-kinds: gitlab_community_edition and gitlab_enterprise_edition are the same kind here.

Their docs.

Not implemented, deliberately and permanently. Both POST /organizations/{organization}/organization-memberships and DELETE /organization-memberships/{id} answer 501 Not Implemented. This is a decision, not a gap that will be filled later.

That endpoint is the invite-by-email flow: bringing in somebody who does not yet have an account. Access here is modelled through teams instead:

  • POST /teams/{team_id}/memberships/{username} adds an existing user to a team by username. That covers a colleague who already has an account here.

  • It does not cover inviting somebody who has none. That happens on the dashboard, under Settings → People, because identity belongs to the control plane rather than to the run engine — the invitation, its expiring token, the acceptance page and the binding to the right organisation are all there already.

If you are migrating from Terraform Cloud or Enterprise and have scripted invitations against organization-memberships, the equivalent here is inviting from the dashboard.

This endpoint used to be worse than absent. It minted a plausible id and answered 201 Created while writing nothing anywhere, so somebody inviting a colleague was told it had worked when nothing had happened. An honest failure beats a silent one, and the error the API returns now names the supported alternative.

Not supported. Workspaces belong to an organisation directly. This changes the subject format for dynamic credentials — see dynamic credentials.

The registry is served at /v1/modules/, advertised as modules.v1 in service discovery, so source = "tf.runners.io/<org>/<name>/<provider>" resolves in a configuration the way it does anywhere else.

Registry modules are managed over the TFE registry-modules API, or with the tfe provider. Publishing from a repository through a screen is not yet available here.