Getting Started

Staking Data API provides methods to retrieve essential information about network, about validators and delegators within the network.

To start using Staking Data API, get an authentication token.

The section provides the examples of how to interact with the API for Ethereum data.

Using curl commands

Request examples are provided using cURL.

To demonstrate the API usage scenarios, the examples cover:

  • retrieving the last staking period,
  • fetching active stakes for validators,
  • checking validator states,
  • obtaining rewards by type.

Get Last Staking Period

To retrieve the last staking period, send a GET request to /api/v1/{network}/data/network/last-staking-period.

Example request:

curl --request GET \
    --url https://api.p2p.org/api/v1/ethereum/data/network/last-staking-period \
    --header 'accept: application/json' \
    --header 'authorization: Bearer <token>'

Example response:

{
  "result": {
    "period": 244333,
    "updatedAt": "2023-08-24T08:23:18.830Z"
  },
  "error": {}
}
  • period — last staking period.
  • updatedAt — timestamp of the last update to the queue.

Get Delegator Stake

To fetch an active stake for each validator, send a GET request to /api/v1/{network}/data/delegator/stakes. Note that there is a list of additional query params.

Example request:

curl --request GET \
    --url 'https://api.p2p.org/api/v1/ethereum/data/delegator/stakes?startNumber=298991&finishNumber=298991&limit=1000&address=0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb&addressType=deposit' \
    --header 'accept: application/json' \
    --header 'authorization: Bearer <token>'

  • startNumber — start number of the staking period.
  • finishNumber — finish number of the staking period.
  • limit — number of resources that a single response page contains.
  • address — delegator address in the required network.
  • addressType — delegator address type in the required network:
    • deposit — available for the Ethereum network (used by default).
    • withdrawal — available for the Ethereum network.
    • delegator — available for the Polygon, Solana, Cosmos, and Sui networks (used by default).
    • stake_account — available for the Solana.
    • nominator — available for the Polkadot network (used by default).
    • nominator_reward_account — available for the Polkadot network.

Example response:

{
  "result": {
    "limit": 50,
    "offset": 0,
    "list": [
      {
        "stakingPeriod": 298991,
        "stakingPeriodStart": "2023-11-01T06:43:17.000Z",
        "stakingPeriodEnd": "2020-11-01T07:12:27.000Z",
        "stake": 1.82282,
        "validator": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
      }
    ]
  },
  "error": {}
}
  • limit — number of resources that a single response page contains, the default value is 50.
  • offset — number of resources to exclude from the beginning of a response.
  • list:
    • stakingPeriod — number of the staking period.
    • stakingPeriodStart — timestamp of the staking period start in the ISO 8601 format.
    • stakingPeriodEnd — timestamp of the staking period finish in the ISO 8601 format.
    • stake — total stake balance of the delegator.
    • validator — validator address.

Get Validator State and Statuses

To retrieve validator state, send a GET request to /api/v1/{network}/data/validator/state.

Example request:

curl --request GET \
    --url 'https://api.p2p.org/api/v1/ethereum/data/validator/state?address=0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17' \
    --header 'accept: application/json' \
    --header 'authorization: Bearer <token>'
  • address — validator address in the required network. For the Ethereum network, it is a public validator key.

Example response:

{
  "result": {
    "state": "string",
    "activatedAt": "string",
    "activatedStakingPeriodNum": 0
  },
  "error": {}
}
  • state — validator state.
  • activatedAt — timestamp of the validator activated date in the ISO 8601 format.
  • activatedStakingPeriodNum — timestamp of the validator activated staking period.

You can also retrieve the information about validator statuses by sending a GET request to /api/v1/{network}/data/validator/statuses .

Example request:

curl --request GET \
     --url https://api.p2p.org/api/v1/ethereum/data/validator/statuses \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <token>'

Example response:

{
  "result": {
    "total": 3,
    "by_status": [
      {
        "pending_initialized": 0,
        "pending_queued": 0,
        "active_ongoing": 2,
        "active_slashed": 0,
        "exited_unslashed": 0,
        "exited_slashed": 0,
        "withdrawal_possible": 1,
        "withdrawal_done": 0
      }
    ]
  },
  "error": {}
}
  • total — total count of validators.
  • by_status:
    • pending_initialized — number of validators which are initialized but not yet in the queue for activation.
    • pending_queued — number of validators that entered a queue for activation.
    • active_ongoing — number of validators that were activated and currently participate in attesting and proposing blocks.
    • active_slashed — number of validators that were slashed due to misbehaviors.
    • exited_unslashed — number of validators that have exited the network without being slashed and are no longer acting as validators.
    • exited_slashed — number of validators that have exited the network after being slashed and are no longer acting as validators.
    • withdrawal_possible — number of validators having a non-zero balance.
    • withdrawal_done — number of validators completed the withdrawal process.

Get Delegator Rewards

To fetch a list of delegators rewards by type, send a GET request to /api/v1/{network}/data/delegator/rewards. Note that there is a list of additional query params, e.g., grouping the data by date.

Example request:

curl --request GET \
     --url 'https://api.p2p.org/api/v1/ethereum/data/delegator/rewards?startAt=2024-07-01T00%3A00%3A00&finishAt=2024-07-23T00%3A00%3A00&limit=100&address=0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb&addressType=deposit&groupBy=day' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <token>'
  • startAt — timestamp of the report data period start in the ISO 8601 format. If not specified, the default value is the one month ago.
  • finishAt — timestamp of the report data period finish in the ISO 8601 format. If not specified, the default value is the current date.
  • limit — number of resources that a single response page contains; from 1 to 1000.
  • address — delegator address in the required network.
  • addressType — delegator address type in the required network:
    • deposit — available for the Ethereum network (used by default).
    • withdrawal — available for the Ethereum network.
    • delegator — available for the Polygon, Solana, Cosmos, and Sui networks (used by default).
    • stake_account — available for the Solana.
    • nominator — available for the Polkadot network (used by default).
    • nominator_reward_account — available for the Polkadot network.
  • validatorAddress — validator address in the required network for this delegator.
  • groupBy — group the output data:
    • stakingPeriod — aggregate the results by epoch.
    • day — aggregate the results by days.
    • all — aggregate the results over the entire period.

Example response:

{
  "result": {
    "limit": 50,
    "offset": 0,
    "list": [
      {
        "stakingPeriod": 298991,
        "stakingPeriodStart": "2023-11-01T06:43:17.000Z",
        "stakingPeriodEnd": "2020-11-01T07:12:27.000Z",
        "rewards": [
          {
            "type": "consensus",
            "amount": 0.63722,
            "currency": "ETH",
            "recipient": "string"
          }
        ]
      }
    ]
  },
  "error": {}
}


        "validator": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
  • limit — number of resources that a single response page contains.
  • offset — number of resources to exclude from the beginning of a response.
  • list:
    • stakingPeriod — number of the staking period.
    • stakingPeriodStart — timestamp of the staking period start in the ISO 8601 format.
    • stakingPeriodEnd — timestamp of the staking period finish in the ISO 8601 format.
    • rewards:
      • type — rewards type: consensus or execution.
      • amount — amount of tokens in the stake.
      • currency — currency of the tokens.
      • recipient — rewards recipient address.

Using Python code

This section demonstrates how to use Python with the Staking Data API. The examples for Ethereum data cover:

  • fetching the delegator daily rewards,
  • retrieving the summary for a delegator and validator.

Get Delegator Rewards

To fetch the daily rewards for a delegator, use the following code with the API endpoint /api/v1/{network}/data/delegator/rewards:

import requests
import datetime
import pickle

# API endpoint.
API_URL = 'https://api.p2p.org/api/v1/ethereum/data/delegator/rewards'

# Include your Bearer token for authentication and specify the delegator address.
ACCESS_TOKEN = 'YOUR_ACCESS_TOKEN'
DELEGATOR_ADDRESS = 'DELEGATOR_ADDRESS'

def fetch_rewards_for_date(session, date, address):
    """Fetch rewards for a specific date."""
    params = {
        'startAt': date.strftime('%Y-%m-%dT00:00:00') ,# Start time in the ISO 8601 format for each day.
        'finishAt': (date + datetime.timedelta(days=1)).strftime('%Y-%m-%dT00:00:00'), # Finish time in the ISO 8601 format for the next day.
        'limit': 1000, # Number of resources per page; the default value is 1000.
        'offset': 0, # Number of resources to exclude from the beginning; the default value is 0.
        'address': address, # Delegator address in the Ethereum network.
        'addressType': 'deposit', # Delegator address type in the required network. For Ethereum it can be `deposit` or `withdrawal`.
        'skip': 'validator', # Excludes breakdown by validator from the data report. To include validator, specify the empty value.
        'groupBy': 'stakingPeriod' # Group the results by `stakingPeriod`, `day` or `all` (the entire period).
    }
    
    rewards = []
    while True:
        try:
            response = session.get(API_URL, params=params)
            response.raise_for_status()
            result = response.json()
            new_rows = result.get('result', {}).get('list', [])
            
            if new_rows:
                rewards.extend(new_rows)
                params['offset'] += 1000
            else:
                break
        
        except requests.RequestException as e:
            print(f"An error occurred: {e}")
            break
    
    return rewards

def main():
    # Setup session
    session = requests.Session()
    session.headers.update({'Authorization': f'Bearer {ACCESS_TOKEN}'})
    
    # Define date range
    start_date = datetime.date(year=2024, month=1, day=1)
    end_date = datetime.date.today()
    date_range = (start_date + datetime.timedelta(days=d) for d in range((end_date - start_date).days + 1))
    
    all_rewards = []
    
    # Fetch rewards for each date
    for date in date_range:
        print(f"Fetching rewards for {date}")
        daily_rewards = fetch_rewards_for_date(session, date, DELEGATOR_ADDRESS)
        all_rewards.extend(daily_rewards)
    
    # Save rewards to file
    with open('dump.pkl', 'wb') as file:
        pickle.dump(all_rewards, file)
    
    # Calculate total amount
    total_amount = sum(reward['amount'] for epoch in all_rewards for reward in epoch.get('rewards', []))
    
    print(f"Total Amount: {total_amount}")

if __name__ == '__main__':
    main()

This script gathers daily rewards data from a start date to the current date, saves the data to a file, and calculates the total rewards amount.

Get Delegator Summary

To fetch the lifetime stake, rewards, and APY for a delegator, use the following code with the API endpoint /api/v1/{network}/data/delegator/summary:

import requests

# API endpoint.
url = "https://api.p2p.org/api/v1/{network}/data/delegator/summary"

# Include your Bearer token for authentication.
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

# Specify the following parameters:
params = {
    "address": "0x338EF19fA2eC0fc4d1277B1307a613fA1FBbc0cb", # Delegator address.
    "addressType": "deposit", # Delegator address type in the required network. For Ethereum it can be `deposit` or `withdrawal`.
    "network": "ethereum",  # Network name.
    "startAt": "2024-04-17T15:00:00.000Z",  # Report data start time in the ISO 8601 format.
    "finishAt": "2024-04-19T15:00:00.000Z",  # Report data finish time in the ISO 8601 format.
    "groupBy": "all",  # Aggregate the results by `stakingPeriod` or `day`. To aggregate the results for the entire period, set `all`.
    "skip": "validator"  # Exclude breakdown by validator from the report. To include validators in the output, remove the parameter or pass an empty value.
}

try:
    # Make the request.
    response = requests.get(url.format(network=params["network"]), headers=headers, params=params)
    
    # Check the response status.
    response.raise_for_status()
    
    # Parse the JSON response.
    data = response.json()
    
    # Check if the response contains data.
    if data and "result" in data:
        print("Delegator Summary:")
        print("APY:", data["result"]["list"][0]["apy"])
        print("Stake:", data["result"]["list"][0]["stake"], data["result"]["list"][0]["currency"])
        print("Rewards:")
        for reward in data["result"]["list"][0]["rewards"]:
            print("Type:", reward["type"])
            print("Amount:", reward["amount"], reward["currency"])
            print("---")
    else:
        print("Empty response received.")
        
except requests.exceptions.HTTPError as http_err:
    print(f"HTTP error occurred: {http_err}")
except requests.exceptions.RequestException as req_err:
    print(f"Request exception occurred: {req_err}")
except ValueError as val_err:
    print(f"Value error occurred: {val_err}")
except Exception as err:
    print(f"Other error occurred: {err}")

Example output (with breaking down the result by validators):

APY: 1638378.514999824
Stake: 1411 ETH
Rewards: 
  Type: consensus
  Amount: 5.195236601009028 ETH
  ---
  Type: execution
  Amount: 1.188704036616951 ETH
  ---
  • APY — delegator annual percentage yield (APY).
  • Stake — total stake balance of the delegator.
  • Rewards:
    • Type — rewards type: consensus or execution.
    • Amount — amount of tokens in the stake.

Get Validator Summary

To retrieve the validator summary, use the following code with the API endpoint /api/v1/{network}/data/validator/summary:

import requests

# API endpoint.
url = "https://api.p2p.org/api/v1/{network}/data/validator/summary"

# Include your Bearer token for authentication.
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

# Specify the following parameters:
params = {
    "address": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",  # Validator address in the required network. For the Ethereum network, it is a public validator key.
    "network": "ethereum",  # Network name.
    "startAt": "2024-04-17T15:00:00.000Z",  # Report data start time in the ISO 8601 format.
    "finishAt": "2024-04-19T15:00:00.000Z",  # Report data finish time in the ISO 8601 format.
    "limit": 50,  # Number of resources that a single response page contains; the default value is 50.
    "offset": 0  # Number of resources to exclude from the beginning of a response; the default value is 0.
}

try:
    # Make the request.
    response = requests.get(url.format(network=params["network"]), headers=headers, params=params)

    # Check the response status.
    response.raise_for_status()

    # Parse the JSON response.
    data = response.json()

    # Check if the response contains data.
    if data and "result" in data:
        validator_summary = data["result"]

        # Print the validator summary information.
        print("Validator Summary:")
        print("---")

        # Iterate over each item in the list.
        for item in validator_summary["list"]:
            print("Staking Period:", item["stakingPeriod"])
            print("Start:", item["stakingPeriodStart"])
            print("End:", item["stakingPeriodEnd"])
            print("APY:", item["apy"])
            print("Stake:", item["stake"], "ETH")

            # Print the rewards information.
            print("Rewards:")
            for reward in item["rewards"]:
                print("Amount:", reward["amount"], reward["currency"])
            print("---")

    else:
        print("Empty response received.")

except requests.exceptions.HTTPError as http_err:
    print(f"HTTP error occurred: {http_err}")
except requests.exceptions.RequestException as req_err:
    print(f"Request exception occurred: {req_err}")
except ValueError as val_err:
    print(f"Value error occurred: {val_err}")
except Exception as err:
    print(f"Other error occurred: {err}")

Example output (without breaking down the results by validators):

Validator Summary:
---
Staking Period: 277903
Start: 2024-04-19 14:59:35
End: 2024-04-19 15:05:59
APY: 0.024850512
Stake: 32.01709 ETH
Rewards:
  Amount: 9.683e-06 ETH
  ---
  Staking Period: 277902
  Start: 2024-04-19 14:53:11
  End: 2024-04-19 14:59:35
  APY: 0.024770953
  Stake: 32.01708 ETH
  Rewards:
  Amount: 9.652e-06 ETH
  ---
  • Staking Period — number of the staking period.
  • Start and End — timestamp of the staking period start and finish in the ISO 8601 format.
  • APY — validator annual percentage yield (APY).
  • Stake — total stake balance of the validator.
  • Rewards:
    • Amount — amount of tokens in the stake.

What's Next?