# API code examples

> Fetch top pages from the analytics API with curl, JavaScript, Python, PHP, Go and Ruby. Copy working code examples with filters, periods and a Bearer token.

Each example fetches last week's top pages. Keep your token in
`PRIVATUS_TOKEN`.

## curl

```sh
curl -G "https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/breakdown/page.json" \
  --data-urlencode "period=7d" \
  --data-urlencode "limit=20" \
  --data-urlencode 'filters=[["channel","is","organic_search"]]' \
  -H "Authorization: Bearer $PRIVATUS_TOKEN"
```

## JavaScript (Node.js 18+ or the browser's fetch on your server)

```js
const params = new URLSearchParams({
  period: '7d',
  limit: '20',
  filters: JSON.stringify([['channel', 'is', 'organic_search']]),
})
const response = await fetch(
  `https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/breakdown/page.json?${params}`,
  { headers: { Authorization: `Bearer ${process.env.PRIVATUS_TOKEN}` } },
)
if (!response.ok) throw new Error((await response.json()).error.message)
const { data } = await response.json()
for (const row of data.rows) console.log(row.value, row.pageviews)
```

Never use an API token in browser code: it would be visible to everyone.

## Python

```python
import json, os, requests

response = requests.get(
    "https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/breakdown/page.json",
    params={"period": "7d", "limit": 20,
            "filters": json.dumps([["channel", "is", "organic_search"]])},
    headers={"Authorization": f"Bearer {os.environ['PRIVATUS_TOKEN']}"},
    timeout=30,
)
response.raise_for_status()
for row in response.json()["data"]["rows"]:
    print(row["value"], row["pageviews"])
```

## PHP

```php
<?php
$query = http_build_query([
    'period' => '7d',
    'limit' => 20,
    'filters' => json_encode([['channel', 'is', 'organic_search']]),
]);
$context = stream_context_create(['http' => [
    'header' => 'Authorization: Bearer ' . getenv('PRIVATUS_TOKEN'),
]]);
$json = file_get_contents("https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/breakdown/page.json?$query", false, $context);
foreach (json_decode($json, true)['data']['rows'] as $row) {
    echo $row['value'], ' ', $row['pageviews'], PHP_EOL;
}
```

## Go

```go
q := url.Values{}
q.Set("period", "7d")
q.Set("limit", "20")
q.Set("filters", `[["channel","is","organic_search"]]`)

req, _ := http.NewRequest("GET",
	"https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/breakdown/page.json?"+q.Encode(), nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("PRIVATUS_TOKEN"))

resp, err := http.DefaultClient.Do(req)
if err != nil {
	log.Fatal(err)
}
defer resp.Body.Close()

var body struct {
	Data struct {
		Rows []struct {
			Value     string `json:"value"`
			Pageviews int    `json:"pageviews"`
		} `json:"rows"`
	} `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&body)
```

## Ruby

```ruby
require "net/http"
require "json"

uri = URI("https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/breakdown/page.json")
uri.query = URI.encode_www_form(period: "7d", limit: 20,
                                filters: [["channel", "is", "organic_search"]].to_json)
request = Net::HTTP::Get.new(uri, "Authorization" => "Bearer #{ENV.fetch('PRIVATUS_TOKEN')}")
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
JSON.parse(response.body)["data"]["rows"].each { |row| puts "#{row['value']} #{row['pageviews']}" }
```

## Writing: add a deploy note

```sh
curl -X POST https://privatusanalytics.com/sites/pa_7Q2K9XH3AB/notes.json \
  -H "Authorization: Bearer $PRIVATUS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Deployed v2.4.0", "date": "2026-09-29", "source": "deploy"}'
```

Check the [reference](/docs/api) for each operation's exact fields. The
official [SDKs](/docs/server-side/sdks) for Node.js, Python, PHP, Go and
Ruby wrap these calls too.
