API Reference
DocumentationLog In

Advanced API quickstart: Get transaction history for an Ethereum address

The Node Advanced API allows you to simplify and optimize common types of Ethereum requests.
This API supplements the basic Ethereum node JSON-RPC API, available from any Ethereum node provider, so you can make fewer API calls to get the data you want, and more easily develop on the blockchain.

In this tutorial you will get the full transaction history for a user address including external, internal, token, ERC-20 and ERC-721 token transfers in a single request.

Why get address transaction history?

  • Display a user's full transaction history
  • Query an address's transactions filtered by smart contract interactions
  • Analyze a user's historical profit and loss

Prerequisites

⚠️

If you're using a Windows machine as your dev environment, you can run through this tutorial as-written by using Windows Subsystem for Linux

Create a project and get API keys

To get started using the Coinbase Node Advanced API, sign in to your Coinbase Cloud account:

Sign in to Coinbase Cloud Console screenSign in to Coinbase Cloud Console screen

Create project

After you sign in you'll be prompted to set up your first project.

Select the Free plan and enter a name for your project.

Create a project screenCreate a project screen

Get API keys

After creating a project, you will receive the following API access credentials:

  • API Access Token Username (e.g. username)

  • API Access Token Password (e.g. password)

    API token modalAPI token modal

Copy and save these API access credentials to a secure location. You will need them later in order to make API requests.

⚠️

You can return to the project dashboard to retrieve your endpoint and username, however your password is not saved.

If you lose your project password, you will need to create a new project.

Once your project is created, you can visit the dashboard to view other information, such as the endpoint (https://mainnet.ethereum.coinbasecloud.net).

Empty projectEmpty project

Make a request and process the response

Now, you will use the information you copied to make a request to the Advanced APIs.

Make request

Open your terminal and run the following command, replacing <username>, and <password> with the values you copied from the previous step:

curl https://mainnet.ethereum.coinbasecloud.net/ \
  -u <username>:<password> \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{
  "method": "coinbaseCloud_getTransactionsByAddress",
  "params": {
    "address": "0x3cd751e6b0078be393132286c442345e5dc49699",
    "blockStart": "0xe6e8f1",
    "blockEnd": "0xe6f4d6",
    "addressFilter": "RECEIVER_ONLY",
    "blockchain": "Ethereum",
    "network":"Mainnet"
  },
  "id": 1,
  "jsonrpc": "2.0"
}'

This call to getTransactionsByAddress specifies:

ParamValueRequiredExplanation
address"0x3cd751e6b0078be393132286c442345e5dc49699"xEthereum address of transactions you are retrieving
blockStart"0xe6e8f1"xBlock number to start scanning for transactions
blockEnd"0xe6f4d6"Block number to stop scanning for transactions. Defaults to the latest block.
addressFilter"RECEIVER_ONLY"Filters returned transactions to sender or receiver. Defaults to "SENDER_OR_RECEIVER"
blockchain"Ethereum"Ethereum-only in preview. Defaults to "Ethereum"
network"Mainnet"Mainnet-only in preview. Defaults to "Mainnet"

Get the response

You should get a JSON response back that looks similar to this:

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "blockStart": "0xe6e8ff",
    "blockEnd": "0xe6f4d6",
    "blocks": [
      {
        "blockHash": "0x9a44ddd3db03241b18ca6025283df48e04757a0832f9ce9a00a963925e3f427e",
        "blockNumber": "0xe6f426",
        "blockTimestamp": "0x62cf09b2",
        "transactions": [
          {
            "transactionHash": "0x2b8f126151394b6da53814688968a2da4db23e6be01ef580364890fb70302b19",
            "transactionIndex": "0x55",
            "from": "0xedc7001e99a37c3d23b5f7974f837387e09f9c93",
            "to": "0x3cd751e6b0078be393132286c442345e5dc49699",
            "value": "0x4be4db179ca9a00d70",
            "gasLimit": "0x5208",
            "gasPrice": "0x5ab49f9b1",
            "gasUsed": "0x5208",
            "cumulativeGasUsed": "0x59c997",
            "status": "0x1",
            "input": "0x",
            "nonce": "0x13094",
            "blockHash": "0x9a44ddd3db03241b18ca6025283df48e04757a0832f9ce9a00a963925e3f427e",
            "blockNumber": "0xe6f426",
            "blockTimestamp": "0x62cf09b2"
          },
          {
            "...": "output truncated."
          }
        ]
      },
      {
        "blockHash": "0x2a8d0c84e33d00eba7a0e102933ad7d6869d1a16511b3d1df9f0e31f15feccd2",
        "blockNumber": "0xe6f417",
        "blockTimestamp": "0x62cf0901",
        "transactions": [
          {
            "transactionHash": "0xc2b687b8115b631e8ca55e56b220c586841210a784f394a02c125b4759c3dfaf",
            "transactionIndex": "0xf5",
            "from": "0x21079d0b730dc3b3b2888a7fe34ad59bce07d3da",
            "to": "0x3cd751e6b0078be393132286c442345e5dc49699",
            "value": "0x1962d5a8b6408b60",
            "gasLimit": "0x5208",
            "gasPrice": "0x4fdcde329",
            "gasUsed": "0x5208",
            "cumulativeGasUsed": "0x15d9444",
            "status": "0x1",
            "input": "0x",
            "nonce": "0x11",
            "blockHash": "0x2a8d0c84e33d00eba7a0e102933ad7d6869d1a16511b3d1df9f0e31f15feccd2",
            "blockNumber": "0xe6f417",
            "blockTimestamp": "0x62cf0901"
          },
          {
            "...": "output truncated."
          }
        ]
      },
      {
        "...": "output truncated."
      }
    ]
  }
}

Understand the response

This response gives a list of blocks in which transactions were found. Each block includes the list of external transactions found for that address in that block.
Since we specified "RECEIVER_ONLY", the returned transactions will include only those which the specified address was the recipient.

The response returns a lot of information, we will only cover the highlights here. See the API docs for full documentation of the response values.

  • blockStart: the block number this response starts at
  • blockEnd: the block number this response ends at
    • If >1000 transactions would be returned for the requested block range, this API will return 1000+ transactions in a smaller block range (specified by blockStart and blockEnd in the result) such that all blocks returned are complete (i.e. contain all requested transactions)
    • This is covered in more detail in the next section, "Handle pagination"
  • blocks: the list of blocks containing transactions:
    • transactions: a list of relevant transactions in this block
      • from: origin address
      • to: destination address
      • value: value in native blockchain currency
      • status: "0x1" (Success), "0x0" (Failure)

Handle pagination

Note that in your API call, you requested transactions from block "0xe6e8f1" to "0xe6f4d6", but the response only included blocks "0xe6e8ff" to "0xe6f4d6".
This is because the API response is paginated when there are more than 1000 transactions in the requested block range.
If you were to scroll through the full response in your console and count the transactions, you'll see over 1000 transactions returned from this call (1004 to be specific).

To get the rest of the transactions, we'll need to note the returned block range, and make additional API calls to cover the rest of the desired bock range.

Both of the following API calls pipe the response to a utility called jq to format it before we save it to a file.
We'll discuss jq further in the next section.

First, save the response from the previous API call in a file named response1.json:

curl https://mainnet.ethereum.coinbasecloud.net/ \
  -u username:password \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{
  "method": "coinbaseCloud_getTransactionsByAddress",
  "params": {
    "address": "0x3cd751e6b0078be393132286c442345e5dc49699",
    "blockStart": "0xe6e8f1",
    "blockEnd": "0xe6f4d6",
    "addressFilter": "RECEIVER_ONLY",
    "blockchain": "Ethereum",
    "network":"Mainnet"
  },
  "id": 1,
  "jsonrpc": "2.0"
}' | jq '.' > response1.json

Then, make a second API call to get the rest of the transactions and save it into a file named response2.json

curl https://mainnet.ethereum.coinbasecloud.net/ \
  -u username:password \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{
  "method": "coinbaseCloud_getTransactionsByAddress",
  "params": {
    "address": "0x3cd751e6b0078be393132286c442345e5dc49699",
    "blockStart": "0xe6e8f1",
    "blockEnd": "0xe6e8fe",
    "addressFilter": "RECEIVER_ONLY",
    "blockchain": "Ethereum",
    "network":"Mainnet"
  },
  "id": 1,
  "jsonrpc": "2.0"
}' | jq '.' > response2.json

Process the response

For any given purpose, we may only be interested in a subset of this information, or we may have a specific question we'd like answered.
For this example, we'll find any sender addresses this address has received exactly 4 transactions from.

In this tutorial we'll be using the command line utility jq to answer our question quickly and easily from the command line, but you can use any programming language or tools you'd like to process JSON.

Combine our API call responses

To start answering our question (Which senders have sent this address exactly 4 transactions?), we'll start by combining our two files into one unified set of transactions.

Run the following command to create a new file, combined.json that merges the block data from response1.json and response2.json into one array:

jq -s '[.[].result.blocks[]]' response1.json response2.json > combined.json

The previous command finds all the objects in the blocks array inside the result object in response1.json and response2.json, combining them into one object in combined.json.

Filter down our results

Next, run this command to strip down our data to only the sender (from) and amount (value) of each top-level transaction:

cat combined.json | jq '[.[].transactions[] | { from: .from, value: .value }]' > transactions-only.json

The previous command finds all objects in each transactions array and outputs only the from and value properties into new objects, combining them into one object in transactions-only.json.

Finally, we'll group the transactions by sender (from) and filter the results down to only senders that have exactly 4 transactions:

cat transactions-only.json | jq '[group_by(.from)[] | select(length == 4)]' > final.json

Output:

[
  [
    {
      "from": "0xe657d33ca8da35371cdcdaf59825960f9ac5c065",
      "value": "0x3d96ab6e9527b"
    },
    {
      "from": "0xe657d33ca8da35371cdcdaf59825960f9ac5c065",
      "value": "0x370c01de4de0d"
    },
    {
      "from": "0xe657d33ca8da35371cdcdaf59825960f9ac5c065",
      "value": "0x3f62940d7ebe0"
    },
    {
      "from": "0xe657d33ca8da35371cdcdaf59825960f9ac5c065",
      "value": "0x6d6c38a9f1e5df"
    }
  ]
]

There's only one address that has sent our recipient address exactly 4 transactions: "0xe657d33ca8da35371cdcdaf59825960f9ac5c065".

You did it! You now know how to get transaction history for a given Ethereum address and analyze the resulting response data. From here, you can process more information from your response or check out other Advanced API methods.