curl --request GET \
--url https://api.pav.bio/v1/changes \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.pav.bio/v1/changes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.pav.bio/v1/changes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pav.bio/v1/changes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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 := "https://api.pav.bio/v1/changes"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.pav.bio/v1/changes")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pav.bio/v1/changes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": 90211,
"short_name": "pfizer",
"drug": "Danuglipron",
"change_type": "update",
"detected_at": "2026-06-19T04:12:00Z",
"company_id": 412,
"company": "Pfizer",
"indication": "Type 2 Diabetes",
"territory": "United States",
"prev_phase": "Phase 1",
"new_phase": "Phase 2",
"invalidated_at": "2026-06-20T04:12:00Z",
"invalidation_reason": "source correction"
}
],
"pagination": {
"limit": 100,
"offset": 0,
"total": 590355
},
"next_cursor": "<opaque cursor>"
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}List pipeline change events
Detected pipeline changes, newest first: a program added (insert), a program changing phase or details (update), or a program leaving a company’s pipeline (delete), timed by detected_at. Page with the returned next_cursor via ?cursor=; it stays gap-free while new changes arrive. since= bounds the start. Retracted changes are hidden unless include_invalidated=true.
curl --request GET \
--url https://api.pav.bio/v1/changes \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.pav.bio/v1/changes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.pav.bio/v1/changes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pav.bio/v1/changes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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 := "https://api.pav.bio/v1/changes"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.pav.bio/v1/changes")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pav.bio/v1/changes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": 90211,
"short_name": "pfizer",
"drug": "Danuglipron",
"change_type": "update",
"detected_at": "2026-06-19T04:12:00Z",
"company_id": 412,
"company": "Pfizer",
"indication": "Type 2 Diabetes",
"territory": "United States",
"prev_phase": "Phase 1",
"new_phase": "Phase 2",
"invalidated_at": "2026-06-20T04:12:00Z",
"invalidation_reason": "source correction"
}
],
"pagination": {
"limit": 100,
"offset": 0,
"total": 590355
},
"next_cursor": "<opaque cursor>"
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}{
"error": {
"code": "not_found",
"message": "program 999999 not found",
"request_id": "3f2b9c1d8a7e4f6b9c0d1e2f3a4b5c6d"
}
}Authorizations
Use a personal or organization Pav API key from Pav developer settings. Send it as Authorization: Bearer <api_key>.
Query Parameters
Filter to these Pav company ids. Repeatable.
412
Filter by change type: insert, update, delete. Repeatable.
insert, update, delete "update"
Only changes detected at or after this timestamp (ISO 8601).
"2026-06-01T00:00:00Z"
Include changes later retracted after a correction.
false
Opaque cursor from a prior response's next_cursor. Preferred over offset; wins when both are sent.
Maximum rows to return (1-5000).
1 <= x <= 500050
Zero-based row offset. Prefer cursor, which wins when both are sent.
0 <= x <= 20000000000
Response
Successful Response
Page of pipeline change events.
Show child attributes
Show child attributes
Pagination metadata for this page.
Show child attributes
Show child attributes
Opaque cursor to fetch the next page; pass it back as ?cursor=. Null when this page exhausts the feed. Stable under concurrent inserts (unlike offset).
"<opaque cursor>"