Forgecroft Docs
Guides

Go SDK Quickstart

The official Go SDK for Forgecroft has zero external dependencies and is shared by the CLI and agent. Use it to build custom integrations.

Installation

go get github.com/forgecroft/forgecroft/sdk@latest

The SDK uses only the Go standard library — no external dependencies.

Creating a Client

import "github.com/forgecroft/forgecroft/sdk"

client := sdk.New("https://api.forgecroft.com", "fc_live_...")

The client sends Authorization: Bearer <key> on every request. It uses a default 30-second HTTP timeout. You can customize the transport via client.HTTPClient.

Check Your Identity

resp, err := client.WhoAmI(ctx)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Org: %s  Role: %s  Scopes: %v\n", resp.OrgID, resp.OrgRole, resp.Scopes)

List Workspaces

workspaces, err := client.ListWorkspaces(ctx, sdk.ListWorkspacesParams{
    ProjectID: "project-uuid", // optional filter
})

Trigger a Plan

run, err := client.CreateRun(ctx, "workspace-uuid")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Run %s queued\n", run.ID)

Stream Logs

Poll using the next_after cursor until the run completes:

var after int64
for {
    logs, err := client.GetRunLogs(ctx, run.ID, after)
    if err != nil {
        log.Fatal(err)
    }
    for _, line := range logs.Lines {
        fmt.Println(line.Line)
    }
    after = logs.NextAfter

    // Check run status
    r, _ := client.GetRun(ctx, run.ID)
    if sdk.RunStatusIsTerminal(r.Status) {
        fmt.Printf("Run %s: %s\n", r.ID, r.Status)
        break
    }
    time.Sleep(2 * time.Second)
}

List and Filter Runs

runs, err := client.ListRuns(ctx, sdk.ListRunsParams{
    WorkspaceID: "workspace-uuid",
    Status:      "completed",
    Limit:       10,
})

The ListRuns endpoint supports offset pagination and filtering by workspace, project, status, and commit ref.

Manage API Keys

// Create a CI-scoped key
key, err := client.CreateAPIKey(ctx, sdk.APIKeyCreateRequest{
    Name:        "CI",
    ScopeType:   "project",
    ScopeID:     "project-uuid",
    ActionScope: "write",
    Scopes:      []string{"trigger", "read"},
})
// key.Key contains the raw value — store it securely

// Suspend a compromised key immediately
err = client.PatchAPIKey(ctx, keyID, sdk.APIKeyPatchRequest{
    Suspended: boolPtr(true),
})

// List all keys for auditing
keys, err := client.ListAPIKeys(ctx)

Error Handling

API errors are returned as *sdk.APIError:

run, err := client.CreateRun(ctx, workspaceID)
if err != nil {
    var apiErr *sdk.APIError
    if errors.As(err, &apiErr) {
        switch apiErr.StatusCode {
        case 403:
            log.Fatal("API key lacks permission to trigger runs")
        case 409:
            log.Fatal("A run is already in progress for this workspace")
        case 429:
            log.Fatal("Rate limited — back off and retry")
        }
    }
    log.Fatal(err)
}

SDK Coverage

The SDK currently covers authentication, workspaces (read), runs (full lifecycle), and API key management. For endpoints not yet in the SDK (governance, stacks, notifications, etc.), use standard net/http with Bearer token auth against the API reference.