Go Reference Client
The Go package is Keel’s official generated/reference client. Use it when your Go service needs OpenAPI-derived bindings for Keel’s public API.
Go is not a first-class runtime wrapper SDK. The package does not maintain provider-specific wrappers, streaming helpers, custom retry/backoff policy, or custom error types.
Install
go get github.com/keelapi/keel-go/pkg/keelclientPackage
Runtime API calls use the generated client package:
import keelclient "github.com/keelapi/keel-go/pkg/keelclient"The repository root package is documentation-only. Install the generated runtime package above so Go resolves its dependencies; installing only the root package does not prepare this client example.
Basic example
keelclient.NewClient builds the client. The generated client does not add
authentication or request-freshness headers, so register a request editor that
sets them. Hosted Keel requires a current X-Keel-Timestamp (Unix seconds) and
a new X-Keel-Nonce (at least 16 characters) on every POST /v1/permits,
execution, and proxy request; without them it returns 401 request_not_fresh.
The editor runs before every request, so each attempt, including a retry, gets
new values. See Request Freshness.
package main
import (
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"time"
keelclient "github.com/keelapi/keel-go/pkg/keelclient"
)
// keelHeaders runs before every request the client sends. It adds the project
// key and the freshness headers hosted Keel requires: the current Unix time and
// a new random nonce for each attempt, including retries.
func keelHeaders(ctx context.Context, req *http.Request) error {
nonce := make([]byte, 16)
if _, err := rand.Read(nonce); err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("KEEL_API_KEY"))
req.Header.Set("X-Keel-Timestamp", strconv.FormatInt(time.Now().Unix(), 10))
req.Header.Set("X-Keel-Nonce", hex.EncodeToString(nonce))
return nil
}
func main() {
client, err := keelclient.NewClient(
os.Getenv("KEEL_BASE_URL"),
keelclient.WithRequestEditorFn(keelHeaders),
)
if err != nil {
log.Fatal(err)
}
resp, err := client.CreatePermitV1PermitsPost(
context.Background(),
nil,
keelclient.CreatePermitV1PermitsPostJSONRequestBody{
"project_id": os.Getenv("KEEL_PROJECT_ID"),
"idempotency_key": "go-example-1",
"subject": map[string]interface{}{
"type": "user",
"id": "user-123",
},
"action": map[string]interface{}{
"name": "ai.generate",
},
"resource": map[string]interface{}{
"type": "request",
"id": "req-go-example-1",
"attributes": map[string]interface{}{
"provider": "openai",
"model": "gpt-4o-mini",
"operation": "generate.text",
"estimated_input_tokens": 100,
"estimated_output_tokens": 100,
},
},
},
)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(body))
}Set KEEL_BASE_URL to https://api.keelapi.com, and KEEL_API_KEY and
KEEL_PROJECT_ID to your project’s values. The ai.generate action with
generate.text matches the default policy a new personal project starts with;
any other action needs a policy rule that allows it. Every decision, including
deny and review, returns HTTP 200; act only when the body’s decision is
allow.
The generated client returns standard *http.Response values. Callers own status
handling, response decoding, retry policy, and transport configuration.
Regeneration
The canonical OpenAPI source is generated by keel-api and published as a public
artifact. Regenerate the Go client from that OpenAPI contract in the keel-go
repo with:
make generatePublished OpenAPI coverage is a subset of the public HTTP API. Regeneration does not add support for an omitted or unreleased route. Verify the generated client’s operation against its documented release contract before relying on it.
Related pages
- SDKs — Python and TypeScript runtime SDKs plus generated-client posture
- SDK Support Surfaces — official support tiers
- Public API Surface — customer-facing route projection