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

# Migrando para a v3

> O que mudou entre o SDK Go v2 e v3: um único pacote, um *Client concreto, ctx como primeiro argumento, grupos de recursos, um único tipo de erro, timeouts e novas tentativas. Uma tabela método a método.

A v3 é uma versão com breaking changes. Ela usa um único pacote, um `*Client` concreto, `ctx` como primeiro argumento em todo lugar e grupos de recursos, e corrige todos os bugs conhecidos da v2. Ela cobre todas as 67 operações da API atual.

## Visão geral

|                  | v2                                                        | v3                                                                                                  |
| ---------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Módulo           | `.../v2` (pacotes `rest` + `squarecloud`)                 | `github.com/squarecloudofc/sdk-api-go/v3` (um único pacote)                                         |
| Cliente          | `rest.New(rest.NewClient(key, ...))` (interface)          | `squarecloud.New(key, ...Option)` (`*Client`)                                                       |
| Chamadas         | `api.GetApplicationStatus(id, rest.WithContext(ctx))`     | `c.Apps.Status(ctx, id)`                                                                            |
| Erros            | `*rest.APIError` com `StatusCode`, erros de rede sem tipo | `*squarecloud.APIError` com `Status`, `Code`, `Message`, `Method`, `Path` para tudo                 |
| Timeouts         | `http.Client` com um `Timeout` fixo de 30 s em tudo       | Por chamada via `ctx`; `WithTimeout`; streams sem limite                                            |
| Novas tentativas | Nenhuma                                                   | Erros de rede em GET e 503 `UPLOAD_BUSY`/`ANALYTICS_BUSY`/`DATABASE_UNAVAILABLE` (`WithMaxRetries`) |
| Logs             | `WithLogger` (vazava segredos)                            | Nenhum                                                                                              |
| Go               | 1.24                                                      | 1.22 ou superior                                                                                    |
| Licença          | AGPL-3.0                                                  | MIT                                                                                                 |

## Construção e opções

```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                                                                                                                |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Pacotes `rest` + `squarecloud`                        | Um único pacote `squarecloud` (módulo `.../v3`)                                                                   |
| `rest.NewClient(token, opts...)` + `rest.New(client)` | `squarecloud.New(token, opts...)`                                                                                 |
| `rest.Rest` (interface)                               | `*squarecloud.Client` (struct concreta). Para fazer mock, declare sua própria interface pequena ou use `httptest` |
| `rest.ConfigOpt`                                      | `squarecloud.Option`                                                                                              |
| `rest.WithHTTPClient(hc)`                             | `squarecloud.WithHTTPClient(hc)`. Não defina `hc.Timeout`: ele cortaria streams de realtime e downloads           |
| `rest.WithURL(u)`                                     | `squarecloud.WithBaseURL(u)` (ainda inclui `/v2`)                                                                 |
| `rest.WithUserAgent(ua)`                              | `squarecloud.WithUserAgent(ua)`                                                                                   |
| `rest.WithLogger(l)`                                  | Removido: o SDK nunca gera logs (a v2 vazava segredos nos logs de debug). Envolva `hc.Transport` para rastrear    |
| `client.Close()`, `client.HTTPClient()`               | Removidos: mantenha seu próprio `*http.Client` e chame `CloseIdleConnections` nele                                |
| `rest.APIURL`, `rest.APIVersion`, `rest.Endpoint*`    | Removidos; `squarecloud.DefaultBaseURL` é uma constante                                                           |
| (nenhum)                                              | `squarecloud.WithMaxRetries(n)` (novo; padrão 2)                                                                  |
| Timeout fixo de 30 s no `http.Client`                 | `squarecloud.WithTimeout(d)` (novo; padrão 30 s, `d <= 0` desativa todos os prazos padrão)                        |

Opções por requisição:

| v2                                                                                      | v3                                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rest.WithContext(ctx)`                                                                 | `ctx` é o primeiro argumento de todo método                                                                                                                                                        |
| `rest.WithToken(token)` (por exemplo, para validar uma chave no login)                  | Crie um cliente descartável: `squarecloud.New(token).Account.Me(ctx)` (barato, nenhuma conexão é mantida)                                                                                          |
| `rest.WithQueryParam("path", dir)` no commit                                            | `c.Apps.Commit(ctx, id, r, dir, "")`                                                                                                                                                               |
| `rest.WithQueryParam(filter, v)` nos analytics                                          | `c.Apps.Network.Analytics(ctx, id, start, end, squarecloud.AnalyticsFilters{...})` com `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)` no status da lista                             | `c.Apps.StatusAll(ctx, ws)`                                                                                                                                                                        |
| `rest.WithHeader`, `rest.RequestOpt`, `rest.RequestConfig`, `rest.DefaultRequestConfig` | Removidos                                                                                                                                                                                          |

## Método a método

`api` é o `rest.Rest` da v2, `c` o `*squarecloud.Client` da v3.

| v2                                                                                        | v3                                                                                                                  | Observações                                                                                                                                                                                                                                                                                              |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `api.SelfUser()`                                                                          | `me, err := c.Account.Me(ctx)`, depois `me.User`                                                                    | Retorna `Account`                                                                                                                                                                                                                                                                                        |
| `api.GetApplications()`                                                                   | `c.Account.Me(ctx)`, depois `me.Applications` (`[]AppSummary`)                                                      |                                                                                                                                                                                                                                                                                                          |
| `api.GetDatabases()`                                                                      | `c.Account.Me(ctx)`, depois `me.Databases` (`[]DatabaseSummary`)                                                    |                                                                                                                                                                                                                                                                                                          |
| `api.UserSnapshots(scope)`                                                                | `c.Account.Snapshots(ctx, scope)`                                                                                   |                                                                                                                                                                                                                                                                                                          |
| `api.ServiceStatus()`                                                                     | `c.Service.Status(ctx)`                                                                                             | Novo modelo, veja [Tipos](#tipos)                                                                                                                                                                                                                                                                        |
| `api.PostApplications(r)` → `*ApplicationUploaded`                                        | `c.Apps.Create(ctx, r)` → `AppCreated` (um valor)                                                                   | A v2 armazenava o zip em memória e nomeava a parte como `upload.zip`; a v3 o transmite em stream e nomeia a parte a partir de um `*os.File` (seu nome base), senão `app.zip`. `Subdomain` não existe mais: leia `Domain`, o host completo (`my-app.squareweb.app`), `""` para aplicações que não são 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)`                                                                            | A v2 sempre nomeava a parte como `commit.zip`; a v3 usa `filename`, senão o próprio nome de um `*os.File`, então um único arquivo que não é zip agora vai para o seu próprio nome em vez de falhar como zip                                                                                              |
| `api.GetApplicationStatus(id)`                                                            | `c.Apps.Status(ctx, id)`                                                                                            |                                                                                                                                                                                                                                                                                                          |
| `api.GetApplicationStatusRaw(id)`                                                         | `c.Apps.StatusRaw(ctx, id)`                                                                                         |                                                                                                                                                                                                                                                                                                          |
| `api.GetApplicationListStatus()`                                                          | `c.Apps.StatusAll(ctx, "")`                                                                                         | Retorna `[]StatusListItem`                                                                                                                                                                                                                                                                               |
| `api.GetApplicationLogs(id)` → `ApplicationLogs`                                          | `c.Apps.Logs(ctx, id)` → `string`                                                                                   |                                                                                                                                                                                                                                                                                                          |
| `api.GetApplicationMetrics(id)`                                                           | `c.Apps.Metrics(ctx, id)`                                                                                           | Os pontos vêm do mais recente para o mais antigo, como a API os envia                                                                                                                                                                                                                                    |
| `api.ApplicationRealtime(id, rest.WithContext(ctx))`                                      | `c.Apps.Realtime(ctx, id)`                                                                                          | Retorna `*Realtime`; veja [Mudanças de comportamento](#mudanças-de-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)` (as variáveis restantes)                                |                                                                                                                                                                                                                                                                                                          |
| `api.GetApplicationFiles(id, path)` → `[]FileInfo`                                        | `c.Apps.Files.List(ctx, id, path)` → `[]FileEntry`                                                                  | Um diretório inexistente agora resulta em 404 `FILE_NOT_FOUND` (antes era uma lista vazia); um caminho protegido resulta em 403 `BLOCKED_PATH`                                                                                                                                                           |
| `api.ReadApplicationFile(id, path)` → `FileContent`                                       | `c.Apps.Files.Read(ctx, id, path)` → `[]byte`                                                                       | Solicitado em base64 e decodificado; um arquivo acima de 10 MB resulta em 413 `FILE_TOO_LARGE`                                                                                                                                                                                                           |
| `api.PutApplicationFile(id, path, b)` → `(FileWritten, error)`                            | `c.Apps.Files.Write(ctx, id, path, b)` → `error`. Remova qualquer verificação de `written`: sucesso é um erro `nil` | O conteúdo é sempre enviado codificado em base64, então arquivos binários são seguros; conteúdo vazio escreve um arquivo vazio                                                                                                                                                                           |
| `api.MoveApplicationFile(id, from, to)`                                                   | `c.Apps.Files.Move(ctx, id, path, to)`                                                                              |                                                                                                                                                                                                                                                                                                          |
| `api.DeleteApplicationFile(id, path)`                                                     | `c.Apps.Files.Delete(ctx, id, path)`                                                                                | Agora funciona (sempre retornava 400 na v2)                                                                                                                                                                                                                                                              |
| `api.GetApplicationSnapshots(id)`                                                         | `c.Apps.Snapshots.List(ctx, id)`                                                                                    | Cada `Snapshot` agora traz `VersionID` e `URL` (link de download assinado) vindos da API                                                                                                                                                                                                                 |
| `api.CreateApplicationSnapshot(id)`                                                       | `c.Apps.Snapshots.Create(ctx, id)`                                                                                  | Verifique `.Pending` (202) antes de usar `.URL`                                                                                                                                                                                                                                                          |
| `api.RestoreApplicationSnapshot(id, snapID, verID)`                                       | `c.Apps.Snapshots.Restore(ctx, id, snap.Name, snap.VersionID)`                                                      | `VersionID` é um campo que a API envia: nada mais precisa ser extraído de `Key`. Veja [Snapshots](/pt-br/sdks/go/snapshots#restaurando-um-snapshot) para os erros                                                                                                                                        |
| `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`                                          | Chaves de API agora funcionam (escopo `apps:deploy`); o wrapper `repository` não existe mais; uma conta sem GitHub conectado resulta em 403 `GITHUB_NOT_CONNECTED`                                                                                                                                       |
| `api.UnlinkApplicationGithubApp(id)`                                                      | `c.Apps.Deploys.UnlinkGithubApp(ctx, id)`                                                                           | 400 `GIT_NOT_CONFIGURED` sem um vínculo                                                                                                                                                                                                                                                                  |
| `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{...})`                                        | Retorna `*NetworkAnalytics`, `nil` para uma janela sem tráfego                                                                                                                                                                                                                                           |
| `api.GetApplicationNetworkErrors(id, s, e, opts...)`                                      | `c.Apps.Network.Errors(ctx, id, s, e, include4xx)`                                                                  | Retorna `*NetworkErrors`, `nil` quando vazio                                                                                                                                                                                                                                                             |
| `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)`                                                                         | Retorna `*NetworkPerformance`, `nil` quando vazio                                                                                                                                                                                                                                                        |
| `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)`                                                                                        | Retorna `[]StatusListItem`                                                                                                                                                                                                                                                                               |
| `api.GetDatabaseMetrics(id)`                                                              | `c.Databases.Metrics(ctx, id)`                                                                                      |                                                                                                                                                                                                                                                                                                          |
| `api.GetDatabaseCertificate(id)` → `DatabaseCertificate`                                  | `c.Databases.Certificate(ctx, id)` → `string` (PEM em base64)                                                       |                                                                                                                                                                                                                                                                                                          |
| `api.ResetDatabaseCredentials(id, t)` → `DatabasePasswordReset`                           | `c.Databases.ResetCredentials(ctx, id, t)` → `string`                                                               | A nova senha, `""` para resets de certificado                                                                                                                                                                                                                                                            |
| `api.GetDatabaseSnapshots` / `CreateDatabaseSnapshot` / `RestoreDatabaseSnapshot`         | `c.Databases.Snapshots.List` / `Create` / `Restore`                                                                 | Como nas aplicações: restaure com `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`                                                                    |                                                                                                                                                                                                                                                                                                          |
| Baixar você mesmo a URL de um snapshot (`http.Get`)                                       | `c.DownloadSnapshot(ctx, url, w)`                                                                                   | Transmite para qualquer `io.Writer`; nunca envia a chave                                                                                                                                                                                                                                                 |
| `rest.IsRateLimit(err)`                                                                   | `errors.As(err, &apiErr) && apiErr.Status == 429`                                                                   | Removido                                                                                                                                                                                                                                                                                                 |
| `rest.ErrorCode(err)`                                                                     | `errors.As(err, &apiErr)`, depois `apiErr.Code`                                                                     | Removido                                                                                                                                                                                                                                                                                                 |
| `client.Request(...)`, `client.Stream(...)` (`rest.Client`)                               | Os métodos tipados acima                                                                                            | Removidos: toda operação tem seu próprio método                                                                                                                                                                                                                                                          |
| `rest.NewApplications(client)`, `rest.NewDatabases(client)`, `rest.NewWorkspaces(client)` | `squarecloud.New(key)`, depois os campos `c.Apps`, `c.Databases`, `c.Workspaces`                                    | Removidos                                                                                                                                                                                                                                                                                                |
| `rest.Applications`, `rest.Databases`, `rest.Workspaces` (interfaces)                     | `squarecloud.AppsAPI`, `DatabasesAPI`, `WorkspacesAPI` (os tipos desses campos)                                     | Removidos; declare sua própria interface para fazer mock                                                                                                                                                                                                                                                 |
| `rest.Config`, `rest.DefaultConfig()`, `(*rest.Config).Apply(opts)`                       | `squarecloud.New(key, opts...)` com `WithHTTPClient`, `WithBaseURL`, `WithUserAgent`                                | Removidos (use `Option`; não há logger)                                                                                                                                                                                                                                                                  |
| `(*rest.RequestConfig).Apply(opts)`                                                       | Passe `ctx` e argumentos tipados                                                                                    | Removido                                                                                                                                                                                                                                                                                                 |
| `(*rest.RealtimeStream).Next()` / `Close()`                                               | `(*squarecloud.Realtime).Next()` / `Close()`                                                                        | `Next` retorna `io.EOF` após `REALTIME_DISCONNECTED`                                                                                                                                                                                                                                                     |
| (nenhum)                                                                                  | `c.AI.Chat(ctx, squarecloud.ChatRequest{...})`                                                                      | Novo                                                                                                                                                                                                                                                                                                     |

## Tipos

| v2 (`squarecloud.`)                                                                                                                                         | v3 (`squarecloud.`)                                                                                                                                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `User` (de `SelfUser`)                                                                                                                                      | `User` (dentro de `Account`, o resultado de `Account.Me`)                                                                                                                                                                                                                |
| `UserPlan`, `UserPlanMemory`                                                                                                                                | `Plan`, `PlanMemory`. `Plan.Duration` é a expiração em **milissegundos** Unix (`*int64`, `nil` quando nunca expira): converta-a com `time.UnixMilli`, não com `time.Unix`                                                                                                |
| `UserApplication`, `UserDatabase` (`Type string`)                                                                                                           | `AppSummary`, `DatabaseSummary` (`Type DatabaseType`)                                                                                                                                                                                                                    |
| `Application`                                                                                                                                               | `App`                                                                                                                                                                                                                                                                    |
| `ApplicationUploaded` (`CPU int`), `ApplicationLanguage`                                                                                                    | `AppCreated` (`CPU float64`), `AppLanguage`                                                                                                                                                                                                                              |
| `ApplicationStatus`, `DatabaseStatus`                                                                                                                       | `RuntimeStats` (compartilhado)                                                                                                                                                                                                                                           |
| `ApplicationStatusRaw`, `DatabaseStatusRaw`                                                                                                                 | `RuntimeStatsRaw`                                                                                                                                                                                                                                                        |
| `ApplicationStatusNetwork`, `ApplicationStatusNetworkRaw`                                                                                                   | `StatsNetwork`, `StatsNetworkRaw`                                                                                                                                                                                                                                        |
| `ApplicationStatusListItem`, `DatabaseStatusListItem`                                                                                                       | `StatusListItem`                                                                                                                                                                                                                                                         |
| `ApplicationLogs`                                                                                                                                           | `string`                                                                                                                                                                                                                                                                 |
| `ApplicationSignal*`                                                                                                                                        | Removido (use `Start`/`Stop`/`Restart`)                                                                                                                                                                                                                                  |
| `FileInfo` (`Type FileType`, `LastModified int64`), constantes `FileType*`                                                                                  | `FileEntry` (`Type string`, `LastModified *float64`): `"file"`/`"directory"`; a API envia Unix ms fracionário, ou `null`                                                                                                                                                 |
| `FileContent`, `ByteArray`                                                                                                                                  | `[]byte`                                                                                                                                                                                                                                                                 |
| `FileWritten`                                                                                                                                               | Removido (campo não documentado)                                                                                                                                                                                                                                         |
| `Deployment` (`State DeploymentState`)                                                                                                                      | `DeployEvent` (`State`, `Source`, `Code`, `Message` como `string`). `Source` é novo, sempre `"git"`; um evento `"error"` traz `Code`, por exemplo `CLONE_FAILED`, e às vezes `Message`                                                                                   |
| `DeploymentState*` (`DeploymentStateError` = `"error"`)                                                                                                     | Constantes string `Deploy*` (`DeployPending`, `DeployClone`, `DeployCommit`, `DeployRestarting`, `DeploySuccess`, `DeployError` = `"error"`)                                                                                                                             |
| `DeploymentFiles`, `DeploymentCurrent`, `DeploymentGithubApp`                                                                                               | `DeployFiles`, `DeployCurrent`, `DeployRepository`                                                                                                                                                                                                                       |
| `GithubWebhook`                                                                                                                                             | `string`                                                                                                                                                                                                                                                                 |
| `GithubAppLink`, `GithubAppRepository`                                                                                                                      | `LinkedRepository` com `ID`, `FullName`, `Branch` (retornado diretamente, sem o wrapper `Repository`)                                                                                                                                                                    |
| `Snapshot`                                                                                                                                                  | `Snapshot` + `VersionID`, `URL`, `Runtime`, `Origin` (todos os campos que a API envia)                                                                                                                                                                                   |
| `SnapshotCreated`                                                                                                                                           | `SnapshotCreated` + `Pending`                                                                                                                                                                                                                                            |
| `DatabaseType` com `DatabaseTypeMongo`, `DatabaseTypeMySQL`, `DatabaseTypeRedis`, `DatabaseTypePostgres`                                                    | `DatabaseType` (inalterado) com `DatabaseMongo`, `DatabaseMySQL`, `DatabaseRedis`, `DatabasePostgres` (constantes renomeadas)                                                                                                                                            |
| `DatabaseCreateOptions`, `DatabaseUpdateOptions`                                                                                                            | `DatabaseCreate`, `DatabaseUpdate`                                                                                                                                                                                                                                       |
| `DatabaseCreated` (`CPU int`, `Certificate string`)                                                                                                         | `DatabaseCreated` (`CPU float64`, `Certificate *string`, `nil` quando a API não envia nenhum)                                                                                                                                                                            |
| `DatabaseResetType`, `DatabaseResetPassword`, `DatabaseResetCertificate`                                                                                    | `DatabaseReset`, `ResetPassword`, `ResetCertificate`                                                                                                                                                                                                                     |
| `DatabaseCertificate`, `DatabasePasswordReset`                                                                                                              | `string`                                                                                                                                                                                                                                                                 |
| `WorkspaceMemberGroup`, `WorkspaceGroup*`                                                                                                                   | Entrada: `WorkspaceGroup` (`GroupAdmin`, `GroupMaintain`, `GroupManager`, `GroupView`); `WorkspaceMember.Group` é uma `string` (pode ser `"owner"`)                                                                                                                      |
| `WorkspaceMember` (`Name string`)                                                                                                                           | `WorkspaceMember` (`Name *string`, `nil` quando a API envia `null`). Os ids de workspace têm 32 ou 40 caracteres hexadecimais                                                                                                                                            |
| `WorkspaceInviteCode`                                                                                                                                       | `string`                                                                                                                                                                                                                                                                 |
| `ServiceStatus` (`Status`, `Message`)                                                                                                                       | `ServiceStatus` (`Status`, `Message`, `CheckedAt`, `Stale`, `Services`, `Dependencies`). `Status` agora é, por exemplo, `"online"`; as entradas são `ServiceEntry`                                                                                                       |
| `rest.RealtimeStream`                                                                                                                                       | `*squarecloud.Realtime` (`Next`, `Close`)                                                                                                                                                                                                                                |
| `RealtimeEvent` (`Event`, `Data`)                                                                                                                           | `RealtimeEvent` (`Event`, `Data`, `ID`, `Stream`, `Line`, `Status`)                                                                                                                                                                                                      |
| Opções de query nos analytics                                                                                                                               | `AnalyticsFilters` (sem `Start`/`End`: eles são argumentos)                                                                                                                                                                                                              |
| `NetworkErrorsSummaryClass` (`Class4xx`, `Class5xx`)                                                                                                        | `NetworkErrorsSummary.ByClass`, um `map[string]int64` com as chaves `"4xx"` e `"5xx"`                                                                                                                                                                                    |
| `NetworkErrorsByStatus`, `NetworkErrorsTimeseries`, `NetworkErrorsTopPath`, `NetworkErrorsByMethod`                                                         | `NetworkErrorsStatus`, `NetworkErrorsBucket`, `NetworkErrorsPath`, `NetworkErrorsMethod`                                                                                                                                                                                 |
| `NetworkLatency`, `NetworkPerformance*`                                                                                                                     | `Percentiles` (`P50`/`P95`/`P99` são `*float64`, `nil` para uma janela sem requisições), `PerformanceSummary`, `PerformanceBucket`, `PerformanceRegion` (países e colos; `P50`/`P95` `*float64`, `City`/`Country` `*string`), `PerformancePath` (`P95`/`P99` `*float64`) |
| `RealtimeStatus`                                                                                                                                            | `RealtimeStatus.CPULimit` é um número de núcleos (por exemplo, `1`, `0.5`)                                                                                                                                                                                               |
| Valores de provider nos analytics                                                                                                                           | `"NAME (ASN)"` (por exemplo, `"GOOGLE (15169)"`); `AnalyticsFilters.Provider` recebe exatamente esse valor                                                                                                                                                               |
| `AppDomainType*`                                                                                                                                            | `AppDomain.Type` é uma `string`                                                                                                                                                                                                                                          |
| `APIResponse[T]`                                                                                                                                            | Removido (interno)                                                                                                                                                                                                                                                       |
| Tamanhos e contadores `int` (`FileInfo.Size`, `Snapshot.Size`, `Visits`/`Requests` dos analytics, totais e maps de erros de rede, `Requests` de desempenho) | `int64`                                                                                                                                                                                                                                                                  |

## Erros

`rest.APIError` (`StatusCode`, `Code`, `Message`) passa a ser `squarecloud.APIError` (`Status`, `Code`, `Message`, `Method`, `Path`): renomeie `StatusCode` para `Status`. `rest.ErrorCode(err)` e `rest.IsRateLimit(err)` foram removidos: use `errors.As` e verifique `Code` ou `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
}
```

* Falhas de rede agora são `*APIError` com `Status` `0`, `Code` `NETWORK_ERROR` ou `TIMEOUT` e o texto da causa como `Message`, e fazem unwrap para a causa (`errors.Is(err, context.Canceled)` funciona).
* O mesmo vale para as verificações locais (`Status` `0`: `INVALID_ID`, `FILE_TOO_LARGE`, `INVALID_API_KEY`) e para um corpo 2xx que não é JSON (`UNKNOWN_ERROR`, `Invalid JSON in HTTP <status> response`).
* Um corpo 2xx que diz `"status": "error"` agora é um erro (a v2 o reportava como sucesso). As recusas do cluster ao iniciar/parar aplicações e bancos de dados chegam como 409 `CONTAINER_ALREADY_STARTED`, `CONTAINER_ALREADY_STOPPED`, `CONTAINER_TEMPORARILY_SUSPENDED`, `CONTAINER_NOT_FOUND`, `CONTAINER_INSUFFICIENT_DISK_SPACE`, `CONTAINER_NETWORK_CONFLICT` ou `ACTION_FAILED`, sem mensagem. O SDK retorna uma resposta "já" como erro: trate-a como sucesso por conta própria se precisar.
* Uma resposta sem código tem `Code` `UNKNOWN_ERROR`.
* Uma chave de API expirada resulta em 401 `ACCESS_DENIED`, como uma desconhecida.
* Há uma constante `Code*` para cada código que a API documenta. A API agora envia 429 `RATE_LIMITED` (`CodeRateLimited`) onde enviava `RATE_LIMIT` e `RATE_LIMIT_EXCEEDED`; `CodeRateLimit` e `CodeRateLimitExceeded` continuam existindo, depreciados.
* Todo erro de `AI.Chat` segue o formato da OpenAI, com um código em minúsculas (`access_denied`, `rate_limit_exceeded`, `server_overloaded`, ...), que `Code` carrega literalmente.
* `Error()` gera `squarecloud: <METHOD> <path>: HTTP <status> <CODE>: <message>` (v2: `squarecloud: <message> (<CODE>, HTTP <status>)`). Compare pelos campos, não pelo texto.

Veja [Erros](/pt-br/sdks/go/errors) para a referência completa.

## Mudanças de comportamento

* **Chave de API vazia:** `New("")` (ou uma chave composta apenas de espaços) ainda retorna um cliente (ele não pode retornar um erro), mas toda chamada, exceto `Service.Status`, falha localmente com `INVALID_API_KEY`.
* **Snapshot 202:** a v2 retornava um `*APIError` com `StatusCode` 202. A v3 retorna um `SnapshotCreated` com `Pending: true` e um erro `nil`.
* **Realtime:** `Next` agora retorna um `RealtimeEvent`. Faça um switch em `ev.Event` (`system`, `status`, `logs`, `error`, `message`). Para logs, imprima `ev.Line` (o byte `\u0001`/`\u0002` é removido; `ev.Data` permanece o frame bruto) e use `ev.Stream` para stdout/stderr. Para status, use `ev.Status`: nunca `nil` em um evento de status, mesclado superficialmente entre frames e reconexões. Após `REALTIME_DISCONNECTED`, `Next` retorna `io.EOF`. O stream não morre mais após 30 s, as reconexões esperam pelo menos 5,5 s após a abertura anterior, e a abertura é limitada pelo timeout do cliente até os headers chegarem. Veja [Tempo real](/pt-br/sdks/go/realtime).
* **Timeouts:** a v2 usava um timeout fixo de 30 s no `http.Client` para tudo. A v3 aplica um prazo padrão apenas quando o `ctx` não tem nenhum: o timeout do cliente (`WithTimeout`, 30 s) para a maioria das chamadas; pelo menos 2 minutos para start/stop/restart, criação de bancos de dados, criação/restauração de snapshots e `AI.Chat`; nenhum para uploads, escritas de arquivos com mais de 1 MiB de conteúdo e downloads de snapshots. `WithTimeout(0)` desativa todos eles.
* **Janelas de rede vazias:** `Analytics`, `Errors` e `Performance` retornam ponteiros `nil` quando a janela não tem tráfego.
* **Headers:** toda requisição à API envia `Accept: application/json` (`text/event-stream` para realtime). O `User-Agent` padrão mudou de `Square GO` para `squarecloud-sdk-go/3.0.0` (`WithUserAgent` ainda o substitui).
* **Ids:** todo id agora é codificado com percent-encoding como um único segmento de caminho (a v2 o colava no caminho como estava), e um id vazio, `.` ou `..` falha localmente com `INVALID_ID`.
* **Escrita de arquivos:** a v2 sempre enviava o conteúdo como string, o que corrompia arquivos binários, e não conseguia escrever um arquivo vazio. A v3 sempre envia o conteúdo codificado em base64, então todo byte chega intacto, conteúdo vazio escreve um arquivo vazio, e conteúdo acima de 10 MB falha localmente com `FILE_TOO_LARGE`. A API responde 400 `INVALID_CONTENT` para conteúdo que não consegue decodificar.
* **Leitura de arquivos:** a v3 sempre solicita base64 e o decodifica, em vez do array de bytes JSON que a v2 lia (que a API depreciou). Um arquivo acima de 10 MB resulta em 413 `FILE_TOO_LARGE`.
* **Listagem de arquivos:** listar um diretório que não existe resulta em 404 `FILE_NOT_FOUND`; antes era uma lista vazia.
* **Snapshots:** as entradas da listagem trazem `VersionID` e `URL` vindos da API; nada é extraído de `Key`.
* **Novas tentativas:** novidade. Erros de rede em GET, 503 `UPLOAD_BUSY`/`ANALYTICS_BUSY` e 503 `DATABASE_UNAVAILABLE` em GET são tentados novamente duas vezes por padrão; `WithMaxRetries(0)` restaura o comportamento da v2. `DATABASE_UNAVAILABLE` pode chegar depois que uma mutação já começou, então o SDK nunca o repete em outros métodos; repita uma mutação idempotente por conta própria se quiser. Veja [Novas tentativas](/pt-br/sdks/go/errors#novas-tentativas).
* **Versão do Go:** o mínimo caiu do Go 1.24 para o Go 1.22.
