curl --request GET \
--url http://localhost:3000/api/changelog \
--header 'Origin: <api-key>'import requests
url = "http://localhost:3000/api/changelog"
headers = {"Origin": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Origin: '<api-key>'}};
fetch('http://localhost:3000/api/changelog', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3000",
CURLOPT_URL => "http://localhost:3000/api/changelog",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Origin: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://localhost:3000/api/changelog"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Origin", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("http://localhost:3000/api/changelog")
.header("Origin", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3000/api/changelog")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Origin"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"rows": [
{
"id": "0f3a6c1e-2b9d-4e57-8a41-6d2c9b7e5f10:0",
"appId": "324684580",
"appName": "Spotify - Music and Podcasts",
"appIconUrl": "<string>",
"appDeveloper": "Spotify Ltd.",
"scrapedAt": 1789776000000,
"source": "live",
"triggeredBy": "scheduled",
"entry": {
"type": "added",
"description": "\"Data Linked to You\" now collects: Location"
}
}
],
"total": 42
}Read the universal changelog feed
Every recorded change across all tracked apps, one row per change
entry, newest snapshot first. Only snapshots flagged as having
changes are read: label, accessibility and age-rating changes from
syncs, label changes back-filled from the Internet Archive, and
privacy-policy text changes flagged while
flag.notifications.types.policy_updates was on. Wayback import
attempts aren’t changes, so the wayback type and the
wayback-attempt category never match.
The feed reads the newest limit × 8 of those snapshots (4,000 at
most), filters their entries, then applies offset and limit. On
a long history, total counts only the entries in those snapshots,
and paging with offset stops there.
curl --request GET \
--url http://localhost:3000/api/changelog \
--header 'Origin: <api-key>'import requests
url = "http://localhost:3000/api/changelog"
headers = {"Origin": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Origin: '<api-key>'}};
fetch('http://localhost:3000/api/changelog', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3000",
CURLOPT_URL => "http://localhost:3000/api/changelog",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Origin: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://localhost:3000/api/changelog"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Origin", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("http://localhost:3000/api/changelog")
.header("Origin", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3000/api/changelog")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Origin"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"rows": [
{
"id": "0f3a6c1e-2b9d-4e57-8a41-6d2c9b7e5f10:0",
"appId": "324684580",
"appName": "Spotify - Music and Podcasts",
"appIconUrl": "<string>",
"appDeveloper": "Spotify Ltd.",
"scrapedAt": 1789776000000,
"source": "live",
"triggeredBy": "scheduled",
"entry": {
"type": "added",
"description": "\"Data Linked to You\" now collects: Location"
}
}
],
"total": 42
}Authorizations
Same-origin CSRF check. The Origin header must match the request host;
enforced for every mutating verb (POST, PUT, PATCH, DELETE).
Query Parameters
Only snapshots taken at or after this time (Unix ms).
Only snapshots taken at or before this time (Unix ms).
Only this app's changes (Apple's numeric track ID). Ignored unless
it contains only letters, digits, _ and -.
Comma-separated entry types to include: added, removed,
modified, policy, wayback. Other values are dropped, and if
none are left, every type is returned.
Comma-separated entry categories to include: privacy-label,
privacy-policy, wayback-attempt, accessibility. An entry
with no category counts as privacy-label. Other values,
age-rating included, are dropped, and if none are left, every
category is returned.
Page size. Larger values are treated as 500.
1 <= x <= 500Entries to skip from the start of the filtered list.
x >= 0