> ## 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.

# Migrazione a v3

> Cosa è cambiato tra la v2 e la v3 dell'SDK Go: un solo package, un *Client concreto, ctx come primo argomento, gruppi di risorse, un unico tipo di errore, timeout e retry. Una tabella metodo per metodo.

La v3 è una release con breaking change. Usa un solo package, un `*Client` concreto, `ctx` come primo argomento ovunque e gruppi di risorse, e corregge ogni bug noto della v2. Copre tutte le 67 operazioni dell'API attuale.

## In sintesi

|          | v2                                                              | v3                                                                                                      |
| -------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Modulo   | `.../v2` (package `rest` + `squarecloud`)                       | `github.com/squarecloudofc/sdk-api-go/v3` (un solo package)                                             |
| Client   | `rest.New(rest.NewClient(key, ...))` (interfaccia)              | `squarecloud.New(key, ...Option)` (`*Client`)                                                           |
| Chiamate | `api.GetApplicationStatus(id, rest.WithContext(ctx))`           | `c.Apps.Status(ctx, id)`                                                                                |
| Errori   | `*rest.APIError` con `StatusCode`, errori di rete non tipizzati | `*squarecloud.APIError` con `Status`, `Code`, `Message`, `Method`, `Path` per tutto                     |
| Timeout  | `http.Client` con un `Timeout` fisso di 30 s su tutto           | Per chiamata tramite `ctx`; `WithTimeout`; flussi senza limite                                          |
| Retry    | Nessuno                                                         | Errori di rete delle GET e 503 `UPLOAD_BUSY`/`ANALYTICS_BUSY`/`DATABASE_UNAVAILABLE` (`WithMaxRetries`) |
| Logging  | `WithLogger` (esponeva segreti)                                 | Nessuno                                                                                                 |
| Go       | 1.24                                                            | 1.22 o più recente                                                                                      |
| Licenza  | AGPL-3.0                                                        | MIT                                                                                                     |

## Costruzione e opzioni

```diff theme={"system"}
-import (
-	"github.com/squarecloudofc/sdk-api-go/v2/rest"
-	"github.com/squarecloudofc/sdk-api-go/v2/squarecloud"
-)
-client := rest.NewClient(token, rest.WithUserAgent(ua), rest.WithLogger(logger))
-api := rest.New(client)
-defer client.Close()
+import "github.com/squarecloudofc/sdk-api-go/v3"
+
+c := squarecloud.New(token, squarecloud.WithUserAgent(ua))
```

```bash theme={"system"}
go get github.com/squarecloudofc/sdk-api-go/v3@v3.0.0
```

| v2                                                    | v3                                                                                                                |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Package `rest` + `squarecloud`                        | Un solo package `squarecloud` (modulo `.../v3`)                                                                   |
| `rest.NewClient(token, opts...)` + `rest.New(client)` | `squarecloud.New(token, opts...)`                                                                                 |
| `rest.Rest` (interfaccia)                             | `*squarecloud.Client` (struct concreta). Per farne un mock, dichiara una tua piccola interfaccia o usa `httptest` |
| `rest.ConfigOpt`                                      | `squarecloud.Option`                                                                                              |
| `rest.WithHTTPClient(hc)`                             | `squarecloud.WithHTTPClient(hc)`. Non impostare `hc.Timeout`: interromperebbe i flussi realtime e i download      |
| `rest.WithURL(u)`                                     | `squarecloud.WithBaseURL(u)` (include ancora `/v2`)                                                               |
| `rest.WithUserAgent(ua)`                              | `squarecloud.WithUserAgent(ua)`                                                                                   |
| `rest.WithLogger(l)`                                  | Rimosso: l'SDK non scrive mai log (la v2 esponeva segreti nei log di debug). Avvolgi `hc.Transport` per tracciare |
| `client.Close()`, `client.HTTPClient()`               | Rimossi: mantieni un tuo `*http.Client` e chiama `CloseIdleConnections` su di esso                                |
| `rest.APIURL`, `rest.APIVersion`, `rest.Endpoint*`    | Rimossi; `squarecloud.DefaultBaseURL` è una costante                                                              |
| (nessuno)                                             | `squarecloud.WithMaxRetries(n)` (nuovo; predefinito 2)                                                            |
| Timeout fisso di 30 s dell'`http.Client`              | `squarecloud.WithTimeout(d)` (nuovo; predefinito 30 s, `d <= 0` disattiva tutte le scadenze predefinite)          |

Opzioni per richiesta:

| v2                                                                                      | v3                                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rest.WithContext(ctx)`                                                                 | `ctx` è il primo argomento di ogni metodo                                                                                                                                                          |
| `rest.WithToken(token)` (ad es. per validare una chiave al login)                       | Crea un client usa e getta: `squarecloud.New(token).Account.Me(ctx)` (economico, non mantiene connessioni)                                                                                         |
| `rest.WithQueryParam("path", dir)` nel commit                                           | `c.Apps.Commit(ctx, id, r, dir, "")`                                                                                                                                                               |
| `rest.WithQueryParam(filter, v)` nelle analytics                                        | `c.Apps.Network.Analytics(ctx, id, start, end, squarecloud.AnalyticsFilters{...})` con `Country`, `IP`, `Path`, `Status`, `OS`, `Browser`, `Protocol`, `Referer`, `Provider`, `ContentType`, `Bot` |
| `rest.WithQueryParam("include_4xx", "true")`                                            | `c.Apps.Network.Errors(ctx, id, start, end, true)`                                                                                                                                                 |
| `rest.WithQueryParam("workspaceId", ws)` nello stato dell'elenco                        | `c.Apps.StatusAll(ctx, ws)`                                                                                                                                                                        |
| `rest.WithHeader`, `rest.RequestOpt`, `rest.RequestConfig`, `rest.DefaultRequestConfig` | Rimossi                                                                                                                                                                                            |

## Metodo per metodo

`api` è il `rest.Rest` della v2, `c` il `*squarecloud.Client` della v3.

| v2                                                                                        | v3                                                                                                                        | Note                                                                                                                                                                                                                                                                                          |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `api.SelfUser()`                                                                          | `me, err := c.Account.Me(ctx)`, poi `me.User`                                                                             | Restituisce `Account`                                                                                                                                                                                                                                                                         |
| `api.GetApplications()`                                                                   | `c.Account.Me(ctx)`, poi `me.Applications` (`[]AppSummary`)                                                               |                                                                                                                                                                                                                                                                                               |
| `api.GetDatabases()`                                                                      | `c.Account.Me(ctx)`, poi `me.Databases` (`[]DatabaseSummary`)                                                             |                                                                                                                                                                                                                                                                                               |
| `api.UserSnapshots(scope)`                                                                | `c.Account.Snapshots(ctx, scope)`                                                                                         |                                                                                                                                                                                                                                                                                               |
| `api.ServiceStatus()`                                                                     | `c.Service.Status(ctx)`                                                                                                   | Nuovo modello, vedi [Tipi](#tipi)                                                                                                                                                                                                                                                             |
| `api.PostApplications(r)` → `*ApplicationUploaded`                                        | `c.Apps.Create(ctx, r)` → `AppCreated` (un valore)                                                                        | La v2 teneva lo zip in memoria e chiamava la parte `upload.zip`; la v3 lo trasmette in streaming e chiama la parte come un `*os.File` (il suo nome base), altrimenti `app.zip`. `Subdomain` non esiste più: leggi `Domain`, l'host completo (`my-app.squareweb.app`), `""` per le app non web |
| `api.GetApplication(id)`                                                                  | `c.Apps.Get(ctx, id)`                                                                                                     |                                                                                                                                                                                                                                                                                               |
| `api.DeleteApplication(id)`                                                               | `c.Apps.Delete(ctx, id)`                                                                                                  |                                                                                                                                                                                                                                                                                               |
| `api.PostApplicationSignal(id, squarecloud.ApplicationSignalStart/Stop/Restart)`          | `c.Apps.Start(ctx, id)` / `c.Apps.Stop(ctx, id)` / `c.Apps.Restart(ctx, id)`                                              |                                                                                                                                                                                                                                                                                               |
| `api.PostApplicationCommit(id, r, rest.WithQueryParam("path", p))`                        | `c.Apps.Commit(ctx, id, r, p, filename)`                                                                                  | La v2 chiamava sempre la parte `commit.zip`; la v3 usa `filename`, altrimenti il nome proprio di un `*os.File`, quindi un singolo file non zip ora finisce sotto il suo nome invece di fallire come zip                                                                                       |
| `api.GetApplicationStatus(id)`                                                            | `c.Apps.Status(ctx, id)`                                                                                                  |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationStatusRaw(id)`                                                         | `c.Apps.StatusRaw(ctx, id)`                                                                                               |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationListStatus()`                                                          | `c.Apps.StatusAll(ctx, "")`                                                                                               | Restituisce `[]StatusListItem`                                                                                                                                                                                                                                                                |
| `api.GetApplicationLogs(id)` → `ApplicationLogs`                                          | `c.Apps.Logs(ctx, id)` → `string`                                                                                         |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationMetrics(id)`                                                           | `c.Apps.Metrics(ctx, id)`                                                                                                 | I punti arrivano dal più recente, come li invia l'API                                                                                                                                                                                                                                         |
| `api.ApplicationRealtime(id, rest.WithContext(ctx))`                                      | `c.Apps.Realtime(ctx, id)`                                                                                                | Restituisce `*Realtime`; vedi [Cambiamenti di comportamento](#cambiamenti-di-comportamento)                                                                                                                                                                                                   |
| `api.GetApplicationDomains()`                                                             | `c.Apps.Domains(ctx)`                                                                                                     |                                                                                                                                                                                                                                                                                               |
| `api.GetLoadBalancers()`                                                                  | `c.Apps.LoadBalancers(ctx)`                                                                                               |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationEnvs(id)`                                                              | `c.Apps.Envs.Get(ctx, id)`                                                                                                |                                                                                                                                                                                                                                                                                               |
| `api.SetApplicationEnvs(id, envs)`                                                        | `c.Apps.Envs.Set(ctx, id, envs)`                                                                                          |                                                                                                                                                                                                                                                                                               |
| `api.ReplaceApplicationEnvs(id, envs)`                                                    | `c.Apps.Envs.Replace(ctx, id, envs)`                                                                                      |                                                                                                                                                                                                                                                                                               |
| `api.DeleteApplicationEnvs(id, keys)` → `error`                                           | `c.Apps.Envs.Delete(ctx, id, keys...)` → `(EnvVars, error)` (le variabili rimanenti)                                      |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationFiles(id, path)` → `[]FileInfo`                                        | `c.Apps.Files.List(ctx, id, path)` → `[]FileEntry`                                                                        | Una directory mancante ora produce 404 `FILE_NOT_FOUND` (prima era un elenco vuoto); un percorso protetto produce 403 `BLOCKED_PATH`                                                                                                                                                          |
| `api.ReadApplicationFile(id, path)` → `FileContent`                                       | `c.Apps.Files.Read(ctx, id, path)` → `[]byte`                                                                             | Richiesto in base64 e decodificato; un file oltre 10 MB produce 413 `FILE_TOO_LARGE`                                                                                                                                                                                                          |
| `api.PutApplicationFile(id, path, b)` → `(FileWritten, error)`                            | `c.Apps.Files.Write(ctx, id, path, b)` → `error`. Elimina qualsiasi controllo su `written`: il successo è un errore `nil` | Il contenuto viene sempre inviato codificato in base64, quindi i file binari sono al sicuro; un contenuto vuoto scrive un file vuoto                                                                                                                                                          |
| `api.MoveApplicationFile(id, from, to)`                                                   | `c.Apps.Files.Move(ctx, id, path, to)`                                                                                    |                                                                                                                                                                                                                                                                                               |
| `api.DeleteApplicationFile(id, path)`                                                     | `c.Apps.Files.Delete(ctx, id, path)`                                                                                      | Ora funziona (nella v2 dava sempre 400)                                                                                                                                                                                                                                                       |
| `api.GetApplicationSnapshots(id)`                                                         | `c.Apps.Snapshots.List(ctx, id)`                                                                                          | Ogni `Snapshot` ora contiene `VersionID` e `URL` (link di download firmato) forniti dall'API                                                                                                                                                                                                  |
| `api.CreateApplicationSnapshot(id)`                                                       | `c.Apps.Snapshots.Create(ctx, id)`                                                                                        | Controlla `.Pending` (202) prima di usare `.URL`                                                                                                                                                                                                                                              |
| `api.RestoreApplicationSnapshot(id, snapID, verID)`                                       | `c.Apps.Snapshots.Restore(ctx, id, snap.Name, snap.VersionID)`                                                            | `VersionID` è un campo inviato dall'API: non serve più estrarre nulla da `Key`. Vedi [Snapshot](/it/sdks/go/snapshots#ripristinare-uno-snapshot) per gli errori                                                                                                                               |
| `api.GetApplicationDeployments(id)`                                                       | `c.Apps.Deploys.List(ctx, id)`                                                                                            |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationCurrentDeployment(id)`                                                 | `c.Apps.Deploys.Current(ctx, id)`                                                                                         |                                                                                                                                                                                                                                                                                               |
| `api.PostApplicationDeployWebhook(id, token)` → `GithubWebhook`                           | `c.Apps.Deploys.SetWebhook(ctx, id, token)` → `string`                                                                    |                                                                                                                                                                                                                                                                                               |
| `api.LinkApplicationGithubApp(id, repo, branch)` → `GithubAppLink`                        | `c.Apps.Deploys.LinkGithubApp(ctx, id, repo, branch)` → `LinkedRepository`                                                | Ora le chiavi API funzionano (scope `apps:deploy`); il wrapper `repository` non esiste più; un account senza GitHub collegato produce 403 `GITHUB_NOT_CONNECTED`                                                                                                                              |
| `api.UnlinkApplicationGithubApp(id)`                                                      | `c.Apps.Deploys.UnlinkGithubApp(ctx, id)`                                                                                 | 400 `GIT_NOT_CONFIGURED` senza un collegamento                                                                                                                                                                                                                                                |
| `api.GetApplicationDNS(id)`                                                               | `c.Apps.Network.DNS(ctx, id)`                                                                                             |                                                                                                                                                                                                                                                                                               |
| `api.SetApplicationCustomDomain(id, d)`                                                   | `c.Apps.Network.SetDomain(ctx, id, d)`                                                                                    |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationAnalytics(id, s, e, opts...)`                                          | `c.Apps.Network.Analytics(ctx, id, s, e, squarecloud.AnalyticsFilters{...})`                                              | Restituisce `*NetworkAnalytics`, `nil` per una finestra senza traffico                                                                                                                                                                                                                        |
| `api.GetApplicationNetworkErrors(id, s, e, opts...)`                                      | `c.Apps.Network.Errors(ctx, id, s, e, include4xx)`                                                                        | Restituisce `*NetworkErrors`, `nil` se vuoto                                                                                                                                                                                                                                                  |
| `api.GetApplicationNetworkLogs(id, s, e)`                                                 | `c.Apps.Network.Logs(ctx, id, s, e)`                                                                                      |                                                                                                                                                                                                                                                                                               |
| `api.GetApplicationNetworkPerformance(id, s, e)`                                          | `c.Apps.Network.Performance(ctx, id, s, e)`                                                                               | Restituisce `*NetworkPerformance`, `nil` se vuoto                                                                                                                                                                                                                                             |
| `api.PurgeApplicationCache(id)`                                                           | `c.Apps.Network.PurgeCache(ctx, id)`                                                                                      |                                                                                                                                                                                                                                                                                               |
| `api.CreateDatabase(opts)`                                                                | `c.Databases.Create(ctx, squarecloud.DatabaseCreate{...})`                                                                |                                                                                                                                                                                                                                                                                               |
| `api.GetDatabase(id)`                                                                     | `c.Databases.Get(ctx, id)`                                                                                                |                                                                                                                                                                                                                                                                                               |
| `api.UpdateDatabase(id, opts)`                                                            | `c.Databases.Update(ctx, id, squarecloud.DatabaseUpdate{...})`                                                            |                                                                                                                                                                                                                                                                                               |
| `api.DeleteDatabase(id)`                                                                  | `c.Databases.Delete(ctx, id)`                                                                                             |                                                                                                                                                                                                                                                                                               |
| `api.StartDatabase(id)` / `api.StopDatabase(id)`                                          | `c.Databases.Start(ctx, id)` / `c.Databases.Stop(ctx, id)`                                                                |                                                                                                                                                                                                                                                                                               |
| `api.GetDatabaseStatus(id)` / `api.GetDatabaseStatusRaw(id)`                              | `c.Databases.Status(ctx, id)` / `c.Databases.StatusRaw(ctx, id)`                                                          |                                                                                                                                                                                                                                                                                               |
| `api.GetDatabaseListStatus()`                                                             | `c.Databases.StatusAll(ctx)`                                                                                              | Restituisce `[]StatusListItem`                                                                                                                                                                                                                                                                |
| `api.GetDatabaseMetrics(id)`                                                              | `c.Databases.Metrics(ctx, id)`                                                                                            |                                                                                                                                                                                                                                                                                               |
| `api.GetDatabaseCertificate(id)` → `DatabaseCertificate`                                  | `c.Databases.Certificate(ctx, id)` → `string` (PEM in base64)                                                             |                                                                                                                                                                                                                                                                                               |
| `api.ResetDatabaseCredentials(id, t)` → `DatabasePasswordReset`                           | `c.Databases.ResetCredentials(ctx, id, t)` → `string`                                                                     | La nuova password, `""` per il reset del certificato                                                                                                                                                                                                                                          |
| `api.GetDatabaseSnapshots` / `CreateDatabaseSnapshot` / `RestoreDatabaseSnapshot`         | `c.Databases.Snapshots.List` / `Create` / `Restore`                                                                       | Come per le app: ripristina con `snap.Name` e `snap.VersionID`                                                                                                                                                                                                                                |
| `api.GetWorkspaces()`                                                                     | `c.Workspaces.List(ctx)`                                                                                                  |                                                                                                                                                                                                                                                                                               |
| `api.GetWorkspace(id)`                                                                    | `c.Workspaces.Get(ctx, id)`                                                                                               |                                                                                                                                                                                                                                                                                               |
| `api.CreateWorkspace(name)`                                                               | `c.Workspaces.Create(ctx, name)`                                                                                          |                                                                                                                                                                                                                                                                                               |
| `api.DeleteWorkspace(id)`                                                                 | `c.Workspaces.Delete(ctx, id)`                                                                                            |                                                                                                                                                                                                                                                                                               |
| `api.LeaveWorkspace(id)`                                                                  | `c.Workspaces.Leave(ctx, id)`                                                                                             |                                                                                                                                                                                                                                                                                               |
| `api.AddWorkspaceMember(ws, code, group)`                                                 | `c.Workspaces.Members.Add(ctx, ws, code, group)`                                                                          |                                                                                                                                                                                                                                                                                               |
| `api.UpdateWorkspaceMember(ws, member, group)`                                            | `c.Workspaces.Members.Update(ctx, ws, member, group)`                                                                     |                                                                                                                                                                                                                                                                                               |
| `api.RemoveWorkspaceMember(ws, member)`                                                   | `c.Workspaces.Members.Remove(ctx, ws, member)`                                                                            |                                                                                                                                                                                                                                                                                               |
| `api.GetWorkspaceInviteCode()` → `WorkspaceInviteCode`                                    | `c.Workspaces.Members.InviteCode(ctx)` → `string`                                                                         |                                                                                                                                                                                                                                                                                               |
| `api.AddWorkspaceApplication(ws, app)` / `RemoveWorkspaceApplication`                     | `c.Workspaces.Apps.Add(ctx, ws, app)` / `Remove`                                                                          |                                                                                                                                                                                                                                                                                               |
| Scaricare da solo l'URL di uno snapshot (`http.Get`)                                      | `c.DownloadSnapshot(ctx, url, w)`                                                                                         | Trasmette in streaming verso qualsiasi `io.Writer`; non invia mai la chiave                                                                                                                                                                                                                   |
| `rest.IsRateLimit(err)`                                                                   | `errors.As(err, &apiErr) && apiErr.Status == 429`                                                                         | Rimosso                                                                                                                                                                                                                                                                                       |
| `rest.ErrorCode(err)`                                                                     | `errors.As(err, &apiErr)`, poi `apiErr.Code`                                                                              | Rimosso                                                                                                                                                                                                                                                                                       |
| `client.Request(...)`, `client.Stream(...)` (`rest.Client`)                               | I metodi tipizzati sopra                                                                                                  | Rimossi: ogni operazione ha il proprio metodo                                                                                                                                                                                                                                                 |
| `rest.NewApplications(client)`, `rest.NewDatabases(client)`, `rest.NewWorkspaces(client)` | `squarecloud.New(key)`, poi i campi `c.Apps`, `c.Databases`, `c.Workspaces`                                               | Rimossi                                                                                                                                                                                                                                                                                       |
| `rest.Applications`, `rest.Databases`, `rest.Workspaces` (interfacce)                     | `squarecloud.AppsAPI`, `DatabasesAPI`, `WorkspacesAPI` (i tipi di quei campi)                                             | Rimosse; dichiara una tua interfaccia per il mock                                                                                                                                                                                                                                             |
| `rest.Config`, `rest.DefaultConfig()`, `(*rest.Config).Apply(opts)`                       | `squarecloud.New(key, opts...)` con `WithHTTPClient`, `WithBaseURL`, `WithUserAgent`                                      | Rimossi (usa `Option`; non c'è un logger)                                                                                                                                                                                                                                                     |
| `(*rest.RequestConfig).Apply(opts)`                                                       | Passa `ctx` e argomenti tipizzati                                                                                         | Rimosso                                                                                                                                                                                                                                                                                       |
| `(*rest.RealtimeStream).Next()` / `Close()`                                               | `(*squarecloud.Realtime).Next()` / `Close()`                                                                              | `Next` restituisce `io.EOF` dopo `REALTIME_DISCONNECTED`                                                                                                                                                                                                                                      |
| (nessuno)                                                                                 | `c.AI.Chat(ctx, squarecloud.ChatRequest{...})`                                                                            | Nuovo                                                                                                                                                                                                                                                                                         |

## Tipi

| v2 (`squarecloud.`)                                                                                                                                                     | v3 (`squarecloud.`)                                                                                                                                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `User` (da `SelfUser`)                                                                                                                                                  | `User` (dentro `Account`, il risultato di `Account.Me`)                                                                                                                                                                                                                  |
| `UserPlan`, `UserPlanMemory`                                                                                                                                            | `Plan`, `PlanMemory`. `Plan.Duration` è la scadenza in **millisecondi** Unix (`*int64`, `nil` quando non scade mai): convertila con `time.UnixMilli`, non con `time.Unix`                                                                                                |
| `UserApplication`, `UserDatabase` (`Type string`)                                                                                                                       | `AppSummary`, `DatabaseSummary` (`Type DatabaseType`)                                                                                                                                                                                                                    |
| `Application`                                                                                                                                                           | `App`                                                                                                                                                                                                                                                                    |
| `ApplicationUploaded` (`CPU int`), `ApplicationLanguage`                                                                                                                | `AppCreated` (`CPU float64`), `AppLanguage`                                                                                                                                                                                                                              |
| `ApplicationStatus`, `DatabaseStatus`                                                                                                                                   | `RuntimeStats` (condiviso)                                                                                                                                                                                                                                               |
| `ApplicationStatusRaw`, `DatabaseStatusRaw`                                                                                                                             | `RuntimeStatsRaw`                                                                                                                                                                                                                                                        |
| `ApplicationStatusNetwork`, `ApplicationStatusNetworkRaw`                                                                                                               | `StatsNetwork`, `StatsNetworkRaw`                                                                                                                                                                                                                                        |
| `ApplicationStatusListItem`, `DatabaseStatusListItem`                                                                                                                   | `StatusListItem`                                                                                                                                                                                                                                                         |
| `ApplicationLogs`                                                                                                                                                       | `string`                                                                                                                                                                                                                                                                 |
| `ApplicationSignal*`                                                                                                                                                    | Rimossi (usa `Start`/`Stop`/`Restart`)                                                                                                                                                                                                                                   |
| `FileInfo` (`Type FileType`, `LastModified int64`), costanti `FileType*`                                                                                                | `FileEntry` (`Type string`, `LastModified *float64`): `"file"`/`"directory"`; l'API invia ms Unix frazionari, oppure `null`                                                                                                                                              |
| `FileContent`, `ByteArray`                                                                                                                                              | `[]byte`                                                                                                                                                                                                                                                                 |
| `FileWritten`                                                                                                                                                           | Rimosso (campo non documentato)                                                                                                                                                                                                                                          |
| `Deployment` (`State DeploymentState`)                                                                                                                                  | `DeployEvent` (`State`, `Source`, `Code`, `Message` come `string`). `Source` è nuovo, sempre `"git"`; un evento `"error"` contiene `Code`, ad es. `CLONE_FAILED`, e talvolta `Message`                                                                                   |
| `DeploymentState*` (`DeploymentStateError` = `"error"`)                                                                                                                 | Costanti stringa `Deploy*` (`DeployPending`, `DeployClone`, `DeployCommit`, `DeployRestarting`, `DeploySuccess`, `DeployError` = `"error"`)                                                                                                                              |
| `DeploymentFiles`, `DeploymentCurrent`, `DeploymentGithubApp`                                                                                                           | `DeployFiles`, `DeployCurrent`, `DeployRepository`                                                                                                                                                                                                                       |
| `GithubWebhook`                                                                                                                                                         | `string`                                                                                                                                                                                                                                                                 |
| `GithubAppLink`, `GithubAppRepository`                                                                                                                                  | `LinkedRepository` con `ID`, `FullName`, `Branch` (restituito direttamente, senza wrapper `Repository`)                                                                                                                                                                  |
| `Snapshot`                                                                                                                                                              | `Snapshot` + `VersionID`, `URL`, `Runtime`, `Origin` (tutti i campi inviati dall'API)                                                                                                                                                                                    |
| `SnapshotCreated`                                                                                                                                                       | `SnapshotCreated` + `Pending`                                                                                                                                                                                                                                            |
| `DatabaseType` con `DatabaseTypeMongo`, `DatabaseTypeMySQL`, `DatabaseTypeRedis`, `DatabaseTypePostgres`                                                                | `DatabaseType` (invariato) con `DatabaseMongo`, `DatabaseMySQL`, `DatabaseRedis`, `DatabasePostgres` (costanti rinominate)                                                                                                                                               |
| `DatabaseCreateOptions`, `DatabaseUpdateOptions`                                                                                                                        | `DatabaseCreate`, `DatabaseUpdate`                                                                                                                                                                                                                                       |
| `DatabaseCreated` (`CPU int`, `Certificate string`)                                                                                                                     | `DatabaseCreated` (`CPU float64`, `Certificate *string`, `nil` quando l'API non ne invia)                                                                                                                                                                                |
| `DatabaseResetType`, `DatabaseResetPassword`, `DatabaseResetCertificate`                                                                                                | `DatabaseReset`, `ResetPassword`, `ResetCertificate`                                                                                                                                                                                                                     |
| `DatabaseCertificate`, `DatabasePasswordReset`                                                                                                                          | `string`                                                                                                                                                                                                                                                                 |
| `WorkspaceMemberGroup`, `WorkspaceGroup*`                                                                                                                               | Input: `WorkspaceGroup` (`GroupAdmin`, `GroupMaintain`, `GroupManager`, `GroupView`); `WorkspaceMember.Group` è una `string` (può essere `"owner"`)                                                                                                                      |
| `WorkspaceMember` (`Name string`)                                                                                                                                       | `WorkspaceMember` (`Name *string`, `nil` quando l'API invia `null`). Gli id dei workspace sono di 32 o 40 caratteri esadecimali                                                                                                                                          |
| `WorkspaceInviteCode`                                                                                                                                                   | `string`                                                                                                                                                                                                                                                                 |
| `ServiceStatus` (`Status`, `Message`)                                                                                                                                   | `ServiceStatus` (`Status`, `Message`, `CheckedAt`, `Stale`, `Services`, `Dependencies`). `Status` ora è ad es. `"online"`; le voci sono `ServiceEntry`                                                                                                                   |
| `rest.RealtimeStream`                                                                                                                                                   | `*squarecloud.Realtime` (`Next`, `Close`)                                                                                                                                                                                                                                |
| `RealtimeEvent` (`Event`, `Data`)                                                                                                                                       | `RealtimeEvent` (`Event`, `Data`, `ID`, `Stream`, `Line`, `Status`)                                                                                                                                                                                                      |
| Opzioni di query nelle analytics                                                                                                                                        | `AnalyticsFilters` (senza `Start`/`End`: sono argomenti)                                                                                                                                                                                                                 |
| `NetworkErrorsSummaryClass` (`Class4xx`, `Class5xx`)                                                                                                                    | `NetworkErrorsSummary.ByClass`, una `map[string]int64` con le chiavi `"4xx"` e `"5xx"`                                                                                                                                                                                   |
| `NetworkErrorsByStatus`, `NetworkErrorsTimeseries`, `NetworkErrorsTopPath`, `NetworkErrorsByMethod`                                                                     | `NetworkErrorsStatus`, `NetworkErrorsBucket`, `NetworkErrorsPath`, `NetworkErrorsMethod`                                                                                                                                                                                 |
| `NetworkLatency`, `NetworkPerformance*`                                                                                                                                 | `Percentiles` (`P50`/`P95`/`P99` sono `*float64`, `nil` per una finestra senza richieste), `PerformanceSummary`, `PerformanceBucket`, `PerformanceRegion` (paesi e colo; `P50`/`P95` `*float64`, `City`/`Country` `*string`), `PerformancePath` (`P95`/`P99` `*float64`) |
| `RealtimeStatus`                                                                                                                                                        | `RealtimeStatus.CPULimit` è un numero di core (ad es. `1`, `0.5`)                                                                                                                                                                                                        |
| Valori dei provider nelle analytics                                                                                                                                     | `"NAME (ASN)"` (ad es. `"GOOGLE (15169)"`); `AnalyticsFilters.Provider` accetta esattamente quel valore                                                                                                                                                                  |
| `AppDomainType*`                                                                                                                                                        | `AppDomain.Type` è una `string`                                                                                                                                                                                                                                          |
| `APIResponse[T]`                                                                                                                                                        | Rimosso (interno)                                                                                                                                                                                                                                                        |
| Dimensioni e contatori `int` (`FileInfo.Size`, `Snapshot.Size`, `Visits`/`Requests` delle analytics, totali e mappe degli errori di rete, `Requests` delle prestazioni) | `int64`                                                                                                                                                                                                                                                                  |

## Errori

`rest.APIError` (`StatusCode`, `Code`, `Message`) diventa `squarecloud.APIError` (`Status`, `Code`, `Message`, `Method`, `Path`): rinomina `StatusCode` in `Status`. `rest.ErrorCode(err)` e `rest.IsRateLimit(err)` sono stati rimossi: usa `errors.As` e controlla `Code` o `Status == 429`.

```go theme={"system"}
// v2
if rest.IsRateLimit(err) { ... }

// v3
var apiErr *squarecloud.APIError
if errors.As(err, &apiErr) && apiErr.Status == 429 {
	fmt.Println(apiErr.Code, apiErr.Message) // KEEP_CALM or RATE_LIMITED
}
```

* I fallimenti di rete ora sono `*APIError` con `Status` `0`, `Code` `NETWORK_ERROR` o `TIMEOUT` e il testo della causa come `Message`, e fanno l'unwrap alla causa (`errors.Is(err, context.Canceled)` funziona).
* Lo stesso vale per i controlli locali (`Status` `0`: `INVALID_ID`, `FILE_TOO_LARGE`, `INVALID_API_KEY`) e per un body 2xx che non è JSON (`UNKNOWN_ERROR`, `Invalid JSON in HTTP <status> response`).
* Un body 2xx che contiene `"status": "error"` ora è un errore (la v2 lo segnalava come successo). I rifiuti del cluster all'avvio/arresto di app e database arrivano come 409 `CONTAINER_ALREADY_STARTED`, `CONTAINER_ALREADY_STOPPED`, `CONTAINER_TEMPORARILY_SUSPENDED`, `CONTAINER_NOT_FOUND`, `CONTAINER_INSUFFICIENT_DISK_SPACE`, `CONTAINER_NETWORK_CONFLICT` o `ACTION_FAILED`, senza messaggio. L'SDK restituisce una risposta "already" come errore: trattala tu come successo, se necessario.
* Una risposta senza codice ha `Code` `UNKNOWN_ERROR`.
* Una chiave API scaduta produce 401 `ACCESS_DENIED`, come una sconosciuta.
* Esiste una costante `Code*` per ogni codice documentato dall'API. L'API ora invia 429 `RATE_LIMITED` (`CodeRateLimited`) dove prima inviava `RATE_LIMIT` e `RATE_LIMIT_EXCEEDED`; `CodeRateLimit` e `CodeRateLimitExceeded` restano, deprecati.
* Ogni errore di `AI.Chat` ha la forma di OpenAI con un codice minuscolo (`access_denied`, `rate_limit_exceeded`, `server_overloaded`, ...), che `Code` riporta testualmente.
* `Error()` produce `squarecloud: <METHOD> <path>: HTTP <status> <CODE>: <message>` (v2: `squarecloud: <message> (<CODE>, HTTP <status>)`). Basati sui campi, non sul testo.

Vedi [Errori](/it/sdks/go/errors) per il riferimento completo.

## Cambiamenti di comportamento

* **Chiave API vuota:** `New("")` (o una chiave composta solo da spazi) restituisce comunque un client (non può restituire un errore), ma ogni chiamata tranne `Service.Status` fallisce localmente con `INVALID_API_KEY`.
* **Snapshot 202:** la v2 restituiva un `*APIError` con `StatusCode` 202. La v3 restituisce un `SnapshotCreated` con `Pending: true` e un errore `nil`.
* **Realtime:** `Next` ora restituisce un `RealtimeEvent`. Usa uno switch su `ev.Event` (`system`, `status`, `logs`, `error`, `message`). Per i log, stampa `ev.Line` (il byte `\u0001`/`\u0002` viene rimosso; `ev.Data` resta il frame grezzo) e usa `ev.Stream` per stdout/stderr. Per lo stato, usa `ev.Status`: mai `nil` in un evento di stato, unito in modo superficiale tra frame e riconnessioni. Dopo `REALTIME_DISCONNECTED`, `Next` restituisce `io.EOF`. Il flusso non si interrompe più dopo 30 s, le riconnessioni attendono almeno 5,5 s dopo l'apertura precedente, e l'apertura è limitata dal timeout del client fino all'arrivo degli header. Vedi [Realtime](/it/sdks/go/realtime).
* **Timeout:** la v2 usava un timeout fisso di 30 s dell'`http.Client` per tutto. La v3 applica una scadenza predefinita solo quando `ctx` non ne ha una: il timeout del client (`WithTimeout`, 30 s) per la maggior parte delle chiamate; almeno 2 minuti per start/stop/restart, creazione di database, creazione/ripristino di snapshot e `AI.Chat`; nessuna per upload, scritture di file con contenuto oltre 1 MiB e download di snapshot. `WithTimeout(0)` le disattiva tutte.
* **Finestre di rete vuote:** `Analytics`, `Errors` e `Performance` restituiscono puntatori `nil` quando la finestra non ha traffico.
* **Header:** ogni richiesta all'API invia `Accept: application/json` (`text/event-stream` per il realtime). Lo `User-Agent` predefinito è cambiato da `Square GO` a `squarecloud-sdk-go/3.0.0` (`WithUserAgent` lo sostituisce ancora).
* **Id:** ogni id ora è codificato in percent-encoding come un singolo segmento del percorso (la v2 lo inseriva nel percorso così com'era), e un id vuoto, `.` o `..` fallisce localmente con `INVALID_ID`.
* **Scrittura di file:** la v2 inviava sempre il contenuto come stringa, cosa che corrompeva i file binari, e non poteva scrivere un file vuoto. La v3 invia sempre il contenuto codificato in base64, quindi ogni byte resta identico, un contenuto vuoto scrive un file vuoto e un contenuto oltre 10 MB fallisce localmente con `FILE_TOO_LARGE`. L'API risponde 400 `INVALID_CONTENT` per un contenuto che non riesce a decodificare.
* **Lettura di file:** la v3 richiede sempre base64 e lo decodifica, invece dell'array di byte JSON letto dalla v2 (che l'API ha deprecato). Un file oltre 10 MB produce 413 `FILE_TOO_LARGE`.
* **Elenco dei file:** elencare una directory che non esiste produce 404 `FILE_NOT_FOUND`; prima era un elenco vuoto.
* **Snapshot:** le voci dell'elenco contengono `VersionID` e `URL` forniti dall'API; non viene estratto nulla da `Key`.
* **Retry:** novità. Gli errori di rete delle GET, i 503 `UPLOAD_BUSY`/`ANALYTICS_BUSY` e i 503 `DATABASE_UNAVAILABLE` sulle GET vengono ripetuti due volte per impostazione predefinita; `WithMaxRetries(0)` ripristina il comportamento della v2. `DATABASE_UNAVAILABLE` può arrivare dopo che una mutazione è iniziata, quindi l'SDK non lo ripete mai sugli altri metodi; ripeti tu una mutazione idempotente, se vuoi. Vedi [Retry](/it/sdks/go/errors#retry).
* **Versione di Go:** il minimo è sceso da Go 1.24 a Go 1.22.
