curl -X GET "https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day" \
-H "Authorization: Bearer <YOUR_API_KEY>"fetch("https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day", { headers: { "Authorization": "Bearer <YOUR_API_KEY>"} })
.then(response => response.json())
.then(data => console.log(data))require('axios')
.get("https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day", { headers: { Authorization: 'Bearer <YOUR_API_KEY>' } })
.then(response => console.log(response))require 'net/http'
uri = URI("https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer <YOUR_API_KEY>"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.bodyimport requests
headers = {'Authorization': 'Bearer <YOUR_API_KEY>'}
url = "https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day"
print(requests.get(url, headers=headers).json())<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl",
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.cryptoquant.com/v2/indicator/unrealized-pnl/nupl"
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.cryptoquant.com/v2/indicator/unrealized-pnl/nupl")
.header("Authorization", "Bearer <token>")
.asString();{
"status": {
"code": 123,
"message": "<string>"
},
"result": {
"window": "<string>",
"data": [
{
"datetime": "<string>",
"blockheight": 123,
"nupl": 123,
"nup": 123,
"nul": 123
}
]
}
}NUPL
Net Unrealized Profit and Loss — the difference between market capitalization and realized capitalization as a share of market capitalization.
curl -X GET "https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day" \
-H "Authorization: Bearer <YOUR_API_KEY>"fetch("https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day", { headers: { "Authorization": "Bearer <YOUR_API_KEY>"} })
.then(response => response.json())
.then(data => console.log(data))require('axios')
.get("https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day", { headers: { Authorization: 'Bearer <YOUR_API_KEY>' } })
.then(response => console.log(response))require 'net/http'
uri = URI("https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer <YOUR_API_KEY>"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.bodyimport requests
headers = {'Authorization': 'Bearer <YOUR_API_KEY>'}
url = "https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl?asset=btc&window=day"
print(requests.get(url, headers=headers).json())<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cryptoquant.com/v2/indicator/unrealized-pnl/nupl",
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.cryptoquant.com/v2/indicator/unrealized-pnl/nupl"
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.cryptoquant.com/v2/indicator/unrealized-pnl/nupl")
.header("Authorization", "Bearer <token>")
.asString();{
"status": {
"code": 123,
"message": "<string>"
},
"result": {
"window": "<string>",
"data": [
{
"datetime": "<string>",
"blockheight": 123,
"nupl": 123,
"nup": 123,
"nul": 123
}
]
}
}What it measures
Net Unrealized Profit and Loss — the difference between market capitalization and realized capitalization as a share of market capitalization. A positive value means holders are, on aggregate, sitting on unrealized profit, which is latent selling pressure.nup and nul split it into the profit and loss sides.
📖 Data Guide: Net Unrealized Profit/Loss (NUPL) — definition, interpretation, and chart examples.
Assets and windows
| Asset class | What it covers | Assets | Windows |
|---|---|---|---|
| Bitcoin | the native asset of Bitcoin, asset=btc | btc | block · hour · day |
day.
Response fields
The time key depends on the window:datetime for day and hour and blockheight plus datetime for block.
| Field | Type | Description |
|---|---|---|
nupl | number | Net Unrealized Profit and Loss — (market_cap − realized_cap) divided by market_cap. |
nup | number | Net Unrealized Profit — for UTXOs currently in profit, the amount multiplied by the price gain since creation, summed and divided by market_cap. |
nul | number | Net Unrealized Loss — for UTXOs currently at a loss, the amount multiplied by the price drop since creation, summed and divided by market_cap. |
Authorizations
For each API request, include the Authorization HTTP header with Bearer {access_token}.
Query Parameters
Asset to query, by its CryptoQuant alias (no chain suffix — usdt, not usdt_eth). 1 asset is available on this endpoint, across the asset class btc. Enumerate them with /v2/discovery/endpoints.
Chain the asset lives on. Optional for an asset that exists on exactly one chain, required when the same alias exists on several.
bitcoin Aggregation window. Which windows are valid depends on the asset — see the endpoint page. Defaults to day.
block, hour, day Inclusive start time, YYYYMMDDTHHMMSS (UTC). If window=day, YYYYMMDD is also accepted.
Inclusive end time, YYYYMMDDTHHMMSS (UTC). If window=day, YYYYMMDD is also accepted.
Maximum rows returned (default 100, max 10000).
x <= 10000Response format: json (default) or csv.
json, csv