## Validate

`client.Zones.Providers.Validate(ctx, id, body) (*ValidationResult, error)`

**post** `/zones/{zoneId}/providers/{id}/validate`

Runs on-demand OIDC connection checks (issuer reachability, metadata retrieval, endpoint consistency, authorization endpoint reachability, and a demonstration client_credentials exchange) against the provider and returns a per-check result. Results are not persisted.

### Parameters

- `id string`

- `body ZoneProviderValidateParams`

  - `ZoneID param.Field[string]`

### Returns

- `type ValidationResult struct{…}`

  Result of running the provider OIDC connection checks on demand. Not persisted.

  - `Checks []ValidationResultCheck`

    Per-check results, in execution order

    - `Check string`

      Identifier of an individual provider validation check

      - `const ValidationResultCheckCheckIssuerReachability ValidationResultCheckCheck = "issuer_reachability"`

      - `const ValidationResultCheckCheckMetadataRetrieval ValidationResultCheckCheck = "metadata_retrieval"`

      - `const ValidationResultCheckCheckEndpointConsistency ValidationResultCheckCheck = "endpoint_consistency"`

      - `const ValidationResultCheckCheckAuthorizationEndpointReachability ValidationResultCheckCheck = "authorization_endpoint_reachability"`

      - `const ValidationResultCheckCheckCredentialExchange ValidationResultCheckCheck = "credential_exchange"`

    - `Status string`

      Outcome of a single check. `pass`/`fail` mean the check ran. `skipped_with_reason` means it could not run because a prerequisite is missing on our side (e.g. no credential stored). `not_applicable` means the check does not apply to this provider class (e.g. a login-flow-only provider that does not advertise the `client_credentials` grant) — render as a neutral state, distinct from a failure. Neither `skipped_with_reason` nor `not_applicable` fails the overall run.

      - `const ValidationResultCheckStatusPass ValidationResultCheckStatus = "pass"`

      - `const ValidationResultCheckStatusFail ValidationResultCheckStatus = "fail"`

      - `const ValidationResultCheckStatusSkippedWithReason ValidationResultCheckStatus = "skipped_with_reason"`

      - `const ValidationResultCheckStatusNotApplicable ValidationResultCheckStatus = "not_applicable"`

    - `Detail string`

      Human-readable explanation, present on `fail`, `skipped_with_reason`, and `not_applicable`.

  - `ProviderID string`

    Provider that was validated

  - `Status ValidationResultStatus`

    Overall outcome. `fail` when any individual check failed; skipped checks do not fail the run.

    - `const ValidationResultStatusPass ValidationResultStatus = "pass"`

    - `const ValidationResultStatusFail ValidationResultStatus = "fail"`

  - `ValidatedAt Time`

    When the validation run completed

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/keycardai/keycard-go"
  "github.com/keycardai/keycard-go/option"
)

func main() {
  client := keycard.NewClient(
    option.WithAPIKey("My API Key"),
  )
  validationResult, err := client.Zones.Providers.Validate(
    context.TODO(),
    "id",
    keycard.ZoneProviderValidateParams{
      ZoneID: "zoneId",
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", validationResult.ProviderID)
}
```
