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

# Network & edge

> Manage custom domains, DNS, edge analytics, error tracking, request logs, latency percentiles and cache invalidation for website applications.

<Note>
  The endpoints on this page apply only to **website applications** — apps with a web domain. Calling them on a non-web application fails.
</Note>

```go theme={null}
client := rest.NewClient(os.Getenv("SQUARECLOUD_API_KEY"))
defer client.Close()

api := rest.New(client)
```

## Custom domain

`api.SetApplicationCustomDomain(appID, domain)` sets the custom domain bound to the website.

```go theme={null}
err := api.SetApplicationCustomDomain("abc123def456abc123def456", "yoursite.com")
if err != nil {
	panic(err)
}
```

## DNS records

After attaching a custom domain you need to configure DNS at your registrar. `api.GetApplicationDNS(appID)` returns the records to create as a `[]squarecloud.DNSRecord`.

```go theme={null}
records, err := api.GetApplicationDNS("abc123def456abc123def456")
if err != nil {
	panic(err)
}

for _, record := range records {
	fmt.Printf("%s %s → %s (%s)\n", record.Type, record.Name, record.Value, record.Status)
}
```

| Field    | Type     | Description                                                                                                                                 |
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `Type`   | `string` | `"txt"` or `"cname"` — TXT records cover ownership and SSL validation; the CNAME carries traffic and always points at `cname.squareweb.app` |
| `Name`   | `string` | Record name to create                                                                                                                       |
| `Value`  | `string` | Record value                                                                                                                                |
| `Status` | `string` | Validation state: `"pending"`, `"pending_validation"` or `"active"`                                                                         |

## Analytics

`api.GetApplicationAnalytics(appID, start, end)` returns aggregated edge analytics for the given window as a `squarecloud.NetworkAnalytics`. The window is required, and the maximum retention is **7 days**.

```go theme={null}
end := time.Now()
start := end.Add(-24 * time.Hour)

analytics, err := api.GetApplicationAnalytics("abc123def456abc123def456", start, end)
if err != nil {
	panic(err)
}

fmt.Println(len(analytics.Visits), "time buckets") // 15-minute series
fmt.Println(analytics.Countries)
fmt.Println(analytics.Paths)
```

The response carries 15-minute time series (`Visits`, `Countries`, `Devices`, `OS`, `Browsers`, `Protocols`, `Methods`, `Paths`, `Referers`, `Providers`) and whole-window buckets (`IPs`, `StatusCodes`, `Bots`, `ContentTypes`).

<Note>
  For a window entirely before the application was created, the API returns an empty object — every slice in the response is `nil`. Check lengths before indexing.
</Note>

### Drill-down filters

Beyond the window, the endpoint accepts optional filters as query parameters — pass them with `rest.WithQueryParam`. Each filter narrows every breakdown in the response at once:

| Filter         | Notes                                           |
| -------------- | ----------------------------------------------- |
| `country`      | 2-letter country code, e.g. `"BR"`              |
| `ip`           | Exact IP match                                  |
| `path`         | Prefix match, e.g. `"/api"`                     |
| `status`       | HTTP status code, e.g. `"404"`                  |
| `os`           | Operating system                                |
| `browser`      | Browser name                                    |
| `protocol`     | Request protocol                                |
| `referer`      | Use `"Direct"` for requests with no referer     |
| `provider`     | Network provider, e.g. `"GOOGLE (15169)"` (ASN) |
| `content_type` | Use `"Unknown"` for unclassified content types  |
| `bot`          | Use `"Unverified"` for normal (non-bot) traffic |

```go theme={null}
analytics, err := api.GetApplicationAnalytics(
	"abc123def456abc123def456",
	start, end,
	rest.WithQueryParam("country", "BR"),
	rest.WithQueryParam("status", "404"),
	rest.WithQueryParam("bot", "Unverified"),
)
```

## Error tracking

`api.GetApplicationNetworkErrors(appID, start, end)` returns the edge error breakdown. By default only 5xx errors are included — add `include_4xx=true` to include 4xx.

```go theme={null}
errs, err := api.GetApplicationNetworkErrors(
	"abc123def456abc123def456",
	start, end,
	rest.WithQueryParam("include_4xx", "true"),
)
if err != nil {
	panic(err)
}
```

## Per-request logs

`api.GetApplicationNetworkLogs(appID, start, end)` returns the per-request edge logs.

```go theme={null}
logs, err := api.GetApplicationNetworkLogs("abc123def456abc123def456", start, end)
if err != nil {
	panic(err)
}
```

<Note>
  Per-request logs require a [Pro plan](https://squarecloud.app/plans) or higher.
</Note>

## Latency percentiles

`api.GetApplicationNetworkPerformance(appID, start, end)` returns p50 / p95 / p99 latencies for the edge and origin layers.

```go theme={null}
perf, err := api.GetApplicationNetworkPerformance("abc123def456abc123def456", start, end)
if err != nil {
	panic(err)
}
```

<Note>
  Performance metrics require a [Pro plan](https://squarecloud.app/plans) or higher.
</Note>

## Purging the edge cache

`api.PurgeApplicationCache(appID)` invalidates the entire edge cache for the application's domains.

```go theme={null}
err := api.PurgeApplicationCache("abc123def456abc123def456")
if err != nil {
	panic(err)
}
```

## Account-wide domains and load balancers

These two methods operate across every application in the account rather than a single website.

### Listing every domain

`api.GetApplicationDomains()` returns every domain configured across all of the account's applications as a `[]squarecloud.AppDomain`. Custom domains are listed first; applications without a web domain are omitted.

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

for _, domain := range domains {
	fmt.Println(domain.AppID, domain.Hostname, domain.Type) // "subdomain" | "custom"
}
```

### Load balancers

`api.GetLoadBalancers()` groups applications that share a custom domain, returning a `squarecloud.LoadBalancers`.

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

fmt.Println("plan limit:", lb.Limit)
for _, balancer := range lb.Balancers {
	fmt.Println(balancer.Hostname, len(balancer.Apps), "apps")
}
```

A group with 2 or more apps is an active load balancer: traffic is balanced at the edge with automatic failover when one of the apps is offline. `Limit` is the maximum number of applications that can share one domain on the account's plan: 2 (Standard), 5 (Pro), 10 (Enterprise).
