Please do not use this approach to get the DXCC value of spots from the DX Cluster or Skimmer. For that, please use cty.xml.

If you are a logging software author, or administer an award where some degree of automation is desired, you might well want to lookup a very large number of records for DXCC purposes. Using the API for each QSO in turn would be very slow, as the total round-trip (and setup and teardown) is far longer than the time needed for the calculation.

Now, instead, you can use the batch DXCC lookup.

The URL for this API end point is:

You need to submit exactly one variable, json, which should be a JSON string containing all of the QSOs you want to look up, formatted in an array. Starting with the elements of the array, you need to provide two key/values in each:

  • C = callsign
  • T = date and time, in the format 1999-12-31 23:59:59 (this is strict)

For example, looking up 5 callsigns, your JSON might look like this:

[{"C":"G7VJR","T":"2011-01-12 15:20:12"},{"C":"G3TXF","T":"2013-12-12 19:00:32"},{"C":"MD0CCE","T":"1999-01-31 16:00:50"},{"C":"VK3VZ\/AM","T":"1999-03-12 12:00:50"},{"C":"FO1AC\/A\/P","T":"1972-05-11 03:40:10"},{"C":"KH8SI","T":"2006-08-01 03:40:10"},{"C":"7O8AA","T":"1990-07-29 06:45:50"},{"C":"KH6GB\/KH1","T":"2021-11-12 06:45:50"}]

Notice that JSON formatting should not really be much effort, and definitely not done manually. Almost all languages have JSON libraries which will handle escaping etc. reliably and you should not be expected to do this by hand. You probably start with an array in memory and at the last step convert it into a JSON string. 

Provided your API key is ok and the JSON checks out, Club Log will return the same JSON, but in each array element it will include:

A - key/value pair A, which is the ADIF number. If known, 

Z - the CQ Zone, if known

B - a boolean which tells you if the callsign mapping would be blocked by whitelists. 

Not all fields will necessarily be present in all cases. For example, for the query above you will get this:

[{"C":"G7VJR","T":"2011-01-12 15:20:12","A":223,"Z":14,"B":false},{"C":"G3TXF","T":"2013-12-12 19:00:32","A":223,"Z":14,"B":false},{"C":"MD0CCE","T":"1999-01-31 16:00:50","A":114,"Z":14,"B":false},{"C":"VK3VZ/AM","T":"1999-03-12 12:00:50","A":998,"Z":0,"B":false},{"C":"FO1AC/A/P","T":"1972-05-11 03:40:10","A":175,"Z":32,"B":false},{"C":"KH8SI","T":"2006-08-01 03:40:10","A":515,"Z":32,"B":false},{"C":"7O8AA","T":"1990-07-29 06:45:50","A":492,"Z":21,"B":false},{"C":"KH6GB/KH1","T":"2021-11-12 06:45:50","A":20,"Z":31,"B":true}]

All you have to do then is use your language's JSON decoder to get the data back inside your code, and you're done. 


  • It's only sensible to use this for batch lookups (more than 10 records at a time is about the right level).
  • The maximum number of elements you can present is 10,000. This will take Club Log hardly any time to process, but it's a reasonable limit that discourages unbounded batches being presented and consuming lots of memory.
  • Be careful how you format the time. The time field is very strict and records that don't comply will be skipped.
  • If you get a value of zero back in A, that means Club Log was unable to process it. A value of 1000 means Club Log successfully parsed the call and believes it is invalid for DXCC on the date in question.
  • 997 means internet/repeater, 998 means aircraft mobile, 999 means maritime mobile.
  • B = true means the callsign has been blocked by whitelisting. You should assume the callsign or date/callsign are not valid.

Please feel free to present as many QSOs as you need, always in batches of 10,000 or less and one batch at a time. For guidance, the bigger than batch the better (Club Log needs less than 1s to calculate 10,000 lookups so it's better if you make the batches large, in terms of overall work).

PHP Example client code:


$arReq = array();

$arReq[] = array("C" => "G7VJR""T" => "2011-01-12 15:20:12");

$arReq[] = array("C" => "G3TXF""T" => "2013-12-12 19:00:32");

$arReq[] = array("C" => "MD0CCE""T" => "1999-01-31 16:00:50");

$arReq[] = array("C" => "VK3VZ/AM""T" => "1999-03-12 12:00:50");

$arReq[] = array("C" => "FO1AC/A/P""T" => "1972-05-11 03:40:10");

$arReq[] = array("C" => "KH8SI""T" => "2006-08-01 03:40:10");

$arReq[] = array("C" => "7O8AA""T" => "1990-07-29 06:45:50");

$arReq[] = array("C" => "KH6GB/KH1""T" => "2021-11-12 06:45:50");

$strJson = json_encode($arReq);

$strRequest = "api=APIKEYHERE&json=$strJson";

$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, "");
curl_setopt($ch,CURLOPT_POSTFIELDS, $strRequest);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);

$strResult = curl_exec($ch);

echo "$strRequest\n";
if ($strResult !== false)
        echo "$strResult\n";
        echo "Lookup failed!\n";