Migrating Ethereum from v1 to v2

How to upgrade from Ethereum API v1 to v2 and access new features and better performance

What's New in Version 2

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

Key Pointsv1v2
NetworkMainnet
Holesky
Mainnet
Holesky
Most Recent Reward EndpointsSupportedSubscribe to the Get a Stream of Rewards endpoint to receive updates on rewards for the most recent epoch.
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 GranularityDayEpoch
Response FormatsAll endpoints are application/jsonMost endpoints are application /nd+json
Reward period allocationUses the start timeUses the end time
Reward Type BreakdownSupportedSupported
Health EndpointUnsupportedSupported
Gzip supportUnsupportedSupported in Responses but not requests
Reward Address MappingUnsupportedTo be added in next release

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

1. Most Recent Reward

➡️ v1

You can use the following request to get the most recent rewards in v1.

curl --request GET \
     --url https://svc.blockdaemon.com/reporting/staking/v1/ethereum/mainnet/validator/rewards/0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b \
     --header 'X-API-Key: YOUR_API_KEY' \
     --header 'accept: application/json'
{
  "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
  "currency": "ETH",
  "return": 0.002086863,
  "timeStart": "2024-07-14T00:00:00Z",
  "timeEnd": "2024-07-14T23:59:59Z",
  "timeAggregation": "daily",
  "startingBalance": 32.006875496,
  "metadata": {
    "validatorIndex": 900000,
    "protocolRewards": 0.002086863,
    "txFeeRewards": 0,
    "mevRewards": 0
  }
}

➡️ v2

Most recent rewards are not supported.

Use the Get a Stream of Rewards endpoint to achieve the latest reward (end times can be in the future) and then select the one with the highest start time.


2. Historical Reward

➡️ 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/ethereum/mainnet/validator/history/0x86adfc13bdea31694d6ca9af586aeb58abab13fe2fefaee6f1b310d4eed9fa89b56c68ea48095fc33945ad53b7cb6e09 \
     --header 'X-API-Key: YOUR_API_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "fromTime": 1678174507000,
  "toTime": 1678779307000,
  "timeUnit": "week"
}
[
  {
    "address": "0x86adfc13bdea31694d6ca9af586aeb58abab13fe2fefaee6f1b310d4eed9fa89b56c68ea48095fc33945ad53b7cb6e09",
    "currency": "ETH",
    "return": 0.020075043,
    "timeStart": "2023-03-13T00:00:00Z",
    "timeEnd": "2023-03-19T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": 32.876963807,
    "metadata": {
      "validatorIndex": 384626,
      "protocolRewards": 0.020075043,
      "txFeeRewards": 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/ethereum/mainnet/validator/history?aggregate=false' \
     --header 'X-API-Key: YOUR_API_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "fromTime": 1678174507000,
  "toTime": 1678779307000,
  "timeUnit": "week",
  "addresses": [
    "0x86adfc13bdea31694d6ca9af586aeb58abab13fe2fefaee6f1b310d4eed9fa89b56c68ea48095fc33945ad53b7cb6e09",
    "0x94e195aa05f8bef0eba38dca31a4d91bc5adb3522936ca46397dbb30a0a9660f9d5d295909379e835a524204bf328124"
  ]
}
[
  {
    "address": "0x86adfc13bdea31694d6ca9af586aeb58abab13fe2fefaee6f1b310d4eed9fa89b56c68ea48095fc33945ad53b7cb6e09",
    "currency": "ETH",
    "return": 0.020075043,
    "timeStart": "2023-03-13T00:00:00Z",
    "timeEnd": "2023-03-19T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": 32.876963807,
    "metadata": {
      "validatorIndex": 384626,
      "protocolRewards": 0.020075043,
      "txFeeRewards": 0,
      "mevRewards": 0
    }
  },
  {
    "address": "0x94e195aa05f8bef0eba38dca31a4d91bc5adb3522936ca46397dbb30a0a9660f9d5d295909379e835a524204bf328124",
    "currency": "ETH",
    "return": 0.020039794,
    "timeStart": "2023-03-13T00:00:00Z",
    "timeEnd": "2023-03-19T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": 32.151495605,
    "metadata": {
      "validatorIndex": 503798,
      "protocolRewards": 0.020039794,
      "txFeeRewards": 0,
      "mevRewards": 0
    }
  }
...
]

➡️ v2

  1. Single Validator: Send the request below to retrieve historical rewards for a single validator.
curl --request GET \
     --url 'https://svc.blockdaemon.com/reporting/staking/v2/ethereum/mainnet/validator/rewards/0x821dcb238db02d80a16f20c585027dd8e2390de32062f8e14f41d5236c4e520acf6e920e05435bc144c6d84b8b6debef?startTime=1705321035&endTime=1721045835&period=monthly&denomination=wei' \
     --header 'X-API-Key: YOUR_API_KEY' \
     --header 'accept: application/x-ndjson'
{
    "address": "0x821dcb238db02d80a16f20c585027dd8e2390de32062f8e14f41d5236c4e520acf6e920e05435bc144c6d84b8b6debef",
    "denomination": "wei",
    "return": "234992641843725404",
    "startTime": 1710505035,
    "endTime": 1713183434,
    "period": "MONTHLY",
    "startBalance": "32007042885000000000",
    "metadata": {
        "attestationReward": "66144485000000000",
        "blockFeeReward": "74040431334628186",
        "blockReward": "75359369000000000",
        "deposits": "0",
        "epoch": "270002-276976",
        "index": "1111111",
        "mevBlockReward": "93488787843725404",
        "syncCommitteeReward": "0",
        "withdrawals": "148393011000000000"
    }
}
  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 --request POST \
     --url https://svc.blockdaemon.com/reporting/staking/v2/ethereum/mainnet/validator/rewards \
     --header 'X-API-Key: YOUR_API_KEY' \
     --header 'accept: application/x-ndjson' \
     --header 'content-type: application/json' \
     --data '
{
  "period": "monthly",
  "aggregate": false,
  "denomination": "wei",
  "startTime": 1705321035,
  "endTime": 1721045835,
  "addresses": [
    "0x821dcb238db02d80a16f20c585027dd8e2390de32062f8e14f41d5236c4e520acf6e920e05435bc144c6d84b8b6debef",
    "0x94e195aa05f8bef0eba38dca31a4d91bc5adb3522936ca46397dbb30a0a9660f9d5d295909379e835a524204bf328124"
  ]
}
{
    "address": "0x821dcb238db02d80a16f20c585027dd8e2390de32062f8e14f41d5236c4e520acf6e920e05435bc144c6d84b8b6debef",
    "denomination": "wei",
    "return": "318928536974103175",
    "startTime": 1718453835,
    "endTime": 1721045834,
    "period": "MONTHLY",
    "startBalance": "32000395040000000000",
    "metadata": {
        "attestationReward": "62611391000000000",
        "blockFeeReward": "129202199596089150",
        "blockReward": "90303270000000000",
        "deposits": "0",
        "epoch": "290702-297451",
        "index": "1111111",
        "mevBlockReward": "166013875974103175",
        "syncCommitteeReward": "0",
        "withdrawals": "146345876000000000"
    }
},
{
    "address": "0x94e195aa05f8bef0eba38dca31a4d91bc5adb3522936ca46397dbb30a0a9660f9d5d295909379e835a524204bf328124",
    "denomination": "wei",
    "return": "482986473605710553",
    "startTime": 1718453835,
    "endTime": 1721045834,
    "period": "MONTHLY",
    "startBalance": "32008742252000000000",
    "metadata": {
        "attestationReward": "62887184000000000",
        "blockFeeReward": "29046463042561149",
        "blockReward": "45391673000000000",
        "deposits": "0",
        "epoch": "290702-297451",
        "index": "503798",
        "mevBlockReward": "45635112605710553",
        "syncCommitteeReward": "329072504000000000",
        "withdrawals": "56462504000000000"
    }
}
...

🚧

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

➡️ v1

  1. Single Validator: To retrieve the status of a single validator, send the request below.
curl --request GET \
     --url https://svc.blockdaemon.com/reporting/staking/v1/ethereum/mainnet/validator/status/0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b \
     --header 'X-API-Key: YOUR_KEY\
     --header 'accept: application/json'
{
  "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
  "status": "active_ongoing",
  "index": 900000,
  "earliestReportDate": "2023-09-17"
}
  1. Multiple Validators: To retrieve the status of multiple validators, send the request below.
curl --request POST \
     --url https://svc.blockdaemon.com/reporting/staking/v1/ethereum/mainnet/validator/status/ \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "addresses": [
 "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
    "0xb80ebfdf6479ab4dcdbe249bc38bf5bda8721c193d01e696cfe7c0699343c9471770d1c627ba2a7a154872a3fea4f489"
  ]
}'
[
  {
    "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
    "status": "active_ongoing",
    "index": 900000,
    "earliestReportDate": "2023-09-17"
  },
  {
    "address": "0xb80ebfdf6479ab4dcdbe249bc38bf5bda8721c193d01e696cfe7c0699343c9471770d1c627ba2a7a154872a3fea4f489",
    "status": "withdrawal_done",
    "index": 1000001,
    "earliestReportDate": "2023-11-02"
  }
...
]

➡️ v2

  1. Single Validator: For a validator, you have to include the address that you want the status for. You can use the validator's contract address or owner's address.
curl -X 'GET' \
  'https://svc.blockdaemon.com/reporting/staking/v2/ethereum/mainnet/validator/status/0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b' \
  -H 'accept: application/json' \
  -H 'X-API-Key: YOUR_TOKEN'
{
  "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
  "status": "ACTIVE",
  "timestamp": 1720713431,
  "metadata": {
    "balance": "32002014036",
    "index": "900000",
    "rawStatus": "active_ongoing"
  }
}
  1. Multiple Validators: 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/ethereum/mainnet/validator/status' \
  -H 'accept: application/x-ndjson' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -d '[
"0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
    "0xb80ebfdf6479ab4dcdbe249bc38bf5bda8721c193d01e696cfe7c0699343c9471770d1c627ba2a7a154872a3fea4f489"
]'
{
  "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
  "status": "ACTIVE",
  "timestamp": 1720713815,
  "metadata": {
    "balance": "32002023516",
    "index": "900000",
    "rawStatus": "active_ongoing"
  }
}
{
  "address": "0xb80ebfdf6479ab4dcdbe249bc38bf5bda8721c193d01e696cfe7c0699343c9471770d1c627ba2a7a154872a3fea4f489",
  "status": "WITHDRAWAL",
  "timestamp": 1720713815,
  "metadata": {
    "balance": "0",
    "index": "1000001",
    "rawStatus": "withdrawal_done"
  }
}

🚧

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

➡️ v1

In v1, rewards are divided into UTC days, weeks, or months (time units).

Send the request below if you want see the rewards starting/ending at a different time zone

curl --request POST \
     --url https://svc.blockdaemon.com/reporting/staking/v1/ethereum/mainnet/validator/history/0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b", \
     --header 'X-API-Key: YOUR_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
    "fromTime": 1704067200000,
    "toTime": 1706745600000,
    "timeUnit": "week"
}

You would get a response like this.

[
  {
    "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
    "currency": "ETH",
    "return": 0.015644999,
    "timeStart": "2024-01-01T00:00:00Z",
    "timeEnd": "2024-01-07T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": 32.005909078,
    "metadata": {
      "validatorIndex": 900000,
      "protocolRewards": 0.015644999,
      "txFeeRewards": 0,
      "mevRewards": 0
    }
  },
  {
    "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
    "currency": "ETH",
    "return": 0.015622414,
    "timeStart": "2024-01-08T00:00:00Z",
    "timeEnd": "2024-01-14T23:59:59Z",
    "timeAggregation": "weekly",
    "startingBalance": 32.004129776,
    "metadata": {
      "validatorIndex": 900000,
      "protocolRewards": 0.015622414,
      "txFeeRewards": 0,
      "mevRewards": 0
    }
  }
...
]

➡️ v2

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

Handling Different Timezones

When working with reward data in UTC, you need to convert your local timestamps to UTC seconds before making a request.

  1. Identify your local timezone (e.g., CET).
  2. Determine your local start and end times. For example, you need data from 00:00 to 00:00 in CET.
  3. Convert your local times to UTC. For CET (UTC+1), subtract 1 hour to get the UTC times.
  4. Change the UTC times to Unix timestamps (seconds since epoch). The API requires this format.
  5. If your end timestamp is within a day, remember that the returned data will include the full day but only up to the specified end timestamp.

👍

Note:

You can use the Epoch Converter tool for the conversion.

Example Request

curl 'https://svc.blockdaemon.com/reporting/staking/v2/ethereum/mainnet/validator/rewards' \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{
    "startTime": 1704067200,
    "endTime": 1706745600,
    "period": "weekly",
    "addresses": [
        "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b"
    ]
}'

Rewards are in wei. If you need them in ETH, you'll have to convert them.

{
  "address": "0x8ddf644ab0079a9231a8605db7f72078dc4e5704340e2b6cb6380a187f83c55a943babb814eac7663f7aadb19e47a89b",
  "denomination": "wei",
  "return": "15754903000000000",
  "startTime": 1705276800,
  "endTime": 1705881599,
  "period": "WEEKLY",
  "startBalance": "32002305852000000000",
  "metadata": {
    "attestationReward": "15754903000000000",
    "blockFeeReward": "0",
    "blockReward": "0",
    "deposits": "0",
    "epoch": "256387-257961",
    "index": "900000",
    "mevBlockReward": "0",
    "syncCommitteeReward": "0",
    "withdrawals": "17435894000000000"
  }
}

5. Data Granularity

  • v1: Rewards are aggregated up to UTC day level.
  • v2: Rewards are available at the epoch level using theepoch.

6. Response Formats

  • v1: All endpoints return application/json response.
  • v2: Most endpoints return application/x-ndjson, while the "GET single status" endpoint returnsapplication/json.

7. Reward Period Allocation

The way rewards are allocated depends on whether the API uses the start time or the end time of an epoch. In this section, we’ll explain how reward allocation works in two versions of the API.

➡️ v1

In v1, rewards are allocated based on when an epoch starts. This means that the reward for an epoch is assigned to the day it starts.

How it works

  • If you query rewards for a specific day, the API returns rewards for any epoch that started on that day.
  • The end time of the epoch does not affect the reward allocation.

Example

For a query on the 6th of the month:

  • Epoch 1 starts at 8:00 PM on the 5th and ends at 8:10 PM on the 6th.
    This epoch would not be included in the rewards for the 6th, because it started on the 5th.
  • Epoch 2 starts at 12:30 AM on the 6th and ends at 12:40 AM on the 6th.
    This epoch would be included in the rewards for the 6th, as it started on the 6th.

➡️ v2

In v2, rewards are allocated based on when an epoch ends. The API will only include rewards for epochs that end during the period you specify. This approach reflects rewards based on when the activity is fully completed to give a more accurate match to daily totals.

How it works

If you query rewards for a specific day, the API returns rewards for any epoch that ended on that day.

Example

For a UTC day query on the 11th of the month:

  • Epoch 1 starts at 11:57 PM on the 10th and ends at 12:03 AM on the 11th.
    This epoch will be included in the rewards for the 11th, because it ended on the 11th.
  • Epoch 2 starts at 11:57 PM on the 11th and ends at 12:03 AM on the 12th.
    This epoch will not be included in the rewards for the 11th, because it ended on the 12th

👍

Info:

If you need rewards in a specific time zone, v2 lets you set your preferred time zone and the API will adjust the data accordingly. See this section.


8. Reward Type Breakdown

Rewards are categorized differently between v1 and v2, but both versions break down the rewards into specific components in the metadata object.

➡️ v1

The reward components are protocolReward, txFeeRewards, and mevRewards.

➡️ v2

  1. Consensus layer rewards - These are payments of newly minted ETH to validators for performing duties that maintain network security and consensus. These duties include:
    • Attestation (attestationReward): Validators receive rewards for attesting to the validity of blocks. These rewards are predictable and occur once per epoch.
    • Block proposal (blockReward): Validators earn rewards for proposing new blocks, incentivizing their participation in network maintenance.
    • Sync committee participation (syncCommitteeReward): Validators earn rewards for participating in the sync committee.
  2. Execution layer rewards - These include transaction fees and Maximal Extractable Value (MEV) rewards.
    • Transaction fees (blockFeeReward): Validators earn a share of the gas fees from user transactions included in the blocks they propose.
    • MEV rewards (mevBlockReward): Validators earn MEV rewards when they propose a block.

9. Health Endpoint

In v2, a health endpoint provides a high-level overview of the reward processing status. The metadata object also includes a breakdown of the status of individual reward types.

Below is an example request.

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

The response shows whether the reward processing is running optimally or not.

{
  "status": "OPTIMAL",
  "timestamp": 1720715486,
  "metadata": {
    "chainEpoch": "296590",
    "lastProcessedEpoch": "296589"
  }
}

📘

Info:

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


10. 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.