I think your should consider that using an API could result in fakes, wrongly-validated data. Using an API means you fully trust the API service,... which is kind-of against bitcoin no-trust model.
I recommend you to run a full node (Bitcoin Core 0.13.2 during time of writing).
There is no address-index (there is a patch you can manually compile into Core).
Simplest way with standard Bitcoin-Core 0.13.2 is to import all your addresses as watch-only into a wallet.
import addresses
Use the RPC call importaddress <address> "" false
to import a watch only address.
The 3rd argument false
is required to not rescan the blockchain for each import (can take serval hours).
Once you have imported all addresses, stop bitcoind/qt and restart it with the startup argument -rescan
.
The rescan may take a couple of minutes/hours (depending on your Disk/RAM/CPU). Once done, you can call getreceivedbyaddress <addr>
for each address to get the balance.
This result in authentic, self-validated data.
Note: If you are using Bitcoin Core 0.14, consider importing multiple addresses with importmulti