Go SDK
Status: pre-release. The SDK is in active development. This page documents the v1.0 shape; until the module is published, use the REST API directly per Authentication and Conventions.
An idiomatic Go client. Context-aware, no runtime dependencies, generated from the OpenAPI spec. Targets Go 1.22+.
Install (when shipped)
go get github.com/NimbusNexus/nimbusnexus-go
Quick usage
package main
import (
"context"
"log"
"os"
"time"
nn "github.com/NimbusNexus/nimbusnexus-go"
)
func main() {
client := nn.NewClient(nn.Config{
APIKey: os.Getenv("NIMBUS_KEY"),
})
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// List VMs
page, err := client.VMs.List(ctx, &nn.VMListParams{
Region: nn.String("us-east-1"),
Limit: nn.Int(50),
})
if err != nil { log.Fatal(err) }
for _, vm := range page.Items {
log.Println(vm.ID, vm.Name, vm.State)
}
// Create a VM
vm, err := client.VMs.Create(ctx, &nn.VMCreateParams{
Name: "web-01",
Size: "gp-1-2",
Region: "us-east-1",
Image: "ubuntu-24.04",
})
if err != nil { log.Fatal(err) }
log.Println("created", vm.ID)
}
Design principles
- Context everywhere. Every API call takes a
context.Context. No default-context shortcuts. Cancel a slow request by canceling its context. - Mirrors the REST API.
client.VMs.List(ctx, ...)isGET /v1/vms. Resource groups follow the URL —client.Databases.Snapshots.List(ctx, dbID, ...)isGET /v1/databases/{db_id}/snapshots. - Zero runtime dependencies. Only standard library. We're explicit about not pulling in
viper,cobra, or any opinionated companion — those are your call. - Idiomatic params with pointers. Optional fields are pointers (
*string,*int); use the helpersnn.String("..."),nn.Int(42),nn.Bool(true)to take addresses of literals. - Idempotency by default. Mutating calls auto-generate a UUID
IdempotencyKey. Override viann.VMCreateParams{ IdempotencyKey: nn.String("...") }. - Retries 429 + 5xx. Default config retries with exponential backoff + jitter. Disable with
nn.Config{ MaxRetries: -1 }.
Configuration
client := nn.NewClient(nn.Config{
APIKey: os.Getenv("NIMBUS_KEY"),
BaseURL: "https://api.nimbusnexus.net", // defaults to canonical
Timeout: 30 * time.Second,
MaxRetries: 3,
RetryBackoff: time.Second, // base; doubled per attempt with jitter
UserAgent: "my-app/2.4", // appended to the default UA
HTTPClient: customClient, // optional *http.Client override
})
Webhook verification helper
This verifies platform webhooks — the notifications NimbusNexus sends you about
your own infrastructure, signed with NN- headers. It is not the helper for the
Webhooks product, which signs with X-Webhook- headers and ships its own
Go module; the two expose a same-named Verify with different signatures, so a snippet from the
wrong page compiles nowhere useful. The import below is aliased nnwebhooks to keep which is which
visible at the call site.
import nnwebhooks "github.com/NimbusNexus/nimbusnexus-go/webhooks"
func handleWebhook(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil { http.Error(w, "bad body", 400); return }
ok := nnwebhooks.Verify(nnwebhooks.VerifyParams{
Body: body,
Timestamp: r.Header.Get("NN-Timestamp"),
Signature: r.Header.Get("NN-Signature"),
Secret: os.Getenv("NIMBUS_WEBHOOK_SECRET"),
})
if !ok {
http.Error(w, "bad signature", 401)
return
}
// handle event...
w.WriteHeader(200)
}
The verifier uses crypto/hmac.Equal for constant-time comparison and enforces a 5-minute replay window via the NN-Timestamp header.
Pagination helper
// Manual paging
iter := client.VMs.ListPages(ctx, &nn.VMListParams{Region: nn.String("us-east-1")})
for iter.Next() {
page := iter.Page()
log.Printf("got %d VMs", len(page.Items))
}
if err := iter.Err(); err != nil { log.Fatal(err) }
// Auto-flatten — yields one resource per iteration
all := client.VMs.ListAll(ctx, &nn.VMListParams{Region: nn.String("us-east-1")})
for all.Next() {
vm := all.Value()
log.Println(vm.Name)
}
if err := all.Err(); err != nil { log.Fatal(err) }
Both iterators handle the cursor walk for you. See Pagination for the mechanics.
Errors
The SDK exposes a typed error type for every error.code:
vm, err := client.VMs.Create(ctx, &nn.VMCreateParams{
Name: "web-01",
Size: "gp-1-2",
Region: "us-east-1",
Image: "ubuntu-24.04",
})
if err != nil {
var validation *nn.ValidationError
if errors.As(err, &validation) {
for field, problem := range validation.Fields {
log.Printf(" %s: %s", field, problem)
}
return
}
var rate *nn.RateLimitError
if errors.As(err, &rate) {
log.Printf("slow down — wait %s", rate.RetryAfter)
return
}
log.Fatal(err)
}
Error types: AuthenticationError, PermissionError, ValidationError, NotFoundError, ConflictError, RateLimitError, ServerError. All implement the standard error interface and unwrap to *nn.APIError (the underlying error envelope).
Where it stands today
The SDK is being generated from the OpenAPI spec but hasn't been published yet. While you wait:
- Use the REST API directly. Auth + conventions are documented and stable.
- The shape on this page is the API design we're committing to.
- Subscribe to the changelog for the release announcement.
What's next
- Authentication — what
APIKeydoes on the wire. - Platform webhooks — what
nnwebhooks.Verifyis checking. - Webhooks (product) — the separate webhook-delivery product, with its own Go module and signing headers.
- Pagination — what the iterators are walking.
- Errors — the codes that map to the typed error types above.