Migrating from v1 to v2

Enhanced features and improvements in Solana Staking Reporting API v2.

What's New in Version 2

See the comparison between v1 and v2 in the table below.

Key Pointsv1v2
NetworkMainnetMainnet
Most Recent Reward EndpointsSupportedNot Supported
Historical Reward EndpointsSupportedSupported
Status EndpointsSupportedSupported
Timezone-based ReportingNot Officially SupportedSupported

The grouping periods are calculated based on the start timestamp and the chosen period type.
Data GranularityEpochEpoch with support for individual reward types including Fee, Rent, Voting, Staking, and MEV.

It doesn't roll up per epoch at the raw level
Response FormatsAll endpoints are application/json.Most endpoints are application/x-ndjson.
Reward Period AllocationUses the start time.Uses the end time.
Reward Type BreakdownSupportedSupported
Jito MEV TrackingSupportedSupported
Reward Address MappingNot SupportedSupported
Health EndpointNot SupportedSupported
Gzip SupportNot SupportedSupported in responses only.

Let's delve into the details for each key point:

1. Most Recent Reward

➡️ v1

To get the most recent rewards, send the following request.

curl --request GET \
     --url https://svc.blockdaemon.com/reporting/staking/v1/solana/mainnet/validator/rewards/7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json'

This would return a response below.

[
  {
    "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "currency": "SOL",
    "return": "70.351448765",
    "timeStart": "2024-05-27T15:24:34Z",
    "timeEnd": "2024-05-27T15:24:34Z",
    "timeAggregation": "epoch",
    "startingBalance": "491.983642837",
    "metadata": {
      "delegationAddress": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
      "epoch": 620,
      "inflationaryRewards": "36.552373236",
      "blockFeeRewards": "33.799075529",
      "mevRewards": "0"
    }
  }
]

➡️ v2

To achieve similar functionality in v2, you would need to make a rewards request with a wide enough window to include the latest reward (end times can be in the future) and then pick the one with the highest start time.


2. Historical Reward

👍

Note:

Validators and delegators follow the same request/response format in both API versions.

The examples below are for validator requests. For delegator requests, replace "validator" with "delegator" in the URI.

➡️ v1

  1. Single Validator: Send the request below to retrieve historical rewards for a single validator.
curl --request POST \
     --url https://svc.blockdaemon.com/reporting/staking/v1/solana/mainnet/validator/history/7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "fromTime": 1678174507000,
  "toTime": 1678779307000,
  "timeUnit": "week"
}

This would return a response below.

[
  {
    "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "currency": "SOL",
    "return": "39.669796317",
    "timeStart": "2023-03-13T00:00:00Z",
    "timeEnd": "2023-03-19T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": "2155.357089892",
    "metadata": {
      "delegationAddress": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
      "epoch": 0,
      "inflationaryRewards": "39.669796317",
      "blockFeeRewards": "0",
      "mevRewards": "0"
    }
  },
  {
    "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "currency": "SOL",
    "return": "79.852583879",
    "timeStart": "2023-03-06T00:00:00Z",
    "timeEnd": "2023-03-12T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": "2075.504506013",
    "metadata": {
      "delegationAddress": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
      "epoch": 0,
      "inflationaryRewards": "79.852583879",
      "blockFeeRewards": "0",
      "mevRewards": "0"
    }
  }
]
  1. Multiple Validators: Send the request below to retrieve historical rewards for multiple validators in one request.
curl --request POST \
     --url 'https://svc.blockdaemon.com/reporting/staking/v1/solana/mainnet/validator/history?aggregate=true' \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "fromTime": 1678174507000,
  "toTime": 1678779307000,
  "timeUnit": "week",
  "addresses": [
    "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy"
  ]
}'

This would return a response below.

[
  {
    "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "currency": "SOL",
    "return": "39.669796317",
    "timeStart": "2023-03-13T00:00:00Z",
    "timeEnd": "2023-03-19T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": "2155.357089892",
    "metadata": {
      "delegationAddress": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
      "epoch": 0,
      "inflationaryRewards": "39.669796317",
      "blockFeeRewards": "0",
      "mevRewards": "0"
    }
  },
  {
    "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "currency": "SOL",
    "return": "79.852583879",
    "timeStart": "2023-03-06T00:00:00Z",
    "timeEnd": "2023-03-12T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": "2075.504506013",
    "metadata": {
      "delegationAddress": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
      "epoch": 0,
      "inflationaryRewards": "79.852583879",
      "blockFeeRewards": "0",
      "mevRewards": "0"
    }
  }
]

➡️ v2

  1. Single Validator: Send the request below to retrieve historical rewards for a single validator.
curl --location 'https://svc.blockdaemon.com/reporting/staking/v2/solana/mainnet/validator/rewards/FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571?startTime=1678174507&endTime=1678779307&period=weekly' \
--header 'Authorization: Bearer YOUR_KEY' \
--header 'accept: application/x-ndjson' 

This would return a response below.

{
  "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
  "denomination": "lamports",
  "return": "152995957268",
  "startTime": 1678174507,
  "endTime": 1678779306,
  "period": "WEEKLY",
  "startBalance": "582507713330",
  "metadata": {
    "epoch": "419-422",
    "fee": "33473577072",
    "identity": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "slot": "181226296-182498587",
    "voteKey": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "voting": "119522380196",
    "stake": "1118732553958212"
  }
}
  1. Multiple Validators: In v2, you can include a maximum of 1000 addresses per request. If you have more, you will have to make multiple requests.
curl -X 'POST' \
  'https://svc.blockdaemon.com/reporting/staking/v2/solana/mainnet/validator/rewards' \
  -H 'accept: application/x-ndjson' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '{
  "startTime": 1678174507,
  "endTime": 1678779307,
  "addresses": [
    "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571"
  ],
  "period": "weekly"
}' 

This would return a response below.

{
  "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
  "denomination": "lamports",
  "return": "152995957268",
  "startTime": 1678174507,
  "endTime": 1678779306,
  "period": "WEEKLY",
  "startBalance": "582507713330",
  "metadata": {
    "epoch": "419-422",
    "fee": "33473577072",
    "identity": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "slot": "181226296-182498587",
    "voteKey": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "voting": "119522380196",
    "stake": "1118732553958212"
  }
}

🚧

Note:

In v2, the response comes in ndjson format, so there's no wrapper JSON object. However, the above response has been formatted for better readability.


3. Status Endpoints

👍

Note:

Validators and delegators follow the same request/response format in both API versions.

The examples below are for validator requests. For delegator requests, replace "validator" with "delegator" in the URI.

➡️ v1

  1. Single Delegator: To retrieve the status of a single validator, send the request below.
curl --request GET \
     --url https://svc.blockdaemon.com/reporting/staking/v1/solana/mainnet/validator/status/7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json'

This would return a response below.

{
  "address": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
  "status": "active",
  "commission": 8,
  "activationDate": "2022-01-26"
}
  1. Multiple Delegators: To retrieve the status of multiple validators, send the request below.
curl --request POST \
     --url https://svc.blockdaemon.com/reporting/staking/v1/solana/mainnet/validator/status/ \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "addresses": [
    "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "CW9C7HBwAMgqNdXkNgFg9Ujr3edR2Ab9ymEuQnVacd1A"
  ]
}'

This would return a response below.

[
  {
    "address": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "status": "active",
    "commission": 8,
    "activationDate": "2022-01-26"
  },
  {
    "address": "CW9C7HBwAMgqNdXkNgFg9Ujr3edR2Ab9ymEuQnVacd1A",
    "status": "active",
    "commission": 8,
    "activationDate": "2023-03-13"
  }
]

➡️ v2

  1. Single Delegator: To retrieve the status of a single validator, send the request below.
curl -X 'GET' \
	'https://svc.blockdaemon.com/reporting/staking/v2/solana/mainnet/delegator/status/78NumgHAAgfaHUDPBPTyzFcSgvPnXSqqTnSmXPAW9KZW' \
	-H 'Content-Type: application/json' \
	-H 'Authorization: Bearer KEY' 

This would return a response below.

{
  "address": "78NumgHAAgfaHUDPBPTyzFcSgvPnXSqqTnSmXPAW9KZW",
  "status": "ACTIVE",
  "metadata": {
    "activationEpoch": "631",
    "deactivationEpoch": "18446744073709551615",
    "identity": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "solanaAccount": "A2VLtkfrXxBCLKUGQqwhyD5fmGSvSZpc6a8jMA78T2eL",
    "stakeAccount": "78NumgHAAgfaHUDPBPTyzFcSgvPnXSqqTnSmXPAW9KZW",
    "type": "delegator",
    "voteKey": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571"
  }
}

Below is an INACTIVE example.

curl -X 'GET' \
	'https://svc.blockdaemon.com/reporting/staking/v2/solana/mainnet/delegator/status/EzJtpdYHhHNg2b6btUEvYnF7jaW138q2USu1SJLi1SyW' \
	-H 'Content-Type: application/json' \
	-H 'Authorization: Bearer KEY' 
{
  "address": "EzJtpdYHhHNg2b6btUEvYnF7jaW138q2USu1SJLi1SyW",
  "status": "INACTIVE",
  "metadata": {
    "activationEpoch": "631",
    "deactivationEpoch": "633",
    "identity": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "solanaAccount": "A2VLtkfrXxBCLKUGQqwhyD5fmGSvSZpc6a8jMA78T2eL",
    "stakeAccount": "EzJtpdYHhHNg2b6btUEvYnF7jaW138q2USu1SJLi1SyW",
    "type": "delegator",
    "voteKey": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571"
  }
}
  1. Multiple Delegators: In v2, you can look up multiple statuses for a single validator at a time.
curl -X 'POST' \
  'https://svc.blockdaemon.com/reporting/staking/v2/solana/mainnet/validator/status' \
  -H 'accept: application/x-ndjson' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '[
  "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
  "CW9C7HBwAMgqNdXkNgFg9Ujr3edR2Ab9ymEuQnVacd1A"
]'

This would return a response below.

{
  "address": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
  "status": "ACTIVE",
  "metadata": {
    "authorisedWithdrawer": "GRKMJ1zE99jGh4SVA8HCwizVN9fL3yvr8JCCgvqUpbNv",
    "commission": "8",
    "identity": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "type": "validator",
    "voteKey": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571"
  }
}
{
  "address": "CW9C7HBwAMgqNdXkNgFg9Ujr3edR2Ab9ymEuQnVacd1A",
  "status": "ACTIVE",
  "metadata": {
    "authorisedWithdrawer": "91hLRqfYtNXQrX28eKMPZCMprZmj7o4DdwbRv5d29fiX",
    "commission": "8",
    "identity": "CW9C7HBwAMgqNdXkNgFg9Ujr3edR2Ab9ymEuQnVacd1A",
    "type": "validator",
    "voteKey": "6D2jqw9hyVCpppZexquxa74Fn33rJzzBx38T58VucHx9"
  }
}

🚧

Note:

In v2, the response comes in ndjson format, so there's no wrapper JSON object. However, the above response has been formatted for better readability.


4. Timezone-based Reporting

👍

Note:

Validators and delegators follow the same request/response format in both API versions.

The examples below are for validator requests. For delegator requests, replace "validator" with "delegator" in the URI.

➡️ v1

In v1, rewards are divided into UTC days, weeks, or months (time units), and use the millisecond timestamp to retrieve the historical stake and rewards.

curl --request POST \
     --url https://svc.blockdaemon.com/reporting/staking/v1/solana/mainnet/validator/history/7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "fromTime": 1678174507000,
  "toTime": 1678779307000,
  "timeUnit": "week"
}'

This will generate the response below, in which you must combine the two values to calculate the reward for the chosen timeframe.

[
  {
    "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "currency": "SOL",
    "return": "39.669796317",
    "timeStart": "2023-03-13T00:00:00Z",
    "timeEnd": "2023-03-19T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": "2155.357089892",
    "metadata": {
      "delegationAddress": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
      "epoch": 0,
      "inflationaryRewards": "39.669796317",
      "blockFeeRewards": "0",
      "mevRewards": "0"
    }
  },
  {
    "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "currency": "SOL",
    "return": "79.852583879",
    "timeStart": "2023-03-06T00:00:00Z",
    "timeEnd": "2023-03-12T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": "2075.504506013",
    "metadata": {
      "delegationAddress": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
      "epoch": 0,
      "inflationaryRewards": "79.852583879",
      "blockFeeRewards": "0",
      "mevRewards": "0"
    }
  }
]

➡️ v2

In v2, time units adjust automatically based on the start time and chosen time unit.

curl -X 'POST' \
  'https://svc.blockdaemon.com/reporting/staking/v2/solana/mainnet/validator/rewards' \
  -H 'accept: application/x-ndjson' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_KEY' \
  -d '{
  "startTime": 1678174507,
  "endTime": 1678779307,
  "addresses": [
    "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571"
  ],
  "period": "weekly"
}'

This will generate a response below. Please note:

  • If you need the reward data in a different timezone, convert timestamps to UTC seconds.
  • Partitions are in whole units, and daily periods cover full days regardless of end timestamp.
  • Rewards are in lamports. If you need them in SOL, you'll have to convert them.
  • startBalance is the balance of the account (or stake account for delegators) before the reward was applied for the period."
  • This response applies to delegators as well.
{
  "address": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
  "denomination": "lamports",
  "return": "283291849202",
  "startTime": 1709251200,
  "endTime": 1711929600,
  "period": "raw",
  "startBalance": "124222",
  "metadata": {
    "fee": "532626257312",
    "epoch": "1",
    "identity": "7cVfgArCheMR6Cs4t6vz5rfnqd56vZq4ndaBrY5xkxXy",
    "slot": "251296884",
    "voteKey": "FQwewNXahV7MiZcLpY6p1xhUs2acVGQ3U5Xxc7FzV571",
    "voting": "532626257312",
    "stake": "532626257312",
    "mev": "532626257312",
    "staking": "532626257312"
  }
}

🚧

Note:

In v2, the response comes in ndjson format, so there's no wrapper JSON object. However, the above response has been formatted for better readability.


5. Data Granularity

  • v1: Rewards are aggregated up to epoch level (All reward types: Fee, Rent, MEV, Voting, and Staking).
  • v2: Rewards are available at the individual level using theraw and are not currency aggregatable to an epoch level.

6. Response Formats

  • v1: All endpoints return application/json response.
  • v2: The Get Status for an Address returns application/json, the rest are all streaming responses in application/x-ndjson format.

7. Reward Period Allocation

  • v1: Rewards are allocated to partitions based on the start time.
  • v2: Rewards are allocated based on the end time (when the rewards are available). Comparing results between the two versions may show small discrepancies if a reward crosses the end timestamp boundaries.

8. Reward Type Breakdown

In both versions, rewards are broken down into constituent parts in the metadata object.

  • v1: The names in v1 are inflationRewards, blockFeeRewards, and mevRewards.
  • v2: The names in v2 are Voting/Staking (Inflation Rewards for validators/delegators), Fee, Rent, and MEV.

9. Jito MEV Tracking

Jito MEV tracking is available in both versions.

  • v1: MEV rewards are attributed to the previous payout epoch (-1). This means that rewards from a previous epoch could be updated later.
  • v2: MEV rewards are also allocated to the payout epoch. After an epoch ends, it can take between 90 and 120 minutes to process MEV rewards. If querying during this period, rewards could still change afterwards.

📘

Info:

Use the Health Endpoint to keep track of the available rewards and check processing status.


10. Reward Address Mapping

  • v1:
    ├── You must use the correct address type to get rewards (identity for validators). If the vote key is used, no data is returned.
    └── For delegators, using the Solana account would return stake account rewards without clear identification. When querying multiple addresses, there is no way to differentiate between them.
  • v2:
    ├── You can use either address type.
    └── The address mappings are available in the metadata object.

11. Health Endpoint

A health endpoint provides a high-level overview of the reward processing status. It also includes a breakdown of the status of individual reward types in the metadata object.

Below is an example request.

curl 'https://svc.blockdaemon.com/reporting/staking/v2/solana/mainnet/health' \
     -H 'Authorization: Bearer YOUR_KEY'

Below is an example response.

{
    "status": "OPTIMAL",
    "timestamp": 1716893171,
    "metadata": {
        "lastProcessedInflationEpoch": "620",
        "lastProcessedMevEpoch": "620",
        "lastProcessStatusesEpoch": "621",
        "chainEpoch": "621",
        "chainSlot": "268425883",
        "lastProcessedSlot": "268425383",
        "lastProcessedMevTxTimestamp": "1716893374"
    }
}

📘

Info:

The endpoint will return unknown if queried before 2024/06/03.


12. GZIP Support

  • v1: Gzip is not supported.
  • v2: Gzip is supported on responses via the Accept-Encoding header.

👋 Need Help?

Contact us through email or our support page for any issues, bugs, or assistance you may need.