> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Terraform Provider

> terraform-provider-knoxcall — manage KnoxCall routes, secrets, clients, and webhooks as code through the /v1 Management API.

The official Terraform provider manages KnoxCall resources as code through the `/v1` Management API. Built with the Terraform Plugin Framework.

## Resources

| Resource           | CRUD | Import     |
| ------------------ | ---- | ---------- |
| `knoxcall_route`   | Yes  | Yes (`id`) |
| `knoxcall_secret`  | Yes  | Yes (`id`) |
| `knoxcall_client`  | Yes  | Yes (`id`) |
| `knoxcall_webhook` | Yes  | Yes (`id`) |

## Provider configuration

```hcl theme={"dark"}
terraform {
  required_providers {
    knoxcall = {
      source = "knoxcall/knoxcall"
    }
  }
}

provider "knoxcall" {
  # Defaults to https://api.knoxcall.com (or $KNOXCALL_BASE_URL).
  base_url = "https://api.knoxcall.com"

  # A tenant API key (tk_…) or OAuth token (kc_…). Sent as Authorization: Bearer.
  # Prefer the KNOXCALL_API_KEY environment variable over committing this.
  api_key = var.knoxcall_api_key
}
```

<Note>
  Not yet published to the Terraform Registry — until it is, build from the monorepo (`sdk/knoxcall-terraform`) and point Terraform at the local binary with a `dev_overrides` block in `~/.terraformrc`.
</Note>

## Example

```hcl theme={"dark"}
resource "knoxcall_route" "weather" {
  name            = "weather-api"
  target_base_url = "https://api.weatherapi.com"
}

resource "knoxcall_secret" "weather_key" {
  name  = "weather-api-key"
  value = var.weather_api_key # Sensitive; never read back from the server
}

resource "knoxcall_client" "backend" {
  name       = "backend-service"
  type       = "server"
  ip_address = "203.0.113.10"
}

resource "knoxcall_webhook" "alerts" {
  name        = "request-errors"
  url         = "https://hooks.example.com/knoxcall"
  event_types = ["request.server_error", "request.timeout"]
}

output "route_id" {
  value = knoxcall_route.weather.id
}
```

## Sensitive state

* `knoxcall_secret.value` is **write-only server-side** — `GET` returns metadata, never the value — so `Read` keeps the value from state instead of diffing it. Rotations you make outside Terraform will not show as drift.
* `knoxcall_webhook.secret_key` is returned **exactly once** at create and preserved in state (marked `Sensitive`) across refreshes.
* The provider's `api_key` is `Sensitive` in the schema and never appears in errors, logs, or diagnostics.

<Warning>
  Both values live in your Terraform state file. Treat the state as a secret: use an encrypted remote backend and restrict access accordingly.
</Warning>

## Import

All four resources import by `id` (the resource's UUID):

```sh theme={"dark"}
terraform import knoxcall_route.weather <route-uuid>
```

## Behavior

The provider's API client follows the [SDK parity standard](/sdks/overview) where applicable:

* **Retries:** 408/429/500/502/503/504 retried up to 3 attempts with half-jitter exponential backoff (100ms base, 5s cap). 409 is never retried. On 429 a server `Retry-After` is honored, capped at 30s.
* **Idempotency:** every mutating request carries a ULID `X-Idempotency-Key` generated once per logical request — stable across retries, so transport failures are also safe to retry.
* **401:** fails fast with a clear diagnostic (the credential is a static `api_key`, so there is nothing to re-mint).
* **Cancellation:** all requests and retry backoffs respect Terraform's operation context — interrupts abort promptly.

## Full reference

Local build instructions and `dev_overrides` setup: [`sdk/knoxcall-terraform/README.md`](https://github.com/knoxcall/knoxcall/tree/main/sdk/knoxcall-terraform) in the monorepo.
