> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Client

> The rest package is the entry point to the Go SDK. Instantiate a client with an API key and access every resource — applications, databases, workspaces, user and platform service — through a single interface.

## Requirements

* **Go 1.24** or newer
* **Zero external dependencies** — the SDK is built on the Go standard library only
* A valid API key — request one at the [Square Cloud Dashboard](https://squarecloud.app/en/dashboard) under **My Account → Regenerate API/CLI KEY**

## Installation

```bash theme={null}
go get github.com/squarecloudofc/sdk-api-go/v2
```

The module ships two packages:

| Package       | Import path                                           | Contents                                                              |
| ------------- | ----------------------------------------------------- | --------------------------------------------------------------------- |
| `rest`        | `github.com/squarecloudofc/sdk-api-go/v2/rest`        | HTTP client, resource interfaces, request options, errors, SSE stream |
| `squarecloud` | `github.com/squarecloudofc/sdk-api-go/v2/squarecloud` | Every request/response type and struct                                |

## Instantiating the client

```go theme={null}
package main

import (
	"fmt"
	"os"

	"github.com/squarecloudofc/sdk-api-go/v2/rest"
)

func main() {
	client := rest.NewClient(os.Getenv("SQUARECLOUD_API_KEY"))
	defer client.Close()

	api := rest.New(client)

	user, err := api.SelfUser()
	if err != nil {
		panic(err)
	}
	fmt.Println(user.Name)
}
```

`rest.NewClient(token, opts...)` builds the underlying HTTP client; `rest.New(client)` wraps it in `rest.Rest`, the interface that exposes every resource. Always `defer client.Close()` to release idle connections.

### Client configuration (`ConfigOpt`)

`rest.NewClient` accepts optional `ConfigOpt`s after the token:

| Option                              | Default                          | Description                                           |
| ----------------------------------- | -------------------------------- | ----------------------------------------------------- |
| `rest.WithLogger(*slog.Logger)`     | discarded                        | Structured logger for request/response debugging      |
| `rest.WithHTTPClient(*http.Client)` | 30s timeout                      | Custom `*http.Client` (proxies, transports, timeouts) |
| `rest.WithURL(string)`              | `https://api.squarecloud.app/v2` | Base API URL                                          |
| `rest.WithUserAgent(string)`        | SDK default                      | Custom `User-Agent` header                            |

```go theme={null}
client := rest.NewClient(
	os.Getenv("SQUARECLOUD_API_KEY"),
	rest.WithLogger(slog.Default()),
	rest.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}),
)
```

## Modules

`rest.Rest` embeds one interface per resource domain, plus the user and service methods documented on this page:

| Interface      | Coverage                                                           | Documentation                                             |
| -------------- | ------------------------------------------------------------------ | --------------------------------------------------------- |
| `Applications` | Manage, upload, files, envs, snapshots, deploys, network, realtime | [Managing applications](/en/sdks/go/managing_application) |
| `Databases`    | Create, manage, credentials and snapshots                          | [Databases](/en/sdks/go/databases)                        |
| `Workspaces`   | Create, members, shared applications                               | [Workspaces](/en/sdks/go/workspaces)                      |

## Getting the authenticated user

`api.SelfUser()` returns a `squarecloud.User` with the account details and current plan.

```go theme={null}
user, err := api.SelfUser()
if err != nil {
	panic(err)
}

fmt.Println(user.ID)       // "abcdef0123456789abcdef01"
fmt.Println(user.Name)     // "John Doe"
fmt.Println(user.Email)    // "john@example.com"
fmt.Println(user.Locale)   // "en-US"
fmt.Println(user.Plan.Name)             // e.g. "standard"
fmt.Println(user.Plan.Duration)         // plan duration, e.g. "monthly"
fmt.Println(user.Plan.Memory.Limit)     // MB
fmt.Println(user.Plan.Memory.Available) // MB
fmt.Println(user.Plan.Memory.Used)      // MB
fmt.Println(user.CreatedAt)
```

| Field       | Type                   | Description                                                  |
| ----------- | ---------------------- | ------------------------------------------------------------ |
| `ID`        | `string`               | User ID (24 hex chars)                                       |
| `Name`      | `string`               | Display name                                                 |
| `Email`     | `string`               | Account email                                                |
| `Locale`    | `string`               | Preferred locale, e.g. `"en-US"`                             |
| `Plan`      | `squarecloud.UserPlan` | `Name`, `Memory{Limit, Available, Used}` (MB) and `Duration` |
| `CreatedAt` | `string`               | Account creation date                                        |

## Listing your applications and databases

`api.GetApplications()` and `api.GetDatabases()` list everything you own through the `/users/me` endpoint, returning compact `squarecloud.UserApplication` / `squarecloud.UserDatabase` descriptors:

```go theme={null}
apps, err := api.GetApplications()
if err != nil {
	panic(err)
}
for _, app := range apps {
	fmt.Printf("%s (%s) — %dMB\n", app.Name, app.ID, app.RAM)
}

dbs, err := api.GetDatabases()
if err != nil {
	panic(err)
}
for _, db := range dbs {
	fmt.Printf("%s (%s)\n", db.Name, db.ID)
}
```

To fetch the full record of a single resource, use `GetApplication` / `GetDatabase` — see [Managing applications](/en/sdks/go/managing_application) and [Databases](/en/sdks/go/databases).

## Listing snapshot history (account-wide)

`api.UserSnapshots(scope)` returns every snapshot you own for a given domain:

```go theme={null}
appSnapshots, err := api.UserSnapshots(squarecloud.SnapshotScopeApplications)
if err != nil {
	panic(err)
}

dbSnapshots, err := api.UserSnapshots(squarecloud.SnapshotScopeDatabases)
if err != nil {
	panic(err)
}
```

See [Snapshots](/en/sdks/go/snapshots) for details on snapshot payloads.

## Platform status

`api.ServiceStatus()` exposes the aggregated platform health (the same data shown on the public status page).

```go theme={null}
status, err := api.ServiceStatus()
if err != nil {
	panic(err)
}

fmt.Println(status.Status)  // "ok" | "degraded" | "down"
fmt.Println(status.Message) // human-readable summary
```

<Note>
  Unlike most v2 endpoints, this route does **not** wrap its payload in the standard `{ status, code, response }` envelope — it responds with `{ status, message }` directly.
</Note>

## Request options

Every method accepts trailing `...rest.RequestOpt`s to customize the individual request:

| Option                            | Description                                              |
| --------------------------------- | -------------------------------------------------------- |
| `rest.WithContext(ctx)`           | Attach a `context.Context` for cancellation or deadlines |
| `rest.WithQueryParam(key, value)` | Append a query parameter                                 |
| `rest.WithHeader(key, value)`     | Set a request header                                     |
| `rest.WithToken(token)`           | Override the authentication token for this request only  |

```go theme={null}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

user, err := api.SelfUser(rest.WithContext(ctx))
if err != nil {
	panic(err)
}
```

## Error handling

Any non-2xx response is returned as a `*rest.APIError` exposing `StatusCode`, `Code` and `Message`. Unwrap it with the idiomatic `errors.As`:

```go theme={null}
app, err := api.GetApplication("invalid-id")
if err != nil {
	var apiErr *rest.APIError
	if errors.As(err, &apiErr) {
		fmt.Println(apiErr.StatusCode) // e.g. 404
		fmt.Println(apiErr.Code)       // e.g. "APP_NOT_FOUND"
		fmt.Println(apiErr.Message)
	}
	return
}
```

Two helpers simplify common checks:

* `rest.ErrorCode(err) string` — returns the API error code (or `""` when the error is not an `*rest.APIError`)
* `rest.IsRateLimit(err) bool` — reports whether the error is any of the rate-limit codes (`KEEP_CALM`, `RATE_LIMIT`, `RATE_LIMIT_EXCEEDED`, `RATELIMIT`, `DELAY_NOW`)

```go theme={null}
if err != nil {
	if rest.IsRateLimit(err) {
		time.Sleep(5 * time.Second)
		// retry...
	}

	switch rest.ErrorCode(err) {
	case "APP_NOT_FOUND":
		fmt.Println("application does not exist")
	case "ACCESS_DENIED":
		fmt.Println("invalid API key")
	}
}
```

The error codes are the same ones used by `@squarecloud/api-types` — see the [full code table in the JS SDK reference](/en/sdks/js/client#error-codes-apierrorcode).
