Skip to main content

Documentation Index

Fetch the complete documentation index at: https://gcore.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

The gcore-go module provides typed access to the full Gcore REST API from Go 1.22+. Generated from the OpenAPI specification using Stainless, all request structs use Go’s type system with omitzero semantics from Go 1.24 encoding/json. All responses are strongly typed structs with a .JSON metadata field for optional field inspection. Module: github.com/G-Core/gcore-go · Source: gcore-go on GitHub

Requirements

Go 1.22 or higher.

Install

go get github.com/G-Core/gcore-go
To pin a specific version:
go get -u 'github.com/G-Core/gcore-go@v0.48.0'

Initialize the client

gcore.NewClient() returns a value type (gcore.Client), not a pointer. The client reads the API key from the GCORE_API_KEY environment variable by default:
package main

import (
    "context"
    "fmt"
    "os"

    "github.com/G-Core/gcore-go"
    "github.com/G-Core/gcore-go/cloud"
    "github.com/G-Core/gcore-go/option"
)

func main() {
    client := gcore.NewClient(
        option.WithAPIKey(os.Getenv("GCORE_API_KEY")),
    )
}

First call

List all instances in a project and region:
projectID, _ := strconv.ParseInt(os.Getenv("PROJECT_ID"), 10, 64)
regionID, _  := strconv.ParseInt(os.Getenv("REGION_ID"), 10, 64)

page, err := client.Cloud.Instances.List(context.TODO(), cloud.InstanceListParams{
    ProjectID: gcore.Int(projectID),
    RegionID:  gcore.Int(regionID),
})
if err != nil {
    panic(err)
}
for _, inst := range page.Results {
    fmt.Println(inst.ID, inst.Name)
}

Request parameters

Required primitive fields carry the tag `api:"required"` and are always serialized, even when zero. Optional fields are wrapped in param.Opt[T] and set using the provided constructors:
params := cloud.InstanceNewParams{
    ProjectID: projectID,                   // required int64 - always serialized
    RegionID:  regionID,                    // required int64 - always serialized
    Flavor:    "g2-standard-2-4",           // required string
    Name:      gcore.String("my-vm"),       // optional - use gcore.String(), gcore.Int(), etc.
}
To send null for an optional field instead of omitting it:
params.Name = param.Null[string]()
Flavor IDs are region-specific. Run client.Cloud.Instances.Flavors.List(ctx, params) to see what flavors are available in a given region before creating an instance.

Task polling

Cloud API write operations return a task ID. Use NewAndPoll methods where available - they submit the request and block until the resource is ready:
projectID, _ := strconv.ParseInt(os.Getenv("PROJECT_ID"), 10, 64)
regionID, _  := strconv.ParseInt(os.Getenv("REGION_ID"), 10, 64)
imageID := os.Getenv("IMAGE_ID")

instance, err := client.Cloud.Instances.NewAndPoll(context.TODO(), cloud.InstanceNewParams{
    ProjectID: projectID,
    RegionID:  regionID,
    Flavor:    "g2-standard-2-4",
    Name:      gcore.String("my-vm"),
    Interfaces: []cloud.InstanceNewParamsInterface{
        {Type: cloud.InstanceNewParamsInterfaceTypeExternal},
    },
    Volumes: []cloud.InstanceNewParamsVolume{{
        Source:    cloud.InstanceNewParamsVolumeSourceImage,
        ImageID:   gcore.String(imageID),
        Size:      gcore.Int(20),
        BootIndex: gcore.Int(0),
    }},
})
if err != nil {
    panic(err)
}
fmt.Println(instance.ID)
When NewAndPoll is not available for a resource, poll with client.Cloud.Tasks.Poll directly:
taskList, err := client.Cloud.SomeResource.New(context.TODO(), params)
if err != nil {
    panic(err)
}

task, err := client.Cloud.Tasks.Poll(context.TODO(), taskList.Tasks[0])
if err != nil {
    panic(err)
}

// task.CreatedResources is a typed struct
fmt.Println(task.CreatedResources.Instances[0])
task.CreatedResources is a typed struct. Access fields as task.CreatedResources.Instances[0], not as a map. The client.Cloud.Tasks.Get(ctx, taskID) method takes only the task ID string - no project or region parameters.

Pagination

Use ListAutoPaging() to iterate across all pages automatically:
iter := client.Cloud.Projects.ListAutoPaging(context.TODO(), cloud.ProjectListParams{
    Limit: gcore.Int(10),
})
for iter.Next() {
    project := iter.Current()
    fmt.Printf("%+v\n", project)
}
if err := iter.Err(); err != nil {
    panic(err)
}
For manual page control:
page, err := client.Cloud.Projects.List(context.TODO(), cloud.ProjectListParams{
    Limit: gcore.Int(10),
})
for page != nil {
    for _, project := range page.Results {
        fmt.Println(project.ID, project.Name)
    }
    page, err = page.GetNextPage()
}
if err != nil {
    panic(err)
}

Error handling

Use errors.As to inspect API errors:
import "errors"

_, err := client.Cloud.Projects.New(context.TODO(), cloud.ProjectNewParams{
    Name: "my-project",
})
if err != nil {
    var apierr *gcore.Error
    if errors.As(err, &apierr) {
        fmt.Println(string(apierr.DumpRequest(true)))
        fmt.Println(string(apierr.DumpResponse(true)))
    }
    panic(err)
}

Retries and timeouts

The client retries connection errors, 408, 409, 429, and 5xx errors twice by default. Requests have no default timeout - use context to set one:
// Set a 5-minute budget for the request including all retries
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()

client.Cloud.Projects.New(
    ctx,
    cloud.ProjectNewParams{Name: "my-project"},
    option.WithRequestTimeout(20*time.Second), // per-retry timeout
)
Disable or configure retries:
// Globally
client := gcore.NewClient(option.WithMaxRetries(0))

// Per request
client.Cloud.Projects.New(ctx, params, option.WithMaxRetries(5))

Middleware

Apply custom logic to all requests using option.WithMiddleware:
func Logger(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
    start := time.Now()
    res, err := next(req)
    fmt.Printf("%s %s %v\n", req.Method, req.URL, time.Since(start))
    return res, err
}

client := gcore.NewClient(
    option.WithAPIKey(os.Getenv("GCORE_API_KEY")),
    option.WithMiddleware(Logger),
)
When multiple middleware functions are provided, they run left to right. Client-level middleware runs before per-request middleware.

Accessing raw response data

Use option.WithResponseInto() to capture the raw HTTP response alongside the parsed result:
var response *http.Response
project, err := client.Cloud.Projects.New(
    context.TODO(),
    cloud.ProjectNewParams{Name: "my-project"},
    option.WithResponseInto(&response),
)
fmt.Printf("Status: %d\n", response.StatusCode)
fmt.Printf("Headers: %+v\n", response.Header)