Analytics SEO REST API User Guide

General Access

The Analytics SEO API is developed using REST principles, so can be accessed using any HTTP client with appropriate URLs, verbs and authentication. Data is returned in JSON format, and standard HTTP response codes are used to indicate success, validation failures, bad requests, etc.

The API endpoint is api.analyticsseo.com/v1 .

Data Types

Where additional parameters can be passed to a resource, please note the following about each data type:

Data Type Notes

string These must be URL-encoded

number (This note intentionally left blank)

boolean use 0 for FALSE and 1 for TRUE

NB: Each API call consumes one API credit, so if you are running weekly ranking checks, for example, on one keyword for one search engine, you will be use between 4 and 5 API units per month (as there are between 4 and 5 weeks each calendar month).

Authentication

When you sign up for an API key, we will generate a public key and private key for you, and an initial cryptographic SALT , which you can change at any time using your company settings page.

When you send a request to our API, you need to 1. generate a Unix timestamp of the current time 2. build a string consisting of the timestamp, your public API key, and your salt concatenated together in that order, with no delimiters 3. encrypt the string using HMAC-SHA256, with your private API key as the encryption key 4. add your public key, encrypted hash and timestamp to your request in the Authorization header in this format:

Authorization: KeyAuth publicKey=abc123 hash=A5748BE83DF8674D ts=1345781243

1

Resource Types

Reference Data

This collection of resources enables you to interact with reference data lists, such as lists of supported search engines.

Search Engines URL: api.analyticsseo.com/v1/reference_data/search_engines Supported verbs: GET Returns a list of currently-supported search engines.

Example: api.analyticsseo.com/v1/reference_data/search_engines Response: [{ "internal_name":"bing", "display_name":"Bing" }, { "internal_name":"google", "display_name":"Google" }, { "internal_name":"yahoo", "display_name":"Yahoo" }, { "internal_name":"yandex", "display_name":"Yandex" }]

Regions URL: api.analyticsseo.com/v1/reference_data/regions?search_engine=[internal_name] Supported verbs: GET

Returns a list of regions supported by the specified search engine (using the internal name of the engine).

Example: api.analyticsseo.com/v1/reference_data/regions?search_engine=google Response (truncated for clarity): [{ "region_code":"global", "region":"Global" }, { "region_code":"gb", "region":"" }, { "region_code":"us", "region":"United States"

2 }, { "region_code":"fr", "region":"France" }, { "region_code":"dz", "region":"Algeria" }]

Towns URL: api.analyticsseo.com/v1/reference_data/towns?region=[region_code] Supported verbs: GET Returns a list of towns in the specified region.

Example: api.analyticsseo.com/v1/reference_data/towns?region=gb Response (truncated for clarity): [ {"name":"Abbey Wood (Greater London)"}, {"name":"Abbots Langley (Hertfordshire)"}, {"name":"Abercanaid (County Borough of Merthyr Tydfil)"}, {"name":"Abercarn (County Borough of Caerphilly)"}, {"name":"Aberdare (Rhondda Cynon Taff)"}, {"name":"Aberdeen"}, {"name":"Abergavenny (Monmouthshire)"}, {"name":"Abergele (Conwy)"}, {"name":"Aberkenfig ( county borough)"}, {"name":"Abertillery (Blaenau Gwent)"}, {"name":"Abertridwr (County Borough of Caerphilly)"}, {"name":"Aberystwyth (County of Ceredigion)"} ]

Search Types URL: api.analyticsseo.com/v1/reference_data/search_types?search_engine=[internal_name] Supported verbs: GET Returns a list of search types supported by the specified search engine

Example: api.analyticsseo.com/v1/reference_data/search_types?search_engine=google Response: [{ "search_type":"web", "display_name":"Whole Web" }, { "search_type":"country", "display_name":"Country Only" }]

Search Engine Languages URL: api.analyticsseo.com/v1/reference_data/search_engine_languages?search_engine=[internal_nam e]®ion=[region_code] Supported verbs: GET Returns a list of languages supported by the specified search engine in the specified region

3

Example: api.analyticsseo.com/v1/reference_data/search_engine_languages?search_engine=google®io n=ch Response: [{ "language_code":"de", "display_name":"German" }, { "language_code":"en", "display_name":"English" }, { "language_code":"fr", "display_name":"French" }, { "language_code":"it", "display_name":"Italian" }, { "language_code":"rm", "display_name":"Rumantsch" }]

Search Results

This resource enables you to request a background job which will fetch structured search results from different search engines.

From the initial request you will receive a job id and which can be used via a different request (see Get Job Results below) to determine whether a job has been completed and get the available data.

Submit a job request:

URL: v2.api.analyticsseo.com/search_results?qualifiers Supported verbs: GET Notes: town, search_type, language and universal results are only available on Google.

Allowed qualifiers are:

Qualifier Type Required Notes

search_engine string yes Internal search engine name

region string yes Region code

town string no This must exactly match one of our towns (including the county, state or area if

4 applicable)

search_type string yes The search type. Defaults to “web” if not supplied.

language string no Language code. Optional - defaults to primary language for selected region if not supplied.

max_results number no Maximum value = 100. Defaults to 10 if not supplied.

phrase string yes The phrase to search for. This must be URL- encoded.

universal boolean no Set to TRUE to return universal search results, or FALSE to return just organic search results. Defaults to FALSE.

Example response: { "ready": false, "jid": "65b25a4b-5128-4691-9d4e-14383f741330", "payload": null }

Get job results As stated you can periodically query the api to see if your job request has been completed.

URL: v2.api.analyticsseo.com/get_job/ Supported verbs: GET

Example response: { "ready":true, "jid":"e59d5ba0-a0ea-41b7-9357-c849640c801c", "payload":{ "pages":{ "1":{ "total":7, "organic":7 } }, "results":{ "universal":{ "1":{ "landing_page":"http:\/\/magiccards.info\/", "site_links":1, "title":"MTG Magic: The Gathering card search", "url":"http:\/\/magiccards.info\/", "breadcrumbs":0, "more_results":1,

5 "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"MagicCards.Info MTG Magic: The Gathering card search. To get started, simply enter your sear ch terms. By default only names will be searched. Query: View as ..." }, "3":{ "landing_page":"http:\/\/book.cakephp.org\/2.0\/en\/models\/retrieving-your-data.html", "site_links":0, "title":"Retrieving Your Data - Book - CakePHP", "url":"http:\/\/book.cakephp.org\/2.0\/en\/models\/retrieving-your-data.html", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"The before state is the moment to modify the query, bind new associations, apply .... These ma gic functions can be used as a shortcut to search your tables by a ..." }, "2":{ "landing_page":"http:\/\/stackoverflow.com\/questions\/897185\/sql-magic-query-shouldnt-take-15-hours- but-it-does", "site_links":0, "title":"SQL magic - query shouldn't take 15 hours, but it does", "url":"http:\/\/stackoverflow.com\/questions\/897185\/sql-magic-query-shouldnt-take-15-hours-but-it- does", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"May 22, 2009 - Using hashses is one of the ways in which a database engine can execute a join. It should be very rare that you'd have to write your own hash-based ..." }, "5":{ "landing_page":"http:\/\/logicalread.solarwinds.com\/oracle-11g-making-query-run-magically-faster- mc02\/", "site_links":0, "title":"Making the Oracle Query "Magically" Faster", "url":"http:\/\/logicalread.solarwinds.com\/oracle-11g-making-query-run-magically-faster-mc02\/", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"When a query is run multiple times in succession, it becomes faster because the data is cached

6 in memory. This can make it seem faster then it is." }, "4":{ "landing_page":"https:\/\/wordpress.org\/support\/topic\/using-custom-select-query-and-magic-fields", "site_links":0, "title":"Using Custom Select Query and Magic fields - WordPress", "url":"https:\/\/wordpress.org\/support\/topic\/using-custom-select-query-and-magic-fields", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"Hello, i have this perfectly working code showing posts based on two or more custom fields; &l t;?php global $wpdb; global $post; $key1 = 'color'; $val1 = 'red'; ..." }, "7":{ "landing_page":"http:\/\/data.stackexchange.com\/help", "site_links":0, "title":"Help - Stack Exchange Data Explorer", "url":"http:\/\/data.stackexchange.com\/help", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"Features include collaborative query editing and OData endpoints for all graduated and ... Gett ing Started; Query Parameters; Magic Columns; Graphing; FAQ ..." }, "6":{ "landing_page":"http:\/\/www.amazon.com\/Open-Query-File-Magic-Holt\/dp\/1883884578", "site_links":0, "title":"Open Query File Magic!: Ted Holt: 9781883884574 ...", "url":"http:\/\/www.amazon.com\/Open-Query-File-Magic-Holt\/dp\/1883884578", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"Open Query File Magic! [Ted Holt] on Amazon.com. *FREE* shipping on qualifying offers. OPN QRYF (Open Query File) is the most powerful, most complex, and ..." } }, "organic":{ "1":{ "landing_page":"http:\/\/magiccards.info\/", "site_links":1, "title":"MTG Magic: The Gathering card search", "url":"http:\/\/magiccards.info\/", "breadcrumbs":0,

7 "more_results":1, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"MagicCards.Info MTG Magic: The Gathering card search. To get started, simply enter your sear ch terms. By default only names will be searched. Query: View as ..." }, "3":{ "landing_page":"http:\/\/book.cakephp.org\/2.0\/en\/models\/retrieving-your-data.html", "site_links":0, "title":"Retrieving Your Data - Book - CakePHP", "url":"http:\/\/book.cakephp.org\/2.0\/en\/models\/retrieving-your-data.html", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"The before state is the moment to modify the query, bind new associations, apply .... These ma gic functions can be used as a shortcut to search your tables by a ..." }, "2":{ "landing_page":"http:\/\/stackoverflow.com\/questions\/897185\/sql-magic-query-shouldnt-take-15-hours- but-it-does", "site_links":0, "title":"SQL magic - query shouldn't take 15 hours, but it does", "url":"http:\/\/stackoverflow.com\/questions\/897185\/sql-magic-query-shouldnt-take-15-hours-but-it- does", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"May 22, 2009 - Using hashses is one of the ways in which a database engine can execute a join. It should be very rare that you'd have to write your own hash-based ..." }, "5":{ "landing_page":"http:\/\/logicalread.solarwinds.com\/oracle-11g-making-query-run-magically-faster- mc02\/", "site_links":0, "title":"Making the Oracle Query "Magically" Faster", "url":"http:\/\/logicalread.solarwinds.com\/oracle-11g-making-query-run-magically-faster-mc02\/", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1,

8 "description":"When a query is run multiple times in succession, it becomes faster because the data is cached in memory. This can make it seem faster then it is." }, "4":{ "landing_page":"https:\/\/wordpress.org\/support\/topic\/using-custom-select-query-and-magic-fields", "site_links":0, "title":"Using Custom Select Query and Magic fields - WordPress", "url":"https:\/\/wordpress.org\/support\/topic\/using-custom-select-query-and-magic-fields", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"Hello, i have this perfectly working code showing posts based on two or more custom fields; &l t;?php global $wpdb; global $post; $key1 = 'color'; $val1 = 'red'; ..." }, "7":{ "landing_page":"http:\/\/data.stackexchange.com\/help", "site_links":0, "title":"Help - Stack Exchange Data Explorer", "url":"http:\/\/data.stackexchange.com\/help", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"Features include collaborative query editing and OData endpoints for all graduated and ... Gett ing Started; Query Parameters; Magic Columns; Graphing; FAQ ..." }, "6":{ "landing_page":"http:\/\/www.amazon.com\/Open-Query-File-Magic-Holt\/dp\/1883884578", "site_links":0, "title":"Open Query File Magic!: Ted Holt: 9781883884574 ...", "url":"http:\/\/www.amazon.com\/Open-Query-File-Magic-Holt\/dp\/1883884578", "breadcrumbs":0, "more_results":0, "search_box":0, "authorship_data":[

], "type":"organic", "page":1, "description":"Open Query File Magic! [Ted Holt] on Amazon.com. *FREE* shipping on qualifying offers. OPN QRYF (Open Query File) is the most powerful, most complex, and ..." } } }, "summary":{ "total":7, "organic":7 } }

9 }

10 Indexed Pages Count

This resource enables you to find the number of pages indexed in a search engine for a site.

URL: http://api.analyticsseo.com/v1/indexed_pages_count?search_engine=[internal_name]&url=[site_domain]

Supported verbs: GET

Returns the number of pages indexed in the requested search engine for the requested site. Note that currently only Google is supported.

Example: http://api.analyticsseo.com/v1/indexed_pages_count?search_engine=google&url=www.analyticsseo.com

Response:

{“indexed_pages”:”468″}

11 Example PHP Script

$params = array( 'search_engine' => 'google', 'region' => 'global', 'town' => '', 'search_type' => 'web', 'language' => '', 'max_results' => 10, 'phrase' => 'lady gaga', 'universal' => TRUE, );

$response = json_decode(call_api('search_results', 'get', $params)); $job_id = $response->jid; // Keep that, you will need it to retrieve your data!

// And now that we got job id, we can periodically check to see whether the results are ready for pickup while(True) { $job = json_decode(retrieve_job($job_id)); if($job->ready) { break; // The job is ready for processing } sleep(5); // Job is clearly not ready yet, so let's wait five seconds before retrying. } print_r($job->payload); exit; function retrieve_job($job_id) { $target_url = API_ENDPOINT . '/' . "get_job/" . $job_id; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $target_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch);

return $output; } function call_api($method, $verb, $params) { switch ($verb) { case 'get': return _call_api_get($method, $params);

default: return 'verb not recognised'; }

12 } function _call_api_get($method, $params) { $target_url = API_ENDPOINT . '/' . $method;

if (count($params)) { $target_url .= '?'; foreach ($params as $key => $value) { $target_url .= $key . '=' . urlencode($value) . '&'; } }

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $target_url); curl_setopt($ch, CURLOPT_HTTPHEADER, array(_build_auth_header())); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$output = curl_exec($ch); curl_close($ch);

return $output; } function _build_auth_header() { $time = time(); $hash_source = $time . API_PUBLIC_KEY . API_SALT; $hash = hash_hmac('sha256', $hash_source, API_PRIVATE_KEY);

$header = 'Authorization: KeyAuth'; $header .= ' publicKey=' . API_PUBLIC_KEY; $header .= ' hash=' . $hash; $header .= ' ts=' . $time; return $header; }

13