NAV
php shell csharp

Introduction

The BrightLocal API provides programmatic access to BrightLocal’s Local SEO Tools. The API provides a “REST” style interface and returns all data as a JSON encoded strings.

API Types

We have two types of API methods:

The first type requires you to submit your requests as part of a batch - a container which makes it easy to bundle up multiple requests and poll for all results. You can read more about batches below.

API URL

The base API URL is: https://tools.brightlocal.com/seo-tools/api

Authentication

Generating a signature:

<?php
define('API_KEY', '<INSERT_API_KEY>');
define('API_SECRET', '<INSERT_API_SECRET>');

$expires = (int) gmdate('U') + 1800; // not more than 1800 seconds
$sig = base64_encode(hash_hmac('sha1', API_KEY.$expires, API_SECRET, true));

echo urlencode($sig); // for get requests
echo $sig;
expiry=$((`date +%s`+1800)) # not more than 1800 seconds
sig=$(echo -n "<INSERT_API_KEY>$expiry" | openssl dgst -sha1 -binary -hmac "<INSERT_API_KEY>" | base64)

private string api_key = "<INSERT_API_KEY>";
private string api_secret = "<INSERT_API_SECRET>";

DateTime date = DateTime.Now;
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); // The seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
TimeSpan diff = date.ToUniversalTime() - origin;  // Subtract the seconds since the Unix Epoch from today's date. 
double expires =  Math.Floor(diff.TotalSeconds + 1800); // Not more than 1800 seconds

var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(api_secret);
byte[] messageBytes = encoding.GetBytes(api_key + expires);
using (var hmacsha1 = new HMACSHA1(keyByte))
{
    byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
    var signature = Convert.ToBase64String(hashmessage);   
}

All methods require a valid trial or production API key. Methods which manipulate or retrieve data in your account additionally require a signature. You ideally need to generate this signature for each request and set a short expiry time. For testing purposes you can chose to create a signature that will be valid for up to 30 minutes.

Authentication Errors

If there’s a problem with your API key, signature or expires one of the following errors will be returned:

Invalid API Key

Error responses:

{
    "errors":  {
        "INVALID_API_KEY": "Invalid API key specified"
    }
}

Signature Incorrect

{
    "errors":  {
        "INVALID_API_KEY": "Signatures don't match"
    }
}

In this situation your signature doesn’t match the one we generated for comparison. Most like there’s something wrong in the way you’re generating your signature. If passing the signature in the query string make sure you’ve URL encoded it before submitting.

Invalid Permissions

{
    "errors":  {
        "INVALID_API_KEY": "API key doesn't has access to the specified api call"
    }
}

If you see this error it means that your API key only has partial access to our API. You’ll need to contact us to get the API method you’re trying to call associated with your API key.

No Trial Requests Left

{
    "errors":  {
        "INVALID_API_KEY": "No trial requests left"
    }
}

Your trial key has used its allocation of free credits and you’re trying to call a batch API method that needs credits. Methods that manipulate your account don’t need credits or a production key.

API Key Doesn’t Support Signed Requests

{
    "errors":  {
        "INVALID_API_KEY": "API key not upgraded to support signed requests"
    }
}

Most likely you’ve got a very old API key and you’re trying to access one of our newer API methods that needs to be sent signature and expiry information but your key doesn’t have these.

Signature Too Old

{
    "errors":  {
        "INVALID_API_KEY": "Signature expired too long ago"
    }
}

The signature you’re trying to use expired more than 30 minutes ago. Ideally you should generate a new signature with every request but you must generate a new one at least every 30 minutes.

Signature Expiry Too Long

{
    "errors":  {
        "INVALID_API_KEY": "Specified expiry is too far in the future (max 1800 seconds allowed)"
    }
}

You can only generate a signature that expires a maximum of 30 minutes into the future. If you see this message you need to check the expiry value you’re using to generate your signature.

General Error Handling

{
    "errors":  {
        "INVALID_COMPANY_NAME": "Company name not specified",
        "INVALID_COMPANY_URL": "Company URL not specified",
        "INVALID_COUNTRY": "Country ISO 3 code not specified",
        "INVALID_BUSINESS_CATEGORY_ID": "Business category ID not specified"
    }
}

When an error occurs the data returned contains an error section with a list of relevant errors. Errors are returned when incorrect parameters are passed to an API method and in a few other distinct cases.

Generally the response will contain a top level node errors {} when an error has occurred and response {} when a successful result is returned.

API Wrapper

If you work with PHP or C# we have API wrappers which simplify authentication against our API and provide simple methods for making requests.

The PHP and C# examples in this documentation use these wrappers.

Batches

A batch acts like a container for API requests. It allows you to group requests for several types of data together and poll for results via a single consolidated call. All bar one of our raw data APIs need to be used within the context of a batch. The basic steps for using a batch are outlined below:

  1. Request a new batch ID
  2. Add one or more requests for data to the batch
  3. Commit the batch
  4. Poll for results

Create

Batch Method

Creating a batch

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$result = $batchApi->create();
if ($result['success']) {
    $batchId = $result['batch-id'];
}
curl -X POST \
    -d 'api-key=<INSERT_API_KEY>' \
    https://tools.brightlocal.com/seo-tools/api/v4/batch
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

int batchId = batchRequest.Create();

Success - status code 201 Created

{
    "success": true,
    "batch-id": "17"
}

Failure

{
    "success": false
}

Creates a new batch. You can add jobs to the batch to enable you to fetch different kinds of data.

A batch can have one of 5 states:

Jobs within a batch can also have one of 5 states:

Whilst you can technically add as many jobs as you want to a batch we recommend you submit jobs in batches of a few hundred at a time. This will allow you to start receiving results sooner.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/batch

Query Parameters

Parameter Notes
api-key Required
stop-on-job-error 1 or 0. default 0. If errors are found in one job the batch will be stopped and no further jobs will be processed.

Commit Batch

Batch Method

Committing a batch

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$batchId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
if ($batchApi->commit($batchId)) {
    echo 'Committed batch successfully.' . PHP_EOL;
}
curl -X PUT \
    -d 'api-key=<INSERT_API_KEY>' \
    -d 'batch-id=<INSERT_BATCH_ID>' \
    https://tools.brightlocal.com/seo-tools/api/v4/batch
int batchId = 1;
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

Success - status code 200 OK

{
    "success":true
}

Failure - status code 400 Bad Request

{
  "success": false,
  "errors" : { "INVALID_JOBS_COUNT":"Batch can't be committed with no jobs" }
}
{
  "success": false,
  "errors" : { "BATCH_ALREADY_COMMITTED":"This batch has been committed already" }
}

Committing a batch signals that you’ve finished adding jobs. At this point our systems will start processing the jobs that you’ve added. Once you commit a batch no further jobs can be added to it.

Authentication for this method is via API key only.

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v4/batch

Query Parameters

Parameter Notes
api-key Required
batch-id Required

Get Results

Batch Method

Getting batch results

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$batchId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
print_r($batchApi->get_results($batchId));
curl 'https://tools.brightlocal.com/seo-tools/api/v4/batch?api-key=<INSERT_API_KEY>&batch-id=<INSERT_BATCH_ID>'
int batchId = 1;
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

var results = batchRequest.GetResults(batchId);

Success - status code 200 OK

{
  "success": true,
  "status": "Finished",
  "results": {
    "LdFetchProfileUrl": [
      {
        "results": [
          {
            "url": "https://plus.google.com/117512971192208385977/about?hl=en&rfmt=s"
          }
        ],
        "status": "Completed",
        "job-id": 318
      }
    ],
    "LdFetchProfileDetails": [
      {
        "results": [
          {
            "business_name": "Hub Plumbing & Mechanical",
            "street_address": null,
            "postcode": null,
            "region": null,
            "locality": null,
            "address": "Greenwich Village New York, NY",
            "contact_telephone": "+1 917-634-8888",
            "description_present": true,
            "num_photos": 2,
            "star_rating": "4.7",
            "num_reviews": 10,
            "claimed": true,
            "website_url": "http://www.hubplumbingnyc.com/",
            "cid": "117512971192208385977",
            "categories": "Plumber",
            "check_in": null
          }
        ],
        "status": "Completed",
        "job-id": 318
      }
    ]
  },
  "statuses": {
    "Completed": 2
  }
}

This retrieves the results of all jobs added to the batch. Results are added as they’re returned so you can keep polling this endpoint to retrieve results progressively. Once results for all jobs have been returned the batch will be marked as “Finished”.

Authentication for this method is via API key only.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/batch

Query Parameters

Parameter Notes
api-key Required
batch-id Required

Delete

Batch Method

Delete a batch

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$batchId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
if ($batchApi->delete($batchId)) {
    echo 'Successfully deleted batch.' . PHP_EOL;
}
curl -X DELETE 'https://tools.brightlocal.com/seo-tools/api/v4/batch?api-key=<INSERT_API_KEY>&batch-id=<INSERT_BATCH_ID>'
int batchId = 1;
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

var success = batchRequest.Delete(batchId);

Success - status code 200 Ok

{
    "success": true
}

Failure - status code 404 Not Found

{
  "success": false,
  "errors" : { "INVALID_BATCH_ID": "Batch ID not found" }
}

Delete a batch. This also deletes all data retrieved for jobs added to the batch.

Authentication for this method is via API key only.

HTTP Request

DELETE https://tools.brightlocal.com/seo-tools/api/v4/batch

Query Parameters

Parameter Notes
api-key Required
batch-id Required

Stop Batch

Batch Method

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$batchId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
if ($batchApi->stop($batchId)) {
    echo 'Successfully stopped batch.' . PHP_EOL;
}
curl -X PUT
    -d 'api-key=<INSERT_API_KEY>' \
    -d 'batch-id=<INSERT_BATCH_ID>' \
    https://tools.brightlocal.com/seo-tools/api/v4/batch/stop
int batchId = 1;
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

var success = batchRequest.Stop(batchId);

Success - status code 200 Ok

{
    "success": true
}

Failure - status code 404 Not Found

{
  "success": false,
  "errors" : { "INVALID_BATCH_ID": "Batch ID not found" }
}

Cancels a batch midway through processing. Any jobs in the batch that haven’t already been processed will also be cancelled.

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v4/batch/stop

Query Parameters

Parameter Notes
api-key Required
batch-id Required

Rankings

Batch Method

Fetch rankings

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$searches = array(
    array(
        'search-engine'   => 'google',
        'country'         => 'USA',
        'google-location' => 'New York, NY',
        'search-term'     => 'restaurant new york',
        'urls'            => json_encode(array('le-bernardin.com')),
        'business-names'  => json_encode(array('Le Bernardin'))
    ),
    array(
        'search-engine'   => 'google',
        'country'         => 'USA',
        'google-location' => 'New York, NY',
        'search-term'     => 'restaurant manhattan',
        'urls'            => json_encode(array('le-bernardin.com')),
        'business-names'  => json_encode(array('Le Bernardin'))
    ),
    array(
        'search-engine'   => 'google',
        'country'         => 'USA',
        'google-location' => 'New York, NY',
        'search-term'     => 'restaurant 10019',
        'urls'            => json_encode(array('le-bernardin.com')),
        'business-names'  => json_encode(array('Le Bernardin'))
    )
);
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($searches as $search) {
        $result = $api->call(
            '/v4/rankings/search',
            array_merge(
                $search, array('batch-id' => $batchId)
            )
        );
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
curl -X POST \
    -d 'api-key=<INSERT_API_KEY>' \
    -d 'batch-id=<INSERT_BATCH_ID>' \
    -d 'search-engine=google' \
    -d 'country=USA' \
    -d 'google-location=new+york,ny' \
    -d 'search-term=restaurant' \
    -d 'urls=["jean-georgesrestaurant.com"]' \
    -d 'business-names=["Jean-Georges Restaurant"]' \
    https://tools.brightlocal.com/seo-tools/api/v4/rankings/search
List<RankingsSearch> searches = new List<RankingsSearch>();
searches.Add(new RankingsSearch()
{
    search_engine = "google",
    country = "USA",
    google_location = "New York, NY",
    search_term = "restaurant new york",
    urls = new List<string>() { "le-bernardin.com" },
    business_names = new List<string>() { "Le Bernardin" }
});
searches.Add(new RankingsSearch()
{
    search_engine = "yahoo",
    country = "USA",
    google_location = "New York, NY",
    search_term = "restaurant new york",
    urls = new List<string>() { "le-bernardin.com" },
    business_names = new List<string>() { "Le Bernardin" }
});


api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();
var parameters = new api.Parameters();

// Add jobs to batch
foreach (var item in searches)
{
    // Convert the searches list into parameters for the web requestt
    parameters = batchRequest.convertListToParameters(item);
    parameters.Add("batch-id", batchId);

    var jobId = Api.Post("/v4/rankings/search", parameters);

    if (jobId.ResponseStatus == ResponseStatus.Completed)
    {
        dynamic job = JsonConvert.DeserializeObject(jobId.Content);
        if (!job.success)
        {
            string message = "Error adding job";
            var batchException = new ApplicationException(message + job.errors, job.ErrorException);
            throw batchException;
        }
    }
    else
    {
        throw new ApplicationException(jobId.ErrorMessage);
    }
}
// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a backgroud process, such as HangFire,  or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic rankingResults = JsonConvert.DeserializeObject(results.Content);

if (rankingResults.success)
{
    while (rankingResults.status != "Stopped" || rankingResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        rankingResults = JsonConvert.DeserializeObject(results.Content);
    }
    return rankingsResults;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message + rankingResults.errors, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": "1"
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

Failure (500 Internal Server Error)

{
    "success": false,
    "reason": "Unable to add job"
}

Get Batch Rankings Result, Sucess(200 Ok)

{
  "success": true,
  "results": {
    "SearchRankV2Api": [
      {
        "results": [
          {
            "identifier": "google",
            "site": "Google Search",
            "site-url": "http://www.google.com",
            "search-url": "https://www.google.com/search?q=Back+Pain+midtown+manhattan&gl=us&gws_rd=cr&pws=0",
            "search-term": "Back Pain midtown manhattan",
            "results": [
              {
                "url": "http://thecenternyc.com/tag/back-pain/",
                "orig_url": "http://www.thecenternyc.com/tag/back-pain/",
                "title": "Back Pain Archives >> New York, NY 10001",
                "rank": 13,
                "sub_rank": null,
                "page": 2,
                "type": "Organic",
                "match": [
                  "website address"
                ],
                "matched_url": "www.thecenternyc.com",
                "serp-screenshot-url": "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/6daa949323ef54687f41d95500751fd08256bc17.png"
              },
              {
                "url": "http://thecenternyc.com/back-pain-nyc/",
                "orig_url": "http://www.thecenternyc.com/back-pain-nyc/",
                "title": "Back Pain NYC Archives >> The Center Chiropractic &amp; PT NYC",
                "rank": 14,
                "sub_rank": null,
                "page": 2,
                "type": "Organic",
                "match": [
                  "website address"
                ],
                "matched_url": "www.thecenternyc.com",
                "serp-screenshot-url": "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/6daa949323ef54687f41d95500751fd08256bc17.png"
              }
            ],
            "result-types": [
              "Organic",
              "Places",
              "Carousel",
              "Directory",
              "Secondary"
            ],
            "http-error": false,
            "error-type": "None",
            "serp-screenshots": [
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/6b3c2ea8060ad5d564bbbfb84e1dc877e401d7ab.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/6daa949323ef54687f41d95500751fd08256bc17.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/7e4fe6933ceff9303c541c3a4ff078d762aefff9.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/fec74577c27321aa403da6733b82f3e3daa06407.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/ceac0abca0233cb404f7859e8942ee1ed6851564.png"
            ]
          }
        ],
        "payload": {
          "queue-attempts": 1,
          "http-codes": [
            0
          ],
          "source": 3,
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "search-engine": "google",
          "options": {
            "urls": [
              "www.thecenternyc.com"
            ],
            "business-names": [
              "The center for chiropractic & pt",
              "the center for chiropractic decomperssion"
            ],
            "search-term": "Back Pain midtown manhattan",
            "postcode": "10001",
            "telephone": "646-606-2580",
            "country": "USA",
            "google-location": "",
            "bing-location": "",
            "include-name-only-matches": true,
            "num-search-pages": 5,
            "debug": false,
            "listings": false,
            "screenshots-enabled": true,
            "include-intermediate-html": false,
            "append-location": false
          },
          "position": 0
        },
        "status": "Completed",
        "job-id": 564270998
      },
      {
        "results": [
          {
            "identifier": "google",
            "site": "Google Search",
            "site-url": "http://www.google.com",
            "search-url": "https://www.google.com/search?q=apos+therapy+new+york&gl=us&gws_rd=cr&pws=0",
            "search-term": "apos therapy new york",
            "results": [
              {
                "url": "http://thecenternyc.com/apostherapy/",
                "orig_url": "http://www.thecenternyc.com/apostherapy/",
                "title": "Apostherapy NYC - Chiropractor NYC",
                "rank": 18,
                "sub_rank": null,
                "page": 2,
                "type": "Organic",
                "match": [
                  "website address"
                ],
                "matched_url": "www.thecenternyc.com",
                "serp-screenshot-url": "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/9fce8698cbbfb59eeb4237dbb337c35e73fca0fa.png"
              }
            ],
            "result-types": [
              "Organic",
              "Places",
              "Carousel",
              "Directory",
              "Secondary"
            ],
            "http-error": false,
            "error-type": "None",
            "serp-screenshots": [
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/98aa8a19a602cefdb4d1ee0c2d220bf651b8d5cc.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/9fce8698cbbfb59eeb4237dbb337c35e73fca0fa.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/7346a7078076feaf155456e4437429bfc7e7bf94.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/95b95e6189dc6a4cae2ec8247b53f507a6cf4925.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/e6b467b76c9e2ea66c1ebfbdcd316ee95f97af6e.png"
            ]
          }
        ],
        "payload": {
          "queue-attempts": 1,
          "http-codes": [
            0
          ],
          "source": 3,
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "search-engine": "google",
          "options": {
            "urls": [
              "www.thecenternyc.com"
            ],
            "business-names": [
              "The center for chiropractic & pt",
              "the center for chiropractic decomperssion"
            ],
            "search-term": "apos therapy new york",
            "postcode": "10001",
            "telephone": "646-606-2580",
            "country": "USA",
            "google-location": "",
            "bing-location": "",
            "include-name-only-matches": true,
            "num-search-pages": 5,
            "debug": false,
            "listings": false,
            "screenshots-enabled": true,
            "include-intermediate-html": false,
            "append-location": false
          },
          "position": 0
        },
        "status": "Completed",
        "job-id": 564270999
      },
      {
        "results": [
          {
            "identifier": "yahoo",
            "site": "Yahoo! Search",
            "site-url": "http://www.yahoo.com",
            "search-url": "http://search.yahoo.com/search?p=apos+therapy+new+york",
            "search-term": "apos therapy new york",
            "results": [],
            "result-types": [
              "Organic",
              "Local",
              "Directory"
            ],
            "http-error": false,
            "error-type": "None",
            "serp-screenshots": [
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/60f6391ac2751102165e4f6b7b360c97e8a63bc1.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/712b2c7d35f59309e36f8bdc79dab76b04695388.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/dace1c14755c4b1467e36cfce7a96af86604a785.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/2c381e008d53e0d02ec4d11cc03e29e5b618a236.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/f754b72bd373673cd6e4010519413d28ec22a1ab.png"
            ]
          }
        ],
        "payload": {
          "queue-attempts": 1,
          "http-codes": [
            0
          ],
          "source": 3,
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "search-engine": "yahoo",
          "options": {
            "urls": [
              "www.thecenternyc.com"
            ],
            "business-names": [
              "The center for chiropractic & pt",
              "the center for chiropractic decomperssion"
            ],
            "search-term": "apos therapy new york",
            "postcode": "10001",
            "telephone": "646-606-2580",
            "country": "USA",
            "google-location": "",
            "bing-location": "",
            "include-name-only-matches": true,
            "num-search-pages": 5,
            "debug": false,
            "listings": false,
            "screenshots-enabled": true,
            "include-intermediate-html": false,
            "append-location": false
          },
          "position": 0
        },
        "status": "Completed",
        "job-id": 564271014
      },
      {
        "results": [
          {
            "identifier": "yahoo",
            "site": "Yahoo! Search",
            "site-url": "http://www.yahoo.com",
            "search-url": "http://search.yahoo.com/search?p=redcord+therapy+manhattan",
            "search-term": "redcord therapy manhattan",
            "results": [
              {
                "url": "http://thecenternyc.com/redcord-physical-therapy-manhattan/",
                "orig_url": "http://www.thecenternyc.com/redcord-physical-therapy-manhattan/",
                "title": "Redcord Physical Therapy Manhattan | Chiropractor...",
                "rank": 3,
                "sub_rank": null,
                "page": 1,
                "type": "Organic",
                "match": [
                  "website address"
                ],
                "matched_url": "www.thecenternyc.com",
                "serp-screenshot-url": "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/7609663e9087a81b92015e1c9af025257ae4be62.png"
              },
              {
                "url": "http://thecenternyc.com/redcord-manhattan/",
                "orig_url": "http://www.thecenternyc.com/redcord-manhattan/",
                "title": "Redcord Manhattan Archives >> The Center...",
                "rank": 5,
                "sub_rank": null,
                "page": 1,
                "type": "Organic",
                "match": [
                  "website address"
                ],
                "matched_url": "www.thecenternyc.com",
                "serp-screenshot-url": "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/7609663e9087a81b92015e1c9af025257ae4be62.png"
              }
            ],
            "result-types": [
              "Organic",
              "Local",
              "Directory"
            ],
            "http-error": false,
            "error-type": "None",
            "serp-screenshots": [
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/7609663e9087a81b92015e1c9af025257ae4be62.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/09424d6d44a145c86aa72c2948414d6bc220969b.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/54938f2561fea42cb97af038e85d3b8ec41d8a4c.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/2256d2c5362c6a7745f82f76bd28801322f902fa.png",
              "https://seo-serp-screenshots.s3.amazonaws.com/2016/10/14/14/11ae9ee7f549d89e2248d97bf6cf3764d997e047.png"
            ]
          }
        ],
        "payload": {
          "queue-attempts": 1,
          "http-codes": [
            0
          ],
          "source": 3,
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "search-engine": "yahoo",
          "options": {
            "urls": [
              "www.thecenternyc.com"
            ],
            "business-names": [
              "The center for chiropractic & pt",
              "the center for chiropractic decomperssion"
            ],
            "search-term": "redcord therapy manhattan",
            "postcode": "10001",
            "telephone": "646-606-2580",
            "country": "USA",
            "google-location": "",
            "bing-location": "",
            "include-name-only-matches": true,
            "num-search-pages": 5,
            "debug": false,
            "listings": false,
            "screenshots-enabled": true,
            "include-intermediate-html": false,
            "append-location": false
          },
          "position": 0
        },
        "status": "Completed",
        "job-id": 564271015
      }

    ]
  },
  "statuses": {
    "Completed": 4
  },
  "status": "Finished"
}

This API method allows you to retrieve search ranking (and listing data) from the major search engines and their local variants, namely Google, Google Maps, Yahoo!, Yahoo! Local, Bing and Bing Maps. It works for the USA, United Kingdom, Canada and Australia. The only exception is in Australia where Yahoo! Local is not supported.

This method needs to be used in conjunction with the batch methods described above.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/rankings/search

Query Parameters

Parameter Notes
api-key Required
batch-id Required
search-engine Required One of google, google-mobile, google-local, yahoo, yahoo-local, bing, bing-local.
country Required Determines whether or not to search against .com, .ca, co.uk, .com.au search engines. One of USA, CAN:EN, CAN:FR, GBR, AUS, IRL or NZL.
google-location Allows you to optionally localize results by specifying your physical location. Specify a ZIP, city name or region. Only applicable to US searches. Also see Check Location method.
bing-location Allows you to optionally localize results by specifying your physical location. See Check Location method.
search-term Required The search term to get ranking information for.
urls The URLs to get ranking information for. Encode as a JSON string, e.g. [“www.bluehillfarm.com”, “www.candle79.com”, “shabutatsu.com”, “marea-nyc.com”, “www.taorestaurant.com”] (max 10).
business-names A list of possible business names to search for. Encode as a JSON string, e.g. [“The Rose Pub”,“Rose Pub”,“The Rose”]. For backwards compatibility this also supports a newline (\n) separated list.
postcode A valid ZIP or country postal code.
telephone A valid telephone number.
include-secondary-matches Determines whether or not to include results matched by name, telephone and/or ZIP/postal code. One of yes or no. This should be used in conjunction with the postal and telephone parameters.
listings Include details of all SERPs returned, not just the matches. Defaults to “no”. Accepts “yes” or “no”. The default is “no”.
screenshots Determines whether or not to generate SERP screenshots and include the links to those screenshots in the response. Accepts “yes” or “no”. The default is “no”.

Batch Method

Fetch rankings

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$searches = array(
    'restaurant new york',
    'restaurant manhattan',
    'restaurant 10019'
);
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    $result = $api->call(
        '/v4/rankings/bulk-search',
        array(
            'batch-id' => $batchId,
            'search-engine'   => 'google',
            'country'         => 'USA',
            'google-location' => 'New York, NY',
            'search-terms'    => json_encode($searches),
            'urls'            => json_encode(array('le-bernardin.com')),
            'business-names'  => json_encode(array('Le Bernardin'))
        )
    );
    if ($result['success']) {
        printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
curl -X POST \
    -F 'api-key=<INSERT_API_KEY>' \
    -F 'batch-id=<INSERT_BATCH_ID>' \
    -F 'search-engine=google' \
    -F 'country=USA' \
    -F 'google-location=new+york,ny' \
    -F 'search-terms=["restaurant","restaurant+new+york","restaurant+manhattan"]' \
    -F 'urls=["jean-georgesrestaurant.com"]' \
    -F 'business-names=["Jean-Georges Restaurant"]' \
    https://tools.brightlocal.com/seo-tools/api/v4/rankings/bulk-search
List<string> searches = new List<string>(
    new string[] {
        "restaurant new york'",
        "restaurant manhattan",
        "restaurant 10019"
    }
);
api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();
var parameters = new api.Parameters();
parameters.Add("batch-id", batchId);
parameters.Add("search-engine", "google");
parameters.Add("country", "USA");
parameters.Add("telephone", "+1 212-554-1515");
parameters.Add("google-location", "New York, NY");
parameters.Add("search-terms", searches);
parameters.Add("urls", "['le-bernardin.com']");
parameters.Add("business-names", "['Le Bernardin']");
var jobId = Api.Post("/v4/rankings/bulk-search", parameters);

if (jobId.ResponseStatus == ResponseStatus.Completed)
{
    dynamic job = JsonConvert.DeserializeObject(jobId.Content);
    if (!job.success)
    {
       string message = "Error adding job";
       var batchException = new ApplicationException(message + job.errors, job.ErrorException);
       throw batchException;
    }
}
else
{
    throw new ApplicationException(jobId.ErrorMessage);
}

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a backgroud process, such as HangFire,  or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic rankingResults = JsonConvert.DeserializeObject(results.Content);

if (rankingResults.success)
{
    while (rankingResults.status != "Stopped" || rankingResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        rankingResults = JsonConvert.DeserializeObject(results.Content);
    }
    return rankingsResults;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message + rankingResults.errors, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-ids": ["1", "2","3"]
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

Failure (500 Internal Server Error)

{
    "success": false,
    "reason": "Unable to add job(s)"
}

This method works the same as the search method above except it allows you to submit up to 100 search terms in one request. Use this when you want to look up rankings for many hundreds or thousands of search terms.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/rankings/bulk-search

Query Parameters

Parameter Notes
api-key Required
batch-id Required
search-engine Required One of google, google-mobile, google-local, yahoo, yahoo-local, bing, bing-local.
country Required Determines whether or not to search against .com, .ca, co.uk, .com.au search engines. One of USA, CAN:EN, CAN:FR, GBR, AUS, IRL or NZL.
google-location Allows you to optionally localize results by specifying your physical location. Specify a ZIP, city name or region. Only applicable to US searches. Also see Check Location method.
bing-location Allows you to optionally localize results by specifying your physical location. See Check Location method.
search-terms Required Encode as a JSON string, e.g. [“restaurant new york”, “restaurant”, “cafe”] (max 100).
urls The URLs to get ranking information for. Encode as a JSON string, e.g. [“www.bluehillfarm.com”, “www.candle79.com”, “shabutatsu.com”, “marea-nyc.com”, “www.taorestaurant.com”] (max 10).
business-names A list of possible business names to search for. Encode as a JSON string, e.g. [“The Rose Pub”,“Rose Pub”,“The Rose”]. For backwards compatibility this also supports a newline (\n) separated list.
postcode A valid ZIP or country postal code.
telephone A valid telephone number.
include-secondary-matches Determines whether or not to include results matched by name, telephone and/or ZIP/postal code. One of yes or no. This should be used in conjunction with the postal and telephone parameters.
listings Include details of all SERPs returned, not just the matches. Defaults to “no”. Accepts “yes” or “no”. The default is “no”.
screenshots Determines whether or not to generate SERP screenshots and include the links to those screenshots in the response. Accepts “yes” or “no”. The default is “no”.

Check Location

Location Found (200 OK)

{
    "success": true,
    "response": true
}

Location Not Found (200 OK)

{
    "success": true,
    "response": false
}

Suggestions (Bing only) (200 OK)

{
    "success": true,
    "response": [
        "lat:40.7145500183105|long:-74.0071182250977|New York, NY",
        "lat:39.6849212646484|long:-93.9093475341797|New York, MO",
        "lat:32.1684989929199|long:-95.669189453125|New York, TX"
    ]
}

Look up a location that’s suitable for use when setting Google or Bing location whilst performing a search using the method above. This method is deprecated for use with Google as there’s no longer any need to check if the location you want to set is valid.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/rankings/check-location

Query Parameters

Parameter Notes
api-key Required
search-engine Required One of google or bing.
country One of USA, CAN, GBR, AUS, IRL or NZL.
location e.g. postcode/ZIP, city and state code

Local Directories

Fetch Profile URL

Batch Method

Fetch profile url for 3 local directories

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$localDirectories = array(
    'google',
    'yelp',
    'yahoo'
);
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($localDirectories as $localDirectory) {
        $result = $api->call('/v4/ld/fetch-profile-url', array(
            'batch-id'        => $batchId,
            'business-names'  => 'La Bernardin\nBernardin Cafe\nBernardin restaraunt',
            'country'         => 'USA',
            'city'            => 'New York',
            'postcode'        => '10019'
            'local-directory' => $localDirectory            
        ));
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
List<string> localDirectories = new List<string>();
localDirectories.Add("google");
localDirectories.Add("yelp");
localDirectories.Add("yahoo");

api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();

// Add jobs to batch
foreach (var directory in localDirectories)
{
    var parameters = new api.Parameters();
    parameters.Add("batch-id", batchId);
    parameters.Add("business-names", "La Bernardin\nBernardin Cafe\nBernardin restaraunt");
    parameters.Add("country", "USA");
    parameters.Add("city", "New York");
    parameters.Add("postcode", "10019");
    parameters.Add("local-directory", directory);

    var jobId = Api.Post("/v4/ld/fetch-profile-url", parameters);

    if (jobId.ResponseStatus == ResponseStatus.Completed)
    {
        dynamic job = JsonConvert.DeserializeObject(jobId.Content);
        if (!job.success)
        {
            string message = "Error adding job";
            var batchException = new ApplicationException(message + job.errors, job.ErrorException);
            throw batchException;
        }
    }
    else
    {
        throw new ApplicationException(jobId.ErrorMessage);
    }
}

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a background process, such as HangFire, or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic directoryResults = JsonConvert.DeserializeObject(results.Content);

if (directoryResults.success)
{
    while (directoryResults.status != "Stopped" || directoryResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        directoryResults = JsonConvert.DeserializeObject(results.Content);
    }
    return results;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Failure (400 Bad Request)

{
  "success": false,
  "errors": {
    "INVALID_BUSINESS_NAMES": "Invalid Business names specified",
    "INVALID_COUNTRY": "Invalid  country  specified",
    "INVALID_CITY": "Invalid  city  specified",
    "INVALID_POSTCODE": "Invalid  postcode  specified",
    "INVALID_LOCAL_DIRECTORY": "Invalid  local directory  specified"
  }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

Get Batch Fetch Profile Url Results, Success (200 Ok)

{
  "success": true,
  "results": {
    "LdFetchProfileUrl": [
      {
        "results": [
          {
            "url": null
          }
        ],
        "payload": {
          "business-names": "La Bernardin\nBernardin Cafe\nBernardin restaraunt",
          "country": "USA",
          "city": "New York",
          "postcode": "10019",
          "telephone": "",
          "directory": "google",
          "street-address": "",
          "api-key": "1a08b2e1fd07fa4150f91b80636906a9a29b8e47"
        },
        "status": "Completed",
        "job-id": 605592911
      }
    ]
  },
  "statuses": {
    "Completed": 1
  },
  "status": "Finished"
}

Authentication for this method is via API key only.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/ld/fetch-profile-url

Query Parameters

Parameter Notes
api-key Required
batch-id Required
business-names Required A newline (\n) separated list of possible business names to search for. For example: The Rose Pub Rose Pub The Rose.
country Required
city Required
postcode Required
local-directory Required See possible options in appendix below.
telephone
street-address

Fetch Profile URL (Telephone Number Only)

Batch Method

Fetch profile url (telephone number only) for 3 local directories

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$localDirectories = array(
    'google',
    'yelp',
    'yahoo'
);
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($localDirectories as $localDirectory) {
        $result = $api->call(/v4/ld/fetch-profile-url', array(
            'batch-id'        => $batchId,
            'telephone'       => '+1 212-554-1515',
            'search-type'     => 'search-by-phone',         
            'local-directory' => $localDirectory            
        ));
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
List<string> localDirectories = new List<string>();
localDirectories.Add("google");
localDirectories.Add("yelp");
localDirectories.Add("yahoo");

api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();

// Add jobs to batch
foreach (var directory in localDirectories)
{
    var parameters = new api.Parameters();
    parameters.Add("batch-id", batchId);
    parameters.Add("local-directory", directory);
    parameters.Add("telephone", "+1 212-554-1515");
    parameters.Add("search-type", "search-by-phone");

    var jobId = Api.Post("/v4/ld/fetch-profile-url", parameters);

    if (jobId.ResponseStatus == ResponseStatus.Completed)
    {
        dynamic job = JsonConvert.DeserializeObject(jobId.Content);
        if (!job.success)
        {
            string message = "Error adding job";
            var batchException = new ApplicationException(message + job.errors, job.ErrorException);
            throw batchException;
        }
    }
    else
    {
        throw new ApplicationException(jobId.ErrorMessage);
    }
}

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a background process, such as HangFire,  or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic directoryResults = JsonConvert.DeserializeObject(results.Content);

if (directoryResults.success)
{
    while (directoryResults.status != "Stopped" || directoryResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        directoryResults = JsonConvert.DeserializeObject(results.Content);
    }
    return results;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Failure (400 Bad Request)

{
 "success": false,
 "errors": {
   "INVALID_TELEPHONE": "Invalid telephone specified",
   "INVALID_LOCAL_DIRECTORY": "Invalid local directory  specified"
 }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

Get Batch Fetch Profile Url (Telephone Number Only) Results, Success (200 Ok)

Authentication for this method is via API key only.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/ld/fetch-profile-url

Query Parameters

Parameter Value Notes
api-key Required
batch-id Required
local-directory Required See possible options in appendix below.
telephone Required
search-type search-by-phone Required

Fetch Profile Details (by profile URL)

Batch Method

Fetch profile details (by profile URL)

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);   
    $result = $api->call('/v4/ld/fetch-profile-details', array(
        'batch-id'        => $batchId,
        'profile-url'  => 'https://www.google.com/search?q="Le+Bernardin"+"10019"',
        'country'         => 'USA' 
    ));
    if ($result['success']) {
        printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
    }    
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();

var parameters = new api.Parameters();
parameters.Add("batch-id", batchId);
parameters.Add("profile-url", "https://www.google.com/search?q='Le+Bernardin'+'10019'");
parameters.Add("country", "USA");       

var jobId = Api.Post("/v4/ld/fetch-profile-details", parameters);

if (jobId.ResponseStatus == ResponseStatus.Completed)
{
    dynamic job = JsonConvert.DeserializeObject(jobId.Content);
    if (!job.success)
    {
        string message = "Error adding job";
        var batchException = new ApplicationException(message + job.errors, job.ErrorException);
        throw batchException;
    }
}
else
{
    throw new ApplicationException(jobId.ErrorMessage);
}

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a background process, such as HangFire, or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic directoryResults = JsonConvert.DeserializeObject(results.Content);

if (directoryResults.success)
{
    while (directoryResults.status != "Stopped" || directoryResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        directoryResults = JsonConvert.DeserializeObject(results.Content);
    }
    return results;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Failure (400 Bad Request)

{
  "success": false,
  "errors": {
    "INVALID_COUNTRY": "Invalid  country  specified",
    "INVALID_PROFILE_URL": "Profile Url is not valid"
  }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

Authentication for this method is via API key only.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/ld/fetch-profile-details

Query Parameters

Parameter Notes
api-key Required
batch-id Required
profile-url Required For requests to fetch Google profile data please see constructing Google URLs.
country Required

Fetch Profile Details (by business data)

Batch Method

Fetch profile details (by business data)

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$localDirectories = array(
    'google',
    'yelp',
    'yahoo'
);
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($localDirectories as $localDirectory) {
        $result = $api->call(/v4/ld/fetch-profile-details-by-business-data', array(
            'batch-id'        => $batchId,
            'business-names'  => 'La Bernardin\nBernardin Cafe\nBernardin restaraunt',
            'country'         => 'USA',
            'city'            => 'New York',
            'postcode'        => '10019'
            'local-directory' => $localDirectory            
        ));
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
List<string> localDirectories = new List<string>();
localDirectories.Add("google");
localDirectories.Add("yelp");
localDirectories.Add("yahoo");

api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();

// Add jobs to batch
foreach (var directory in localDirectories)
{
    var parameters = new api.Parameters();
    parameters.Add("batch-id", batchId);
    parameters.Add("business-names", "La Bernardin\nBernardin Cafe\nBernardin restaraunt");
    parameters.Add("country", "USA");
    parameters.Add("city", "New York");
    parameters.Add("postcode", "10019");
    parameters.Add("local-directory", directory);

    var jobId = Api.Post("/v4/ld/fetch-profile-details-by-business-data", parameters);

    if (jobId.ResponseStatus == ResponseStatus.Completed)
    {
        dynamic job = JsonConvert.DeserializeObject(jobId.Content);
        if (!job.success)
        {
            string message = "Error adding job";
            var batchException = new ApplicationException(message + job.errors, job.ErrorException);
            throw batchException;
        }
    }
    else
    {
        throw new ApplicationException(jobId.ErrorMessage);
    }
}

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a background process, such as HangFire, or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic directoryResults = JsonConvert.DeserializeObject(results.Content);

if (directoryResults.success)
{
    while (directoryResults.status != "Stopped" || directoryResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        directoryResults = JsonConvert.DeserializeObject(results.Content);
    }
    return results;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Failure (400 Bad Request)

{
  "success": false,
  "errors": {
    "INVALID_BUSINESS_NAMES": "Invalid Business names specified",
    "INVALID_COUNTRY": "Invalid  country  specified",
    "INVALID_CITY": "Invalid city  specified",
    "INVALID_POSTCODE": "Invalid postcode  specified",
    "INVALID_LOCAL_DIRECTORY": "Invalid local directory specified"
  }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

This method shortcuts Fetch Profile URL and Fetch Profile Details above by carrying out both in one step. It essentially looks up the URL and then uses that to fetch the profile details.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/ld/fetch-profile-details-by-business-data

Query Parameters

Parameter Notes
api-key Required
batch-id Required
business-names Required A newline (\n) separated list of possible business names to search for. For example: The Rose Pub Rose Pub The Rose.
country Required
city Required
postcode Required
local-directory Required See possible options in appendix below.
telephone
street-address

Reviews

Fetch Reviews (by profile URL)

Batch Method

Fetch reviews for 3 Google+ profile URLs

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$profileUrls = array(
    'https://plus.google.com/114222978585544488148/about?hl=en',
    'https://plus.google.com/117313296997732479889/about?hl=en',
    'https://plus.google.com/111550668382222753542/about?hl=en'
);
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($profileUrls as $profileUrl) {
        $result = $api->call('/v4/ld/fetch-reviews', array(
            'batch-id'    => $batchId,
            'profile-url' => $profileUrl,
            'country'     => 'USA'
        ));
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
List<string> profileUrls = new List<string>();
profileUrls.Add("https://plus.google.com/114222978585544488148/about?hl=en");
profileUrls.Add("https://plus.google.com/117313296997732479889/about?hl=en");
profileUrls.Add("https://plus.google.com/111550668382222753542/about?hl=en");



api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();


// Add jobs to batch
foreach (var item in profileUrls)
{
    var parameters = new api.Parameters();
    parameters.Add("batch-id", batchId);
    parameters.Add("profile-url", item);
    parameters.Add("country", "USA");

    var jobId = Api.Post("/v4/ld/fetch-reviews", parameters);

    if (jobId.ResponseStatus == ResponseStatus.Completed)
    {
        dynamic job = JsonConvert.DeserializeObject(jobId.Content);
        if (!job.success)
        {
            string message = "Error adding job";
            var batchException = new ApplicationException(message + job.errors, job.ErrorException);
            throw batchException;
        }
    }
    else
    {
        throw new ApplicationException(jobId.ErrorMessage);
    }
}
// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a backgroud process, such as HangFire,  or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic reviewResults = JsonConvert.DeserializeObject(results.Content);

if (reviewResults.success)
{
    while (reviewResults.status != "Stopped" || reviewResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        reviewResults = JsonConvert.DeserializeObject(results.Content);
    }
    return reviewResults;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message + rankingResults.errors, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Failure (400 Bad Request)

{
  "success": false,
  "errors": {
    "INVALID_COUNTRY": "Invalid  country  specified",
    "INVALID_PROFILE_URL": "Profile Url is not valid",
    "INVALID_DATE_FROM": "Invalid Date From. Date Format: Y-m-d or Y-m-d H:i:s",
    "INVALID_REVIEWS_LIMIT": "Reviews Limit should be positive number or 'all'"
  }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

Authentication for this method is via API key only.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/ld/fetch-reviews

Query Parameters

Parameter Notes
api-key Required
batch-id Required
profile-url Required For requests to fetch Google reviews please see constructing Google URLs.
country Required
sort ‘rating’ or 'date’. By default 'date’.
reviews-limit Positive number or 'all’. By default 250.
date-from Date Format: Y-m-d or Y-m-d H:i:s. By default not specified.

Fetch Reviews (by business data)

Batch Method

Fetch reviews for a business using business data

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($profileUrls as $profileUrl) {
        $result = $api->call('/v4/ld/fetch-reviews-by-business-data', array(
            'batch-id'        => $batchId,
            'business-names'  => 'Le Bernardin',
            'city'            => 'New York',
            'postcode'        => '10019',
            'street-address'  => '155 W 51st St',
            'local-directory' => 'google',
            'country'         => 'USA',
            'telephone'       => '(212) 554-1515'
        ));
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
List<string> localDirectories = new List<string>();
localDirectories.Add("google");
localDirectories.Add("facebook");
localDirectories.Add("yahoo");

api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();

// Add jobs to batch
foreach (var item in localDirectories)
{    
    var parameters = new api.Parameters();
    parameters.Add("batch-id", batchId);
    parameters.Add("business-names", "Le Bernardin\nLe Bernardin Cafe");
    parameters.Add("city", "New York");
    parameters.Add("postcode", "10019");
    parameters.Add("local-directory", item);
    parameters.Add("country", USA);    

    var jobId = Api.Post("/v4/ld/fetch-reviews-by-business-data", parameters);

    if (jobId.ResponseStatus == ResponseStatus.Completed)
    {
        dynamic job = JsonConvert.DeserializeObject(jobId.Content);
        if (!job.success)
        {
            string message = "Error adding job";
            var batchException = new ApplicationException(message + job.errors, job.ErrorException);
            throw batchException;
        }
    }
    else
    {
        throw new ApplicationException(jobId.ErrorMessage);
    }
}
// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a backgroud process, such as HangFire,  or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic reviewResults = JsonConvert.DeserializeObject(results.Content);

if (reviewResults.success)
{
    while (reviewResults.status != "Stopped" || reviewResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        reviewResults = JsonConvert.DeserializeObject(results.Content);
    }
    return reviewResults;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message + rankingResults.errors, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Success (200 Ok)

{
  "success": true,
  "results": {
    "LdFetchProfileUrl": [
      {
        "results": [
          {
            "url": "https://www.google.com/search?q=%22%5B%22Pick+A+Bagel%22%5D%22+%2210021%22&gws_rd=cr&gl=us"
          }
        ],
        "payload": {
          "business-names": "[\"Pick A Bagel\"]",
          "country": "USA",
          "city": "Manhattan",
          "postcode": "10021",
          "telephone": "(212) 717-4668",
          "directory": "google",
          "street-address": "1475 2nd Avenue",
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "dependent-job": {
            "name": "LdFetchReviews",
            "payload": {
              "profile-url": null,
              "country": "USA",
              "date-from": null,
              "reviews-limit": 250,
              "sort-type": "date",
               "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            }
          }
        },
        "status": "Completed",
        "job-id": 549612293
      },
      {
        "results": [
          {
            "url": "http://www.yelp.com/biz/pick-a-bagel-new-york-5"
          }
        ],
        "payload": {
          "business-names": "[\"Pick A Bagel\"]",
          "country": "USA",
          "city": "Manhattan",
          "postcode": "10021",
          "telephone": "(212) 717-4668",
          "directory": "yelp",
          "street-address": "1475 2nd Avenue",
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "dependent-job": {
            "name": "LdFetchReviews",
            "payload": {
              "profile-url": null,
              "country": "USA",
              "date-from": null,
              "reviews-limit": 250,
              "sort-type": "date",
              "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            }
          }
        },
        "status": "Completed",
        "job-id": 549612304
      }

    ],
    "LdFetchReviews": [
      {
        "results": [
          {
            "reviews": [

              {
                "rating": 4,
                "author": "Jeremy Dayan",
                "timestamp": "2016-07-30",
                "text": "Nice place to have breakfast in. Relatively good prices and fast service.",
                "id": "0c64b06e4c8ddaa0c6be4ba88df17f7e13cd95a0"
              },

              {
                "rating": 4,
                "author": "Alain Schmid",
                "timestamp": "2016-05-30",
                "text": "Choose your Bagle and cream cheese from a broad range of different sets and ingredients.",
                "id": "92d26048a7e297ef8911c21e35479fd2cd267d83"
              },
              {
                "rating": 4,
                "author": "David van der Loo",
                "timestamp": "2016-05-30",
                "text": "Okay for morning breakfast take-away.",
                "id": "1d5abf2447d6d78b467fae216b630c4eef7b3eb5"
              },
              {
                "rating": 4,
                "author": "Riley Sherer",
                "timestamp": "2015-09-30",
                "text": "You want a bagel? Okay, pick a bagel. Come on, I don't got all day. Yeah yeah the coffee's alright.",
                "id": "c88db1e509fbc2e9731f7946b84fdbfc4eb2f607"
              }
            ],
            "reviews-count":4,
            "star-rating": 4
          }
        ],
        "payload": {
          "profile-url": "https://www.google.com/search?q=%22%5B%22Pick+A+Bagel%22%5D%22+%2210021%22&gws_rd=cr&gl=us",
          "country": "USA",
          "date-from": null,
          "reviews-limit": 250,
          "sort-type": "date",
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "parent-id": 549612293
        },
        "status": "Completed",
        "job-id": 549612293
      },
      {
        "results": [
          {
            "reviews": [
              {
                "rating": 1,
                "author": "Krista C.",
                "timestamp": "2008-05-27",
                "text": "One of the worst bagels NYC has to offer.Now I don't consider myself a bagel snob but i'm used to having a Ess-A-Bagel and a Hot Jumbo Bagel around the corner.But now after moving I needed to find my new bagel place, I thought I'd give Pick-A-Bagel a try.",
                "link": "http://www.yelp.com/biz/pick-a-bagel-new-york-5?hrid=6ijWFhvccHDdiSj5MnX3yQ",
                "id": "c0f1160d92b4d60bb6609b7b9d4e7be31013781e"
              },
              {
                "rating": 1,
                "author": "Jeffrey C.",
                "timestamp": "2008-03-04",
                "text": "I don't know about others in the store but I tried from their \"make your own pasta\" menu and had the pesto sauce for the pasta. It was the worst pesto sauce I had in my life.",
                "link": "http://www.yelp.com/biz/pick-a-bagel-new-york-5?hrid=1ZIo0LYcFqmK7IJTMmw_bg",
                "id": "b0223bea06d6fd8e907f41ec73cc792db538b0f9"
              }
            ],
            "reviews-count": 2,
            "star-rating": "1.0"
          }
        ],
        "payload": {
          "profile-url": "http://www.yelp.com/biz/pick-a-bagel-new-york-5",
          "country": "USA",
          "date-from": null,
          "reviews-limit": 250,
          "sort-type": "date",
          "api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "parent-id": 549612304
        },
        "status": "Completed",
        "job-id": 549612304
      }

    ]
  },
  "statuses": {
    "Completed": 6,
    "Failed": 0
  },
  "status": "Finished"
}

Failure (400 Bad Request)

{
  "success": false,
  "errors": {
    "INVALID_BUSINESS_NAMES": "Invalid Business names specified",
    "INVALID_COUNTRY": "Invalid country specified",
    "INVALID_CITY": "Invalid city specified",
    "INVALID_POSTCODE": "Invalid postcode specified",
    "INVALID_LOCAL_DIRECTORY": "Invalid local directory specified",
    "INVALID_DATE_FROM": "Invalid Date From. Date Format: Y-m-d or Y-m-d H:i:s",
    "INVALID_REVIEWS_LIMIT": "Reviews Limit should be positive number or 'all'"
  }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

This method finds profile url then fetches reviews using this URL.

Authentication for this method is via API key only.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/ld/fetch-reviews-by-business-data

Query Parameters

Parameter Notes
api-key Required
batch-id Required
business-names Required A newline (\n) separated list of possible business names to search for. For example: The Rose Pub Rose Pub The Rose.
city Required
postcode Required
local-directory Required See appendix below for possible options.
street-address
country Required Only USA.
telephone A valid telephone number. Providing this will improve the quality of results returned.
sort 'rating’ or 'date’. By default 'date’.
reviews-limit Positive number or 'all’. By default 250.
date-from Date Format: Y-m-d or Y-m-d H:i:s. By default not specified.

Offsite SEO & Social Profiles

Offsite SEO

Batch Method

Fetch offsite SEO information for a website address

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($profileUrls as $profileUrl) {
        $result = $api->call('/v4/seo/offsite', array(
            'batch-id'        => $batchId,
            'website-url'     => 'http://www.gramercytavern.com/'
        ));
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();

var parameters = new api.Parameters();
parameters.Add("batch-id", batchId);
parameters.Add("website-url", "http://le-bernardin.com");   

var jobId = Api.Post("/v4/seo/offsite", parameters);

if (jobId.ResponseStatus == ResponseStatus.Completed)
{
    dynamic job = JsonConvert.DeserializeObject(jobId.Content);
    if (!job.success)
    {
        string message = "Error adding job";
        var batchException = new ApplicationException(message + job.errors, job.ErrorException);
        throw batchException;
    }
}
else
{
    throw new ApplicationException(jobId.ErrorMessage);
}

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a background process, such as HangFire, or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic offsiteResults = JsonConvert.DeserializeObject(results.Content);

if (offsiteResults.success)
{
    while (offsiteResults.status != "Stopped" || offsiteResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        offsiteResults = JsonConvert.DeserializeObject(results.Content);
    }
    return results;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Failure (400 Bad Request)

{
  "success": false,
  "errors": {
    "INVALID_BATCH_ID": "Batch ID not found",
    "INVALID_WEBSITE_URL": "Website URL missing"
  }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

This API method returns offsite SEO information domain age, hosting location, number of pages indexed and authority. Authentication for this method is via API key only.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/seo/offsite

Query Parameters

Parameter Notes
api-key Required
batch-id Required
website-url Required URL of the business web site. Can be specified with or without http(s).

Social Profiles

Batch Method

Fetch details of the social profiles a business has

<?php
use BrightLocal\Api;
use BrightLocal\Batches\V4 as BatchApi;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$batchApi = new BatchApi($api);
$batchId = $batchApi->create();
if ($batchId) {
    printf('Created batch ID %d%s', $batchId, PHP_EOL);
    foreach ($profileUrls as $profileUrl) {
        $result = $api->call('/v4/social/profiles', array(
            'batch-id'         => $batchId,
            'website-url'      => 'http://www.gramercytavern.com/',
            'fetch-twitter'    => 'yes',
            'fetch-facebook'   => 'yes',
            'fetch-foursquare' => 'yes',
            'business-names'   => '["Gramercy Tavern"]',
            'street-address'   => '42 E 20th St',
            'city'             => 'New York',
            'state-code'       => 'NY',
            'telephone'        => '(212) 477-0777',
            'postcode'         => '10003',
            'country'          => 'USA'
        ));
        if ($result['success']) {
            printf('Added job with ID %d%s', $result['job-id'], PHP_EOL);
        }
    }
    if ($batchApi->commit($batchId)) {
        echo 'Committed batch successfully.'.PHP_EOL;
        // poll for results, in a real world example you might
        // want to do this in a separate process (such as via an
        // AJAX poll)
        do {
            $results = $batchApi->get_results($batchId);
            sleep(10); // limit how often you poll
        } while (!in_array($results['status'], array('Stopped', 'Finished')));
        print_r($results);
    }
}
api Api = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
batchApi batchRequest = new batchApi(Api);

// Create a new batch
int batchId = batchRequest.Create();

var parameters = new api.Parameters();
parameters.Add("batch-id", batchId);
parameters.Add("website-url", "http://le-bernardin.com");
parameters.Add("fetch-twitter", "yes");
parameters.Add("fetch-facebook", "yes");
parameters.Add("fetch-foursqaure", "yes");
parameters.Add("business-names", "['Le Bernardin', 'Bernardin Cafe']");
parameters.Add("street-addess", "155 West 51st Street");
parameters.Add("city", "New York");
parameters.Add("state-code", "NY");
parameters.Add("telephone", "+1 212-554-1515");
parameters.Add("postcode", "10019");
parameters.Add("country", "USA");

var jobId = Api.Post("/v4/social/profiles", parameters);

if (jobId.ResponseStatus == ResponseStatus.Completed)
{
    dynamic job = JsonConvert.DeserializeObject(jobId.Content);
    if (!job.success)
    {
        string message = "Error adding job";
        var batchException = new ApplicationException(message + job.errors, job.ErrorException);
        throw batchException;
    }
}
else
{
    throw new ApplicationException(jobId.ErrorMessage);
}

// Commit the batch, resturns true or false
bool commit = batchRequest.Commit(batchId);

// Poll for results. In a real world example you should do this in a background process, such as HangFire, or use the Task Parallel Library to create a BackGroundWorker Task.
// It is bad practice to use Thread.Sleep(). This is only for the example and will actually freeze the UI until the while loop is finished. 

var results = batchRequest.GetResults(batchId);
dynamic socialResults = JsonConvert.DeserializeObject(results.Content);

if (socialResults.success)
{
    while (socialResults.status != "Stopped" || socialResults.status != "Finished")
    {
        Thread.Sleep(10000);
        results = batchRequest.GetResults(batchId);
        socialResults = JsonConvert.DeserializeObject(results.Content);
    }
    return results;
}
else
{
    const string message = "Error Retrieving batch results ";
    var batchException = new ApplicationException(message, results.ErrorException);
    throw batchException;
}

Success (201 Created)

{
    "success": true,
    "job-id": 318
}

Failure (400 Bad Request)

{
  "success": false,
  "errors": {
    "INVALID_WEBSITE_URL": "Website URL missing",
    "INVALID_CITY": "City missing",
    "INVALID_COUNTRY": "Country missing",
    "INVALID_BUSINESS_NAMES": "Business name(s) missing"
  }
}

Failure (405 Method Not Allowed)

{
  "success": false,
  "errors": {
    "INVALID_METHOD": "Invalid method specified. Only POST method is available"
  }
}

This API method returns details of the social profiles a business has on Twitter, Facebook and Foursquare. Authentication for this method is via API key only.

Please Note: Address and telephone fields are mostly optional but the more information you provide the more likely that we’ll return correct matches for your business.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/social/profiles

Query Parameters

Parameter Notes
api-key Required
batch-id Required
website-url Required URL of the business website. Can be specified with or without http(s).
fetch-twitter yes or no. Defaults to no. Fetch Twitter profile for the business if available.
fetch-facebook yes or no. Defaults to no. Fetch Facebook profile for the business if available.
fetch-foursquare yes or no. Defaults to no. Fetch Foursquare profile for the business if available.
business-names Required A JSON encoded string of business names, e.g. [“Delmonico’s”,“Delmonico’s Restaurant”]
street-address
city Required
state-code Required (USA only). A valid two letter state code, e.g. CA.
telephone
postcode A valid ZIP or postal code.
country Required Valid 3 letter ISO code. e.g, USA, GBR, CAN.
follow-mode This determines how our crawler extracts information from your website. We crawl your website to help us identify Twitter, Facebook and Foursquare profile information.
  1. Only follow links that lead to the same root domain (e.g. foo.brightlocal.com and bar.brightlocal.com).
  2. Only follow links that lead to the same domain (e.g. www.brightlocal.com). This is the default.
  3. Only follow links that lead to pages under the same path as that specified in website-url.

Clients

Add Client

Account Method

Creating a Client

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v1/clients-and-locations/clients', [       
    'name'                 => 'Le Bernardin',               
    'company-url'          => 'le-bernardin.com'
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'name=Le Bernardin' \
 -d 'company-url=le-bernardin.com' \
 https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("name", "Le Bernardin");
parameters.Add("company-url", "http://www.le-bernardin.com");

var success = request.Post("/v1/clients-and-locations/clients", parameters);

Success (200 OK)

{
    "success": true,
    "client-id": 1
}

Adds a new client and associates it with your account.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
name Required 50 characters max.
company-url Required 150 characters max
reference-number An arbitrary unique reference you can use to identify a client. This may correspond to a unique value used within your system and can be useful when importing or exporting data. 50 characters max.

Update Client

Account Method

Update an existing client. Only supply values you want to update. The rest will be left unchanged.

Update a Client

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->put('/v1/clients-and-locations/clients/<client_id>', [
    'name'                 => 'Le Bernardin',               
    'company-url'          => 'le-bernardin.com',
]);
print_r($success);
curl -X PUT \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'name=Le Bernardin' \
 -d 'company-url=le-bernardin.com' \
   https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients/<client_id>

Update a client

api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("name", "Le Bernardin Cafe");

var success = request.Put("/v1/clients-and-locations/clients/<client_id>", parameters);

Success (200 OK)

{
    "success": true,
    "client-id": 1
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients/<client_id>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
name 50 characters max
company-url 150 characters max
reference-number An arbitrary unique reference you can use to identify a client. This may correspond to a unique value used within your system and can be useful when importing or exporting data. 50 characters max.

Delete Client

Account Method

Delete a Client

<?php
use BrightLocal\Api;

$clientId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$result = $api->delete('/v1/clients-and-locations/clients/' . $clientId);
if (!empty($result['success'])) {
    echo 'Successfully deleted client.' . PHP_EOL;
}
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var client_id = 36447;

var success = request.Delete("/v1/clients-and-locations/clients/" + client_id);

Success (200 OK)

{
    "success": true
}

Delete an existing client. If there are reports associated with this client then the association is removed but the reports are not deleted. Warning: This action cannot be undone.

HTTP Request

DELETE https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients/<client_id>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
client-id Required

Get Client

Account Method

Get a Client

<?php
use BrightLocal\Api;
$clientId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$client = $api->get('/v1/clients-and-locations/clients/'. $clientId);
print_r($client);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
var clientId = 36447;
var success = request.Get("/v1/clients-and-locations/clients/" + clientId + "", parameters);

Success (200 OK)

{
    "success": true,
    "client": {
        "client-id":1,
        "company-name": "BrightLocal",
        "status": "client",
        "client-reference": "BrightLocal-1"
    }
}

Get extended details for a specific client.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients/<clientId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
client-id Required

Search Clients

Account Method

Search for a client

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v1/clients-and-locations/clients/search', [   
    'q' => 'BrightLocal'    
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'q=My+Sample+Query' \   
  https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients/search
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("q", "BrightLocal");      

var success = request.Put("/v1/clients-and-locations/clients/search", parameters);

Success (200 OK)

{
    "success": true,
    "clients":  [
        {
            "client-id": 1,
            "company-name": "BrightLocal",
            "status": "client",
            "client-reference": "BrightLocal-1"
        },
        {
            "client-id": 2,
            "company-name": "BrightLocal 2",
            "status": "client",
            "client-reference": "BrightLocal-2"
        }
    ]
}

Search for clients matching a specified search string.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/clients/search

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
q Required

Locations

Add Location

Account Method

Add Location

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v1/clients-and-locations/locations/', [
    'name'                 => 'Le Bernardin',
    'url'                  => 'le-bernardin.com',
    'business-category-id' =>  605,
    'country'              => 'USA', // 3 letter iso code
    'address1'             => '155 West 51st Street',
    'address2'             => '',
    'region'               => 'NY', // State or Region
    'city'                 => 'New York',
    'postcode'             => '10019',
    'telephone'            => '+1 212-554-1515',
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'name=Le Bernardin' \
 -d 'url=le-bernardin.com' \
 -d 'business-category-id=605' \ 
 -d 'country=USA' \
 -d 'address1=155 West 51st Street' \
 -d 'address1=' \
 -d 'region=NY' \
 -d 'city=New York' \
 -d 'postcode=10019' \
 -d 'telephone=+1 212-554-1515' \
 https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("name", "Le Bernardin");
parameters.Add("url", "http://le-bernardin.com");
parameters.Add("business-category-id", "605");
parameters.Add("country", "USA"); // 3 Letter iso code
parameters.Add("address1", "155 Weest 51st Street");
parameters.Add("address2", "");
parameters.Add("region", "NY"); // State or Region
parameters.Add("city", "New York");
parameters.Add("postcode", "10019");
parameters.Add("telephone", "+1 212-554-1515");

var success = request.Post("/v1/clients-and-locations/locations/", parameters);

Success (200 OK)

{
    "success": true,
    "location-id": 1
}

Adds a new location and associates it with your account.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
name Required 50 characters max.
client-id
url 256 characters max
business-category-id See here for a full list of valid business codes.
country Required ISO 3 country code.
address1 Required 80 characters max
address2 80 characters max
region Required 20 characters max
city Required 20 characters max
postcode Required 80 characters max
telephone Required 20 characters max
unique-reference An arbitrary unique reference you can use to identify a location. This may correspond to a unique value used within your system and can be useful when importing or exporting data. 50 characters max.
contact-first-name 50 characters max
contact-last-name 50 characters max
contact-mobile 20 characters max
contact-telephone 20 characters max
contact-email 100 characters max
contact-fax 20 characters max
number-of-employees 10 characters max
year-of-formation 20 characters max
extra-business-categories Json encoded array.
working-hours Json encoded array. Available array keys: mon_start, mon_end, tue_start, tue_end, wed_start, wed_end, thu_start, thu_end, fri_start, fri_end, sat_start, sat_end, sun_start, sun_end
payment-methods Json encoded array. Available values: cash, visa, mastercard, amex, cheque, invoice, insurance, atm, travelers, financing, paypal, discover
short-description 200 characters max
long-description 500 characters max
services-of-products Json encoded array

Update Location

Account Method

Update an existing location. Only supply values you want to update. The rest will be left unchanged.

Update Location

<?php
use BrightLocal\Api;

$locationId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->put('/v1/clients-and-locations/locations/' .$locationId, [
    'name'                          => 'Le Bernardin',
    'url'                           => 'le-bernardin.com',
    'business-category-id'          =>  605,
    'country'                       => 'USA', // 3 letter iso code
    'address1'                      => '155 West 51st Street',
    'address2'                      => '',
    'region'                        => 'NY', // State or Region
    'city'                          => 'New York',
    'postcode'                      => '10019',
    'telephone'                     => '+1 212-554-1515',
]);
print_r($success);
curl -X PUT \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'name=Le Bernardin' \
 -d 'url=le-bernardin.com' \
 -d 'business-category-id=605' \ 
 -d 'country=USA' \
 -d 'address1=155 West 51st Street' \
 -d 'address1=' \
 -d 'region=NY' \
 -d 'city=New York' \
 -d 'postcode=10019' \
 -d 'telephone=+1 212-554-1515' \
 https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/1
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var locationId = 1;
var parameters = new api.Parameters();
parameters.Add("name", "Le Bernardin");
parameters.Add("url", "http://le-bernardin.com");
parameters.Add("business-category-id", "605");
parameters.Add("country", "USA"); // 3 Letter iso code
parameters.Add("address1", "155 Weest 51st Street");
parameters.Add("address2", "");
parameters.Add("region", "NY"); // State or Region
parameters.Add("city", "New York");
parameters.Add("postcode", "10019");
parameters.Add("telephone", "+1 212-554-1515");

var success = request.Put("/v1/clients-and-locations/locations/" + locationId + "", parameters);

Success (200 OK)

{
    "success": true,
    "location-id": 1
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/<locationId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
name 50 characters max.
client-id
url 256 characters max
business-category-id See here for a full list of valid business codes.
country ISO 3 country code.
address1 80 characters max
address2 80 characters max
region 20 characters max
city 20 characters max
postcode 80 characters max
telephone 20 characters max
unique-reference An arbitrary unique reference you can use to identify a location. This may correspond to a unique value used within your system and can be useful when importing or exporting data. 50 characters max.
contact-first-name 50 cha8acters max
contact-last-name 50 characters max
contact-mobile 20 characters max
contact-telephone 20 characters max
contact-email 100 characters max
contact-fax 20 characters max
number-of-employees 10 characters max
year-of-formation 20 characters max
extra-business-categories Json encoded array.
working-hours Json encoded array. Available array keys: mon_start, mon_end, tue_start, tue_end, wed_start, wed_end, thu_start, thu_end, fri_start, fri_end, sat_start, sat_end, sun_start, sun_end
payment-methods Json encoded array. Available values: cash, visa, mastercard, amex, cheque, invoice, insurance, atm, travelers, financing, paypal, discover
short-description 200 characters max
long-description 500 characters max
services-of-products Json encoded array

Delete Location

Account Method

Delete a Location

<?php
use BrightLocal\Api;

$locationId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$result = $api->delete('/v1/clients-and-locations/locations/' . $locationId);
if (!empty($result['success'])) {
    echo 'Successfully deleted location.' . PHP_EOL;
}
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var locationId = 1;
var parameters = new api.Parameters();

var success = request.Delete("/v1/clients-and-locations/locations/" + locationId + "", parameters);

Success (200 OK)

{
    "success": true
}

Delete an existing location. If there are reports associated with this location then the association is removed but the reports are not deleted. Warning: This action cannot be undone.

HTTP Request

DELETE https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/<locationId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id Required

Get Location

Account Method

Get location

<?php
use BrightLocal\Api;

$locationId = 1;
$api = new Api(<INSERT_API_KEY>', '<INSERT_API_SECRET>);
$location = $api->get('/v1/clients-and-locations/locations/' . $locationId);
print_r($location);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var locationId = 1;
var parameters = new api.Parameters();

var success = request.Get("/v1/clients-and-locations/locations/" + locationId + "", parameters);

Success (200 OK)

{
   "success":true,
   "location":{
        "location-name":"BrightLocal HQ",
        "client-id":1,
        "location-url":"https://www.brightlocal.com",
        "business-category-id":650,
        "country":"GBR",
        "address1":"The Old Candlemakers",
        "address2":"West St, Lewes",
        "region":"East Sussex",
        "town":"Lewes",
        "postcode":"BN7 2NZ",
        "telephone":"80500 050 0505",
        "location-reference":"BL1",
        "contact-first-name":"first name",
        "contact-last-name":"last name",
        "contact-telephone":"+44 1273 917 374",
        "contact-fax":"",
        "contact-mobile":"",
        "num-of-employees":"50",
        "year-of-formation":"2009",
        "extra-business_categories":[
            "marketing"
        ],
        "working-hours":{
            "mon_start":"9 a.m.",
            "mon_end":"7 p.m."
        },
        "payment-methods-accepted":[
            "visa",
            "paypal"
        ],
        "short-desc":"",
        "long-desc":"",
        "services-or-products":[
            "analytics"
        ]
   }
}

Get extended details for a specific location.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/<locationId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Search Locations

Account Method

Search for a location

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->call('/v1/clients-and-locations/locations/search', [
    'q' => 'BrightLocal'
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'q=My+Sample+Query' \   
  https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/search/
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var parameters = new api.Parameters();
parameters.Add("q", "BrightLocal");
var success = request.Get("/v1/clients-and-locations/locations/search", parameters);

Success (200 OK)

{
    "success": true,
    "locations":  [
        {
        "location-id": 1,
            "location-name":"BrightLocal HQ",
            "client-id":1,
        "location-reference":"BL1"
    },
    {
            "location-id": 2,
            "location-name":"Talking Elephant",
            "client-id":12,
            "location-reference":"TE12"
    }
    ]
}

Search for locations matching a specified search string. The search uses a number of fields including location name, contact firstname, lastname and email address.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v1/clients-and-locations/locations/search

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
q Required
client-id Client Id

Local Search Rank Checker

Add Report

Account Method

Add Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/lsrc/add', [
    'name'              => 'Le Bernardin',
    'schedule'          => 'Adhoc',
    'search-terms'      => "Restaurant\nfood+nyc\ndelivery+midtown+manhattan",
    'website-addresses' => '["le-bernardin.com","le-bernardin2.com"]',
    'search-engines'    => 'google,google-mobile,google-local,yahoo,yahoo-local,bing,bing-local'
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'name=Le Bernardin' \
 -d 'schedule=Adhoc' \
 -d $'search-terms=Restaurant\nfood+nyc\ndelivery+midtown+manhattan' \ 
 -d 'website-addresses=["le-bernardin.com","le-bernardin2.com"]' \
 -d 'search-engines=google,google-mobile,google-local,yahoo,yahoo-local,bing,bing-local' \ 
 https://tools.brightlocal.com/seo-tools/api/v2/lsrc/add
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("name", "Le Bernardin");
parameters.Add("schedule", "Adhoc");
parameters.Add("search-terms", "Restaurant\nfood+nyc\ndelivery+midtown+manhattan");
parameters.Add("website-addresses", JsonConvert.SerializeObject("['le-bernardin.com', 'le-bernardin2.com']"));
parameters.Add("search-engines", "google,google-mobile,google-local,yahoo,yahoo-local,bing,bing-local");

var success = request.Post("/v2/lsrc/add", parameters);

Success (200 OK)

{
    "response":  {
        "status": "Report Added",
        "campaign-id": "9907",
        "credits": 298
    }
}

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/lsrc/add

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
name Required
schedule Adhoc, Weekly or Monthly - defaults to Adhoc
day-of-week Relevant to Weekly schedule only. Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday. Defaults to Tuesday.
day-of-month One of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, -1 (last day of month). Defaults to 1
location-id
white-label-profile-id (branding-profile-id is also supported but deprecated)
tags Comma separated list of tags
search-terms Required Newline (\n) separated list of search terms.
website-addresses Supply one or more website addresses (max 10) as a JSON string. For example, [“test.com”,“test2.com”].
website-address (supported but deprecated)
website-address-2 (supported but deprecated)
website-address-3 (supported but deprecated)
country One of USA, GBR, AUS, CAN:EN, CAN:FR. Defaults to USA.
google-location Specify a location to perform search from. When set search keywords do not need to include a location.
bing-location Specify a location to perform search from. When set search keywords do not need to include a location.
business-names Newline (\n) separated list of business names
postcode 80 characters max.
telephone
search-engines Comma separated list of search engines. Options are google, google-mobile, google-local, yahoo, yahoo-local, bing, bing-local. Defaults to all search engines.
include-local-directory-results Yes or No. Defaults to Yes.
notify Yes or No. Defaults to No.
email-addresses Newline (\n) separated list of email addresses
is-public Publish reports on a white label URL. Yes or No. Defaults to No.

Update Report

Account Method

Update Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/lsrc/update', [
    'campaign-id'       => 9907,
    'name'              => 'Le Bernardin',
    'schedule'          => 'Adhoc',
    'search-terms'      => "Restaurant\nfood+nyc\ndelivery+midtown+manhattan",
    'website-addresses' => '["le-bernardin.com","le-bernardin2.com"]',
    'search-engines'    => 'google,google-mobile,google-local,yahoo,yahoo-local,bing,bing-local'
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'campaign-id=9907' \
 -d 'name=Le Bernardin' \
 -d 'schedule=Adhoc' \
 -d $'search-terms=Restaurant\nfood+nyc\ndelivery+midtown+manhattan' \ 
 -d 'website-addresses=["le-bernardin.com","le-bernardin2.com"]' \
 -d 'search-engines=google,google-mobile,google-local,yahoo,yahoo-local,bing,bing-local' \ 
 https://tools.brightlocal.com/seo-tools/api/v2/lsrc/update
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("campaign-id", "9907");
parameters.Add("name", "Le Bernardin");
parameters.Add("schedule", "Adhoc");
parameters.Add("search-terms", "Restaurant\nfood+nyc\ndelivery+midtown+manhattan");
parameters.Add("website-addresses", JsonConvert.SerializeObject("['le-bernardin.com', 'le-bernardin2.com']"));
parameters.Add("search-engines", "google,google-mobile,google-local,yahoo,yahoo-local,bing, bing-local");

var success = request.Post("/v2/lsrc/update", parameters);

Success (200 OK)

{
    "response":  {
        "status": "Report Updated",
        "campaign-id": 9907
    }
}

Change report settings such as name, search terms, country, website URL, schedule etc. Only specify the fields you want to change.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/lsrc/update

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required
name
schedule Adhoc, Weekly or Monthly
day-of-week Relevant to Weekly schedule only. Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday.
day-of-month One of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, -1 (last day of month).
location-id
white-label-profile-id (branding-profile-id is also supported but deprecated)
tags Comma separated list of tags
search-terms Newline (\n) separated list of search terms
website-addresses Supply one or more website addresses (max 10) as a JSON string. For example, [“test.com”,“test2.com”].
website-address (supported but deprecated)
website-address-2 (supported but deprecated)
website-address-3 (supported but deprecated)
country One of USA, GBR, AUS, CAN:EN, CAN:FR.
google-location Specify a location to perform search from. When set search keywords do not need to include a location.
bing-location Specify a location to perform search from. When set search keywords do not need to include a location.
business-names Newline (\n) separated list of business names
postcode 80 characters max.
telephone
search-engines Comma separated list of search engines. Options are google, google-mobile, google-local, yahoo, yahoo-local, bing, bing-local.
include-local-directory-results Yes or No
notify Yes or No
email-addresses Newline (\n) separated list of email addresses
is-public Publish reports on a white label URL. Yes or No.

Delete Report

Account Method

Delete Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->delete('/v2/lsrc/delete', [
    'campaign-id' => 9907
]);
if($success) {
    echo 'Successfully deleted report.' . PHP_EOL;
}
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("campaign-id", "9907");

var success = request.Delete("/v2/lsrc/delete", parameters);

Success (200 OK)

{
    "response":  {
        "status": "Report Deleted"
    }
}

Deletes a report and all history and ranking data associated with that report. Warning: This action cannot be undone.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/lsrc/delete

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required

Get All Reports

Account Method

Get All Reports

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('v2/lsrc/get-all');
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
  https://tools.brightlocal.com/seo-tools/api/v2/lsrc/get-all
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var parameters = new api.Parameters();
var results = request.Get("/v2/lsrc/get-all", parameters);

Success (200 OK)

{
    "response":  {
        "results":  [
            {
                "campaign_id": "49",
                "name": "Test 1",
                "schedule": "Weekly",
                "day_of_week": "Thursday",
                "day_of_month": "0",
                "location_id": "0"
            },
            {
                "campaign_id": "50",
                "name": "Test 2",
                "schedule": "Weekly",
                "day_of_week": "Wednesday",
                "day_of_month": null,
                "location_id": "0"
            },
            {
                "campaign_id": "52",
                "name": "Test 3",
                "schedule": "Weekly",
                "day_of_week": "Wednesday",
                "day_of_month": null,
                "location_id": "0"
            }
        ]
    }
}

Returns basic details about all reports associated with your account.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/lsrc/get-all

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id

Get Report

Account Method

Get Single Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/lsrc/get', [
    'campaign-id' => 50
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'campaign-id=50' \
  https://tools.brightlocal.com/seo-tools/api/v2/lsrc/get
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("campaign-id", "50");

var results = request.Get("/v2/lsrc/get", parameters);

Success (200 OK)

{
    "response":  {
        "result":  {
            "campaign_id": "50",
            "customer_id": "35",
            "white_label_profile_id": "19",
            "location_id": "19",
            "name": "Test Pub",
            "schedule": "Weekly",
            "day_of_week": "Wednesday",
            "day_of_month": null,
            "search_terms":  [
                "pub fulham",
                "pub in fulham",
                "london pub",
                "pub putney",
                "beer garden in fulham",
                "gastro pub fulham",
                "pubs in fulham",
                "fulham pubs",
                "nice pub fulham",
                "good pub fulham",
                "nice pubs fulham",
                "good pubs fulham",
                "best pubs fulham",
                "excellent pubs fulham",
                "lovely fulham pub",
                "lovely fulham pubs",
                "fulham lovely pubs",
                "close pub fulham",
                "fulham with pubs",
                "pubs around fulham",
                "pubs fulham broadway",
                "pub fulham broadway"
            ],
            "ppc_search_terms": null,
            "lookup_ppc": "No",
            "website-addresses": [
                "http://www.testpub.com/"
            ],
            "website_address": "http://www.testpub.com/",
            "website_address_2": null,
            "website_address_3": null,
            "country": "GBR",
            "google_location": "",
            "bing_location": null,
            "business_names":  [
                "Test Pub"
            ],
            "postcode": "TEST TEST",
            "telephone": "0123456789",
            "search_engines":  [
                "google",
                "google-local",
                "yahoo",
                "yahoo-local",
                "bing",
                "bing-local"
            ],
            "include_local_directory_results": "Yes",
            "notify": "Yes",
            "email_addresses": "test@testpub.com",
            "created": "2011-04-15",
            "last_processed": "2013-07-18",
            "last_message": "",
            "currently_running": "No",
            "status": "Enabled",
            "red_flag": "No",
            "is_public": "No",
            "public_key": null,
            "tags":  [
                "fulham",
                "london",
                "pub"
            ]
        }
    }
}

Returns information about the specified report such as its name, search terms, country, website URL, schedule etc. You can also use this method to find out if a report is currently running (currently_running = Yes) or if the latest run failed (red_flag = Yes).

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/lsrc/get

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required

Run Report

Account Method

Run Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/lsrc/run', [
    'campaign-id' => 50
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'campaign-id=50' \
  https://tools.brightlocal.com/seo-tools/api/v2/lsrc/run
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("campaign-id", "50");

var success = request.Post("/v2/lsrc/run", parameters);

Success (200 OK)

{
    "response":  {
        "status": "Report Run",
        "campaign-id": 50,
        "credits": 298
    }
}

Runs the specified report if your account has sufficient monthly adhoc run credits.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/lsrc/run

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required

Get Report History

Account Method

Get Report History

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/lsrc/history/get', [
    'campaign-id' => 50,
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'campaign-id=50' \
  https://tools.brightlocal.com/seo-tools/api/v2/lsrc/history/get
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("campaign-id", "50");

var results = request.Get("/v2/lsrc/history/get", parameters);

Success (200 OK)

{
    "response":  {
        "results":  [
            {
                "campaign_history_id": "25554",
                "campaign_id": "50",
                "location_id": "5",
                "history_type": "Scheduled",
                "generation_date": "2013-07-18 13:42:32"
            },
            {
                "campaign_history_id": "25499",
                "campaign_id": "50",
                "location_id": "5",
                "history_type": "Scheduled",
                "generation_date": "2013-07-18 11:29:50"
            },
            {
                "campaign_history_id": "25439",
                "campaign_id": "50",
                "location_id": "5",
                "history_type": "Scheduled",
                "generation_date": "2013-07-18 11:17:48"
            }
        ]
    }
}

Returns the campaign history IDs associated with all report runs for the specified report (adhoc or scheduled). These IDs can be passed to the “Get Report Results” method to return report URLs and actual ranking data.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/lsrc/history/get

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required

Get Report Results

Account Method

Get Report Results

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/lsrc/results/get', [
    'campaign-id' => 9636
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'campaign-id=9636' \
  https://tools.brightlocal.com/seo-tools/api/v2/lsrc/results/get

Get Report Results

api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("campaign-id", "9636");

var results = request.Get("/v2/lsrc/results/get", parameters);

Success (200 OK)

{
  "response": {
    "result": {
      "campaign_details": {
        "campaign_id": "9636",
        "customer_id": "1",
        "white_label_profile_id": "24",
        "location_id": "0",
        "name": "Alaska Bar Association",
        "schedule": "Adhoc",
        "day_of_week": "Monday",
        "day_of_month": "18",
        "search_terms": [
          "Alaska Bar Association"
        ],
        "ppc_search_terms": "",
        "lookup_ppc": "No",
        "website_addresses": [
          "https://www.alaskabar.org/"
        ],
        "country": "USA",
        "google_location": "Alaska",
        "bing_location": "",
        "previous_bing_location": null,
        "business_names": [
          ""
        ],
        "postcode": "",
        "telephone": "",
        "search_engines": [
          "google",
          "google-local",
          "yahoo",
          "yahoo-local",
          "bing",
          "bing-local"
        ],
        "include_local_directory_results": "No",
        "notify": "No",
        "email_addresses": "test@testpub.com",
        "created": "2016-01-18",
        "last_processed": "2016-02-01",
        "last_message": "",
        "currently_running": "No",
        "status": "Enabled",
        "red_flag": "No",
        "is_public": "Yes",
        "public_key": "<hidden>",
        "show_advanced_settings": "No",
        "last_batch_id": "2444",
        "tags": []
      },
      "urls": {
        "interactive_url": "https://tools.brightlocal.com/seo-tools/admin/lsrc/reports/interactive/9636",
        "pdf_url": "https://tools.brightlocal.com/seo-tools/admin/lsrc/reports/pdf/9636.pdf",
        "csv_url": "https://tools.brightlocal.com/seo-tools/admin/lsrc/reports/csv/9636.csv",
        "public_interactive_url": "http://www.local-marketing-reports.com/ranking-reports/<hidden>/9636",
        "public_pdf_url": "http://www.local-marketing-reports.com/ranking-reports/<hidden>/9636.pdf",
        "public_csv_url": "http://www.local-marketing-reports.com/ranking-reports/<hidden>/9636.csv"
      },
      "rankings": {
        "keywords": [
          "Alaska Bar Association"
        ],
        "keywords_num_rankings": {
          "Alaska Bar Association": "2"
        },
        "starred_keywords": {
          "Alaska Bar Association": true
        },  
        "extra_results": {
          "Alaska Bar Association": ["local", "video"]
        },
        "search_engines": [
          "google",
          "google-places",
          "yahoo",
          "yahoo-local",
          "bing",
          "bing-local"
        ],
        "rankings": {
          "Alaska Bar Association": {
            "google": [
              {
                "id": "11764",
                "url": "https://alaskabar.org/",
                "orig_url": "https://www.alaskabar.org/",
                "rank": "1",
                "page": "1",
                "type": "Organic",
                "match": "website address",
                "directory": null,
                "date": "2016-02-01 19:00:24",
                "hash": "32d3f35ad7633a34b2cf93dec7dfdd2455d25f84",
                "search_url": "https://www.google.com/search?q=Alaska+Bar+Association&gl=us&gws_rd=cr&uule=w+CAIQICIGQWxhc2th&pws=0",
                "search_engine": "google",
                "last": "1"
              }
            ],
            "google-places": [
              {
                "id": "11766",
                "url": "http://alaskabar.org/",
                "orig_url": "http://www.alaskabar.org/",
                "rank": "1",
                "page": "1",
                "type": "Places",
                "match": "website address",
                "directory": null,
                "date": "2016-02-01 19:00:24",
                "hash": "e008f8d346b2b8f124702d64be0ec1131adba959",
                "search_url": "https://www.google.com/search?tbm=lcl&q=Alaska+Bar+Association&gl=us&gws_rd=cr&uule=w+CAIQICIGQWxhc2th",
                "search_engine": "google-places",
                "last": "1"
              }
            ],
            "yahoo": [
              {
                "id": "11767",
                "url": "http://alaskabar.org/",
                "orig_url": "http://www.alaskabar.org/",
                "rank": "1",
                "page": "1",
                "type": "Organic",
                "match": "website address",
                "directory": null,
                "date": "2016-02-01 19:00:24",
                "hash": "b9ea2849328aa0794c79a60beb6cee38c2a51a67",
                "search_url": "http://search.yahoo.com/search?p=Alaska+Bar+Association",
                "search_engine": "yahoo",
                "last": "1"
              },
              {
                "id": "11768",
                "url": "https://alaskabar.org/servlet/content/46.html",
                "orig_url": "https://www.alaskabar.org/servlet/content/46.html",
                "rank": "6",
                "page": "1",
                "type": "Organic",
                "match": "website address",
                "directory": null,
                "date": "2016-02-01 19:00:24",
                "hash": "e0610efd9a75c627c2f9a8bc1b86680d5064b71d",
                "search_url": "http://search.yahoo.com/search?p=Alaska+Bar+Association",
                "search_engine": "yahoo",
                "last": "6"
              }
            ],
            "yahoo-local": [
              {
                "id": "11769",
                "url": "",
                "orig_url": "",
                "rank": "0",
                "page": "0",
                "type": "",
                "match": "",
                "directory": null,
                "date": "2016-02-01 19:00:24",
                "hash": null,
                "search_url": "https://search.yahoo.com/local/?p=Alaska+Bar+Association",
                "search_engine": "yahoo-local"
              }
            ],
            "bing": [
              {
                "id": "11770",
                "url": "http://alaskabar.org/",
                "orig_url": "http://www.alaskabar.org/",
                "rank": "1",
                "page": "0",
                "type": "Organic",
                "match": "website address",
                "directory": null,
                "date": "2016-02-01 19:00:24",
                "hash": "bbd31c444764b5dd44685b5eae35578bbef68166",
                "search_url": "http://www.bing.com/search?q=Alaska+Bar+Association&mkt=en-us&count=50",
                "search_engine": "bing",
                "last": "1"
              }
            ],
            "bing-local": [
              {
                "id": "11771",
                "url": "",
                "orig_url": "",
                "rank": "0",
                "page": "0",
                "type": "",
                "match": "",
                "directory": null,
                "date": "2016-02-01 19:00:24",
                "hash": null,
                "search_url": "http://www.bing.com/local/default.aspx?q=Alaska+Bar+Association&mkt=en-us&FORM=LLSV",
                "search_engine": "bing-local"
              }
            ]
          }
        },
        "hashes": {
          "google": {
            "Alaska Bar Association": [
              "32d3f35ad7633a34b2cf93dec7dfdd2455d25f84"
            ]
          },
          "google-places": {
            "Alaska Bar Association": [
              "e008f8d346b2b8f124702d64be0ec1131adba959"
            ]
          },
          "yahoo": {
            "Alaska Bar Association": [
              "b9ea2849328aa0794c79a60beb6cee38c2a51a67",
              "e0610efd9a75c627c2f9a8bc1b86680d5064b71d"
            ]
          },
          "yahoo-local": {
            "Alaska Bar Association": []
          },
          "bing": {
            "Alaska Bar Association": [
              "bbd31c444764b5dd44685b5eae35578bbef68166"
            ]
          },
          "bing-local": {
            "Alaska Bar Association": []
          }
        },
        "byPosition": {
          "Position 1": {
            "Alaska Bar Association||google||Organic": {
              "id": "11764",
              "url": "https://alaskabar.org/",
              "orig_url": "https://www.alaskabar.org/",
              "rank": "1",
              "page": "1",
              "type": "Organic",
              "match": "website address",
              "directory": null,
              "date": "2016-02-01 19:00:24",
              "hash": "32d3f35ad7633a34b2cf93dec7dfdd2455d25f84",
              "search_url": "https://www.google.com/search?q=Alaska+Bar+Association&gl=us&gws_rd=cr&uule=w+CAIQICIGQWxhc2th&pws=0",
              "search_engine": "google"
            },
            "Alaska Bar Association||google-places||Places": {
              "id": "11766",
              "url": "http://alaskabar.org/",
              "orig_url": "http://www.alaskabar.org/",
              "rank": "1",
              "page": "1",
              "type": "Places",
              "match": "website address",
              "directory": null,
              "date": "2016-02-01 19:00:24",
              "hash": "e008f8d346b2b8f124702d64be0ec1131adba959",
              "search_url": "https://www.google.com/search?tbm=lcl&q=Alaska+Bar+Association&gl=us&gws_rd=cr&uule=w+CAIQICIGQWxhc2th",
              "search_engine": "google-places"
            },
            "Alaska Bar Association||yahoo||Organic": {
              "id": "11767",
              "url": "http://alaskabar.org/",
              "orig_url": "http://www.alaskabar.org/",
              "rank": "1",
              "page": "1",
              "type": "Organic",
              "match": "website address",
              "directory": null,
              "date": "2016-02-01 19:00:24",
              "hash": "b9ea2849328aa0794c79a60beb6cee38c2a51a67",
              "search_url": "http://search.yahoo.com/search?p=Alaska+Bar+Association",
              "search_engine": "yahoo"
            },
            "Alaska Bar Association||bing||Organic": {
              "id": "11770",
              "url": "http://alaskabar.org/",
              "orig_url": "http://www.alaskabar.org/",
              "rank": "1",
              "page": "0",
              "type": "Organic",
              "match": "website address",
              "directory": null,
              "date": "2016-02-01 19:00:24",
              "hash": "bbd31c444764b5dd44685b5eae35578bbef68166",
              "search_url": "http://www.bing.com/search?q=Alaska+Bar+Association&mkt=en-us&count=50",
              "search_engine": "bing"
            }
          },
          "Positions 2-5": [],
          "Positions 6-10": [],
          "Positions 11-20": [],
          "Positions 21-50": [],
          "Positions 51+": {
            "Alaska Bar Association||yahoo-local||": {
              "id": "11769",
              "url": "",
              "orig_url": "",
              "rank": "0",
              "page": "0",
              "type": "",
              "match": "",
              "directory": null,
              "date": "2016-02-01 19:00:24",
              "hash": null,
              "search_url": "https://search.yahoo.com/local/?p=Alaska+Bar+Association",
              "search_engine": "yahoo-local"
            },
            "Alaska Bar Association||bing-local||": {
              "id": "11771",
              "url": "",
              "orig_url": "",
              "rank": "0",
              "page": "0",
              "type": "",
              "match": "",
              "directory": null,
              "date": "2016-02-01 19:00:24",
              "hash": null,
              "search_url": "http://www.bing.com/local/default.aspx?q=Alaska+Bar+Association&mkt=en-us&FORM=LLSV",
              "search_engine": "bing-local"
            }
          }
        },
        "summary": {
          "all_search_engines": {
            "up": 0,
            "down": 0,
            "no_change": 6,
            "gained_hashes": [],
            "lost_hashes": []
          },
          "google": {
            "up": 0,
            "down": 0,
            "no_change": 1,
            "gained_hashes": [],
            "lost_hashes": []
          },
          "google-places": {
            "up": 0,
            "down": 0,
            "no_change": 1,
            "gained_hashes": [],
            "lost_hashes": []
          },
          "yahoo": {
            "up": 0,
            "down": 0,
            "no_change": 2,
            "gained_hashes": [],
            "lost_hashes": []
          },
          "yahoo-local": {
            "up": 0,
            "down": 0,
            "no_change": 0,
            "gained_hashes": [],
            "lost_hashes": []
          },
          "bing": {
            "up": 0,
            "down": 0,
            "no_change": 1,
            "gained_hashes": [],
            "lost_hashes": []
          },
          "bing-local": {
            "up": 0,
            "down": 0,
            "no_change": 0,
            "gained_hashes": [],
            "lost_hashes": []
          }
        }
      },
      "serp-screenshots": {
        "google": {
          "Alaska Bar Association": {
            "1": {
              "url": "https://brightlocal-serp-pages.s3.amazonaws.com/2016/02/01/18/a7cf190f51b2572fa166803bec9bb07920d3c678.png",
              "expiry_date": "2016-03-17 19:00:24"
            },
            "2": {
              "url": "https://brightlocal-serp-pages.s3.amazonaws.com/2016/02/01/18/e7cd9afb659ecd572c59f4556ae6f1bcf2cac665.png",
              "expiry_date": "2016-03-17 19:00:24"
            },
            "3": {
              "url": "https://brightlocal-serp-pages.s3.amazonaws.com/2016/02/01/18/593e4e97b9780de2e71e3581f1a47d784deb1c4c.png",
              "expiry_date": "2016-03-17 19:00:24"
            },
            "4": {
              "url": "https://brightlocal-serp-pages.s3.amazonaws.com/2016/02/01/18/6ddb19e8c10b899aeee8e4b11d5a8a6fa1129ebd.png",
              "expiry_date": "2016-03-17 19:00:24"
            },
            "5": {
              "url": "https://brightlocal-serp-pages.s3.amazonaws.com/2016/02/01/18/a404cc8a6c30f81a0744d6661f2004b7bcfa2a34.png",
              "expiry_date": "2016-03-17 19:00:24"
            }
          }
        }
      }
    }
  }
}

If no campaign history ID or previous campaign history ID are passed then the latest results for the specified report are returned.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/lsrc/results/get

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required
campaign-history-id If both campaign-history-id and previous-campaign-history-id are not specified then the latest report is returned.
previous-campaign-history-id If both campaign-history-id and previous-campaign-history-id are not specified then the latest report is returned.

Local SEO Check-up

Add Report

Account Method

Add Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v4/lscu', [
    'report-name'               => 'Sample SEO Check-Up Report',
    'business-names'            => ["Le Bernardin"],
    'website-address'           => "le-bernardin.com",
    'address1'                  => '155 West 51st Street',
    'address2'                  => '',
    'city'                      => 'New York',
    'state-code'                => 'NY',
    'postcode'                  => '10019',
    'telephone'                 => '+1 212-554-1515',
    'country'                   => 'USA',
    'business-category'         => 'Restaurant',
    'primary-business-location' => 'NY, New York',
    'search-terms'              => ["restaurant manhattan","cafe new york"]
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \ 
 -d 'report-name=Sample SEO Check-Up Report' \
 -d 'business-names=["Le Bernardin"]' \
 -d 'address1=155 West 51st Street' \ 
 -d 'address2=' \
 -d 'city=New York' \
 -d 'state-code=NY' \ 
 -d 'postcode=10019' \
 -d 'telephone=+1 212-554-1515'
 -d 'country=USA' \
 -d 'business-category=Restaurant' \
 -d 'primary-business-location=NY+NewYork'
 -d 'search-terms=["restaurant manhattan","cafe new york"]'
 https://tools.brightlocal.com/seo-tools/api/v4/lscu
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-name", "Sample SEO Check-Up Report");
parameters.Add("business-names", JsonConvert.SerializeObject("['Le Bernardin']"));
parameters.Add("website-address", "le-bernardin.com");
parameters.Add("address1", "155 Weest 51st Street");
parameters.Add("address2", "");
parameters.Add("city", "New York");
parameters.Add("state-code", "NY");
parameters.Add("postcode", "10019");
parameters.Add("telephone", "+1 212-554-1515");
parameters.Add("country", "USA");
parameters.Add("business-category", "Restaurant");
parameters.Add("primary-business-location", "NY, New York");
parameters.Add("search-terms", JsonConvert.SerializeObject("['restaurant manhattan', 'cafe new york']"));

var success = request.Post("/v4/lscu", parameters);

Supplying Local Directory URLs (see local-directory-urls parameter)

<?php
echo json_encode(array(
   'citysearch' => array(
       'url'     => 'http://www.yelp.co.uk/biz/greens-restaurant-san-francisco-3',
       'include' => 'yes'
   ),
   'dexknows'   => array(
       'url'     => ''
       'include' => 'yes'
   ),
   'kudzu'      => array(
       'url'     => '',
       'include' => 'yes'
   )
));
var localDirectories = new List<dynamic>();
localDirectories.Add(new
{
    yellowbot = new
    {
        url = "http://www.yellowbot.com/le-bernardin-new-york-ny.html",
        include = "yes"
    },
    yellowpages = new
    {
        url = "http://www.yellowpages.com/new-york-ny/mip/le-bernardin-9909153",
        include = "yes"
    },
    yelp = new
    {
        url = "",
        include = "yes"
    }
});

Success (201 Created)

{
    "success": true,
    "report-id": "1"
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_NAME": "Report name missing",
    "INVALID_BUSINESS_NAMES": "Business names missing (at least one must be supplied)",
    "INVALID_WEBSITE_ADDRESS": "Website address missing",
    "INVALID_TELEPHONE": "Telephone number missing",
    "INVALID_ADDRESS1": "Address line 1 missing",
    "INVALID_CITY": "City missing",
    "INVALID_COUNTRY": "Country missing",
    "INVALID_STATE_CODE": "State code missing",
    "INVALID_POSTCODE": "Postcode/ZIP missing",
    "INVALID_BUSINESS_CATEGORY": "Business category missing",
    "INVALID_PRIMARY_BUSINESS_LOCATION": "Primary business location missing",
    "INVALID_SEARCH_TERMS": "Search terms missing (please supply at least one)",
    "INVALID_GOOGLE_LOCATION": "Google location missing"
  }
}

Adds a new Local SEO Check-up report to your account.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/lscu

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-name Required
location-id Associate this report with a location in your account. This ID needs to correspond to a valid location in your account.
white-label-profile-id Assign a white label profile to this report. The ID needs to correspond to a valid white label profile in your account.
business-names Required Supply one or more busines names (max 5) as a JSON string. For example, [“Greens Restaurant”,“Greens”].
website-address Required The address for your business website. 256 characters max.
address1 Required 80 characters max.
address2 80 characters max.
area The neighborhood or district for the business. For example, Charleston or Fulham.
city Required
state-code Required (USA, CAN:EN and AUS)
postcode Required A valid postcode or ZIP. 80 characters max.
telephone Required
country Required One of USA, CAN:EN, GBR or AUS.
business-category Required The type of business - for example, Plumber (not Plumbing & Heating Services).
primary-business-location Required The primary location served by the business. Enter town name and state code - for example, Chicago, IL.
search-terms Required Supply one or more search terms (max 5) as a JSON string. For example, [“restaurant san francisco”,“cafe san francisco”].
google-location A valid google search location. Please refer to our location check method.
bing-location A valid bing search location. Please refer to our location check method.
notify One of yes or no. If set to yes we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Default is no.
email-addresses Supply one or more (max 5) email addresses for us to send report alerts to. This only takes effect if notify is set to yes.
facebook-url If known, please supply the Facebook URL for the business. If not supplied we’ll try and find it on the business website or through a direct search of Facebook.
twitter-url If known, please supply the Twitter URL for the business. If not supplied we’ll try and find it on the business website or through through a direct search of Twitter.
is-public Determines whether or not to make the report available on a public URL you can give to your customers. One of yes or no. Defaults to no.
local-directory-urls

By default we try and find local directory profile URLs and information for your business in all directories we support. If you’d like your report to only contain specific directories or already know the profile URLs for some directories you can supply them here. Please note that if you supply information for this parameter you need to give us all details of the directories you want included. If you have profile URLs for some but not others you can leave those URL fields empty and we’ll do our best to find them. Generally we recommend you run your report for the first time without this setting and then use our update method to add/change URLs or remove directories if needed.

The data for this parameter needs to be supplied as a JSON string. Local directory identifiers (the keys in the example below) are documented here.

run-report One of yes or no. Runs the report after adding. Defaults to no.

Update Report

Account Method

Update Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->put('/v4/lscu', [
    'postcode'                  => '10019',
    'telephone'                 => '+1 212-554-1515',
    'country'                   => 'USA',
    'business-category'         => 'Restaurant',
    'primary-business-location' => 'NY, New York',
    'search-terms'              => '["restaurant manhattan","cafe new york"]'
]);
print_r($success);
curl -X PUT \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'postcode=10019' \
 -d 'telephone=+1 212-554-1515'
 -d 'country=USA' \
 -d 'business-category=Restaurant' \
 -d 'primary-business-location=NY+NewYork'
 -d 'search-terms=["restaurant manhattan","cafe new york"]'
 https://tools.brightlocal.com/seo-tools/api/v4/lscu
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-id", "1");
parameters.Add("postcode", "10019");
parameters.Add("telephone", "+1 212-554-1515");
parameters.Add("country", "USA");
parameters.Add("business-category", "Restaurant");
parameters.Add("primary-business-location", "NY, New York");
parameters.Add("search-terms", JsonConvert.SerializeObject("['restaurant manhattan', 'cafe new york']"));

var success = request.Put("/v4/lscu", parameters);

Supplying Local Directory URLs (see local-directory-urls parameter)

<?php
echo json_encode(array(
   'citysearch' => array(
       'url'     => 'http://www.yelp.co.uk/biz/greens-restaurant-san-francisco-3',
       'include' => 'yes'
   ),
   'dexknows'   => array(
       'url'     => ''
       'include' => 'yes'
   ),
   'kudzu'      => array(
       'url'     => '',
       'include' => 'yes'
   )
));
var localDirectories = new List<dynamic>();
localDirectories.Add(new
{
    yellowbot = new
    {
        url = "http://www.yellowbot.com/le-bernardin-new-york-ny.html",
        include = yes
    },
    yellowpages = new
    {
        url = "http://www.yellowpages.com/new-york-ny/mip/le-bernardin-9909153",
        include = yes
    },
    yelp = new
    {
        url = "",
        include = yes
    }
});

Success (200 OK)

{
    "success": true
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID": "Report ID missing"
  }
}

Failure when report running (400 Bad Request)

{
    "success": false,
    "errors":  {
      "REPORT_RUNNING": "Report is running"
    }
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v4/lscu

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required
report-name
location-id Associate this report with a location in your account. This ID needs to correspond to a valid location in your account.
white-label-profile-id Assign a white label profile to this report. The ID needs to correspond to a valid white label profile in your account.
business-names Supply one or more busines names (max 5) as a JSON string. For example, [“Greens Restaurant”,“Greens”].
website-address The address for your business website. 256 characters max.
address1 80 characters max.
address2 80 characters max.
area The neighborhood or district for the business. For example, Charleston or Fulham.
city
state-code (USA, CAN:EN and AUS)
postcode A valid postcode or ZIP. 80 characters max.
telephone
country One of USA, CAN:EN, GBR or AUS.
business-category The type of business - for example, Plumber (not Plumbing & Heating Services).
primary-business-location The primary location served by the business. Enter town name and state code - for example, Chicago, IL.
search-terms Supply one or more search terms (max 5) as a JSON string. For example, [“restaurant san francisco”,“cafe san francisco”].
google-location A valid google search location. Please refer to our location check method.
bing-location A valid bing search location. Please refer to our location check method.
notify One of yes or no. If set to yes we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Default is no.
email-addresses Supply one or more (max 5) email addresses for us to send report alerts to. This only takes effect if notify is set to yes.
facebook-url If known, please supply the Facebook URL for the business. If not supplied we’ll try and find it on the business website or through a direct search of Facebook.
twitter-url If known, please supply the Twitter URL for the business. If not supplied we’ll try and find it on the business website or through through a direct search of Twitter.
is-public Determines whether or not to make the report available on a public URL you can give to your customers. One of yes or no. Defaults to no.
local-directory-urls

This parameter allows you update the profile URLs we have stored for your business on each local directory, to exclude a directory from subsequent report runs or include one that isn’t currently present. You can also manually supply profile URLs to correct ones that are incorrect or where we haven’t been able to automatically find the relevant profile URL. All changes require the report to be re-run before they take effect.

The data for this parameter needs to be supplied as a JSON string. Local directory identifiers (the keys in the example below) are documented here. Here’s an example of how to generate suitable values in PHP:

Get Report

Account Method

Get Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/lscu', [
    'report-id' => 860
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=860' \
  https://tools.brightlocal.com/seo-tools/api/v4/lscu
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-id", "860");

var results = request.Get("/v4/lscu", parameters);

Success (200 OK)

{
  "success": true,
  "report":  {
    "report_id": "860",
    "customer_id": "35",
    "location_id": "0",
    "company_name": null,
    "name": "McCormick & Schmick's",
    "white_label_profile_id": "59",
    "business_names": "McCormick & Schmick's",
    "website_address": "http://www.mccormickandschmicks.com",
    "telephone": "+1 312-923-7226",
    "address_1": "1 E Upper Wacker Dr",
    "address_2": "",
    "area": "",
    "city": "Chicago",
    "state_code": "IL",
    "postcode": "60601",
    "country": "USA",
    "business_category": "restaurant",
    "primary_business_location": "chicago, il",
    "search_terms": "restuarant chicago\r\ncafe chicago",
    "notify": "No",
    "email_addresses": "<hidden>",
    "date_added": "2014-07-29 10:08:41",
    "last_start_time": "2014-07-29 10:10:25",
    "last_end_time": "2014-07-29 10:44:39",
    "last_message": "Report generated successfully",
    "generation_error": "No",
    "currently_running": "No",
    "facebook": "http://www.facebook.com/mccormickandschmicks",
    "twitter": "http://twitter.com/McandSchmicks",
    "google_location": "chicago, il",
    "bing_location": "",
    "previous_bing_location": null,
    "is_public": "Yes",
    "public_key": "<hidden>",
    "latest_run":  {
      "interactive_url": "https://tools.brightlocal.com/seo-tools/admin/lscu/reports/view/858/2171",
      "pdf_url": "https://tools.brightlocal.com/seo-tools/admin/lscu/reports/pdf/858",
      "public_interactive_url": "http://www.local-marketing-reports.com/seo-reports/<hidden>/858",
      "public_pdf_url": "http://www.local-marketing-reports.com/seo-reports/<hidden>/858.pdf"
    }
  }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/lscu

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required The unique ID for the report in your account.

Run Report

Account Method

Run Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->put('/v4/lscu/run', [
    'report-id' => 860
]);
print_r($results);
curl -X PUT \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=860' \
  https://tools.brightlocal.com/seo-tools/api/v4/lscu/run
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-id", "860");

var success = request.Put("/v4/lscu/run", parameters);

Success (200 OK)

{
    "success": true
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing",
    "NO_CREDITS" : "You don't have any credits left"
  }
}

Failure when report already running (400 Bad Request)

{
    "success": false,
    "errors":  {
      "REPORT_RUNNING": "Report is already running"
    }
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v4/lscu/run

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required The unique ID for the report in your account.

Delete Report

Account Method

Delete Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->delete('/v4/lscu', [
    'report-id' => 860
]);
if($success) {
    echo 'Successfully deleted report.' . PHP_EOL;
}
print_r($success);
curl -X DELETE \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=860' \
  https://tools.brightlocal.com/seo-tools/api/v4/lscu
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-id", "860");

var success = request.Delete("/v4/lscu", parameters);

Success (200 OK)

{
    "success": true
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID": "Report ID missing"
  }
}

Failure when report running (400 Bad Request)

{
    "success": false,
    "errors":  {
      "REPORT_RUNNING": "Report is running"
    }
}

HTTP Request

DELETE https://tools.brightlocal.com/seo-tools/api/v4/lscu

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required The unique ID for the report in your account.

Account Method

Search for a Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/lscu/search', [
    'q' => 'Bodega Wine Bar'
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'q=Bodega+Wine+Bar' \
  https://tools.brightlocal.com/seo-tools/api/v4/lscu/search

Search Reports

api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("q", "Bodega Wine Bar");

var results = request.Get("/v4/lscu/search", parameters);

Success (200 OK)

{
  "success": true,
  "reports":  [
     {
      "report_id": "839",
      "report_name": "Bodega Wine Bar",
      "location_id": "14580",
      "date_added": "2014-01-16 12:50:46",
      "last_run_date": "2014-01-16 12:58:58",
      "last_message": "Report generated successfully",
      "currently_running": "No"
    },
     {
      "report_id": "858",
      "report_name": "Bodega Wine Bar",
      "location_id": "14580",
      "date_added": "2014-06-26 07:46:21",
      "last_run_date": "2014-07-28 16:11:14",
      "last_message": "Report generated successfully",
      "currently_running": "No"
    }
  ]
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_SEARCH": "Search string missing"
  }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/lscu/search

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
q Supply an arbitrary search string. We search in location and report names for matches.

Citation Tracker

Add Report

Account Method

Add Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/ct/add', [
    'report-name'       => 'Le Bernardin',
    'business-name'     => 'Le Bernardin',
    'business-location' => 'New York, NY',
    'postcode'          => '10020',
    'phone'             => '+1 212-554-1515',
    'website'           => 'le-bernardin.com',
    'business-type'     => 'Restaurant',
    'state-code'        => 'NY',
    'primary_location' => '10020',
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-name=Le Bernardin' \
 -d 'business-name=Le Bernardin' \
 -d 'business-location=New York, NY' \ 
 -d 'phone=+1 212-554-1515' \
 -d 'postcode=10020' \
 -d 'website=le-bernardin.com' \ 
 -d 'business-type=Restaurant' \
 -d 'state-code=NY' \
 -d 'primary_location=10020' \
 https://tools.brightlocal.com/seo-tools/api/v2/ct/add
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-name", "Sample Citation Tracking Report");
parameters.Add("business-name", "Le Bernardin");
parameters.Add("business-location", "NY, New York");
parameters.Add("phone", "+1 212-554-1515");
parameters.Add("postcode", "10020");
parameters.Add("website", "le-bernardin.com");
parameters.Add("business-type", "Restaurant");
parameters.Add("state-code", "NY");
parameters.Add("primary_location", "10020");

var success = request.Post("/v2/ct/add", parameters);

Success (200 OK)

{
    "response":  {
        "status": "added",
        "report-id": 682
    }
}

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/ct/add

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id You can specify location ID or unique reference to create report for a location
report-name Required
business-name Required
business-location Required Town or city name in which business is located.
old-business-name-1
old-business-name-2
postcode Required 80 characters max.
old-postcode-1
old-postcode-2
country One of USA, GBR, CAN, AUS. Defaults to USA.
phone Required
website Required Link to the website of your business. 256 characters max.
business-type Required Business type (e.g. Hotel) NOT a business category (e.g. Hotels & Guest houses).
state-code Required (USA only). 2-letter state code (USA only).
monthly-run One of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31. Defaults to 0 (none).
weekly-run One of 1, 2, 3, 4, 5, 6, 7. Defaults to 0 (none).
white-label-profile-id
active-only Flag to fetch only active citations. One of Yes, No. Defaults to No. This cannot be changed once the report has been added.
notify One of yes or no. If set to yes we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Default is no.
email-addresses Supply one or more (max 5) email addresses for us to send report alerts to. Emails should be passed as a JSON encoded array. This only takes effect if notify is set to yes.
is-public Publish reports on a white label URL. Yes or No.
primary-location Required We use ‘Location’ to identify your top 10 ‘Google+ Local’ competitors. Please enter your city/town name or zip/postcode. Note: for US businesses we strongly recommend that you use only 5 digit zips (99750, NOT 99750-0077) as using the longer format can make it harder for us to find competitors.

Update Report

Account Method

Update Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/ct/update', [
    'report-id'         => 682,
    'report-name'       => 'Le Bernardin',
    'business-name'     => 'Le Bernardin',
    'business-location' => 'New York, NY',
    'phone'             => '+1 212-554-1515',
    'website'           => 'le-bernardin.com',
    'business-type'     => 'Restaurant',
    'state-code'        => 'NY' 
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id'=682,
 -d 'report-name=Le Bernardin' \
 -d 'business-name=Le Bernardin' \
 -d 'business-location=New York, NY' \ 
 -d 'phone=+1 212-554-1515' \
 -d 'website=le-bernardin.com' \ 
 -d 'business-type=Restaurant' \
 -d 'state-code=NY' \
 https://tools.brightlocal.com/seo-tools/api/v2/ct/update
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-id", 682);
parameters.Add("report-name", "Sample Citation Tracking Report");
parameters.Add("business-name", "Le Bernardin");
parameters.Add("business-location", "NY, New York");
parameters.Add("phone", "+1 212-554-1515");
parameters.Add("website", "le-bernardin.com");
parameters.Add("business-type", "Restaurant");
parameters.Add("state-code", "NY");

var success = request.Post("/v2/ct/update", parameters);

Success (200 OK)

{
    "response":  {
        "status": "edited"
    }
}

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/ct/update

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id You can specify location ID or unique reference to create report for a location.
report-id Required
report-name
business-name
business-location Town or city name in which business is located.
old-business-name-1
old-business-name-2
postcode 80 characters max.
old-postcode-1
old-postcode-2
country One of USA, GBR, CAN, AUS. Defaults to USA.
phone
website Link to the website of your business. 256 characters max.
business-type Business type (e.g. Hotel) NOT a business category (e.g. Hotels & Guest houses).
location
state-code 2-letter state code (USA only).
monthly-run One of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31. Defaults to 0 (none).
weekly-run One of 1, 2, 3, 4, 5, 6, 7. Defaults to 0 (none).
white-label-profile-id
active-only Flag to fetch only active citations. One of Yes, No. Defaults to No.
notify One of yes or no. If set to yes we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Default is no.
email-addresses Supply one or more (max 5) email addresses for us to send report alerts to. Emails should be passed as a JSON encoded array. This only takes effect if notify is set to yes.
is-public Publish reports on a white label URL. Yes or No.

Get Report

Account Method

Get Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/ct/get', [
    'report-id' => 682 
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=682' \
 https://tools.brightlocal.com/seo-tools/api/v2/ct/get
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
        parameters.Add("report-id", "682");

var results = request.Get("/v2/ct/get", parameters);

Success (200 OK)

{
    "success": true,
    "report": {
        "report_id": "255565",
        "customer_id": "88",
        "location_id": "1",
        "weekly_run": "3",
        "monthly_run": "0",
        "report_name": "The View",
        "website_address": "www.ullubatanc.com",
        "business_name": "Ullu Bata Inc.",
        "business_location": "London",
        "postcode": "ABCD1234",
        "country": "GBR",
        "state_code": null,
        "address1": "",
        "address2": "",
        "telephone": "01273 207 100",
        "business_type": "Restaurant",
        "primary_location": "Brighton",
        "last_run_id": "1185703",
        "old_business_name_1": "View Hove",
        "old_postcode_1": "01273 207 037",
        "old_business_name_2": "Babylon Lounge",
        "old_postcode_2": "BN3 4FA",
        "last_run": "2015-10-28 05:31:59",
        "company_name": "Ullu Bata Inc.",
        "white_label_profile_id": "7819",
        "notify": "0",
        "email_addresses": "[\"example@brightlocal.com\"]",
        "active_only": "",
        "is_public": "Yes",
        "public_key": "<REPLACED>",
        "created": "2015-10-28 05:00:34",
        "status": "complete",
        "urls": {
            "interactive_url": "https:\/\/tools.brightlocal.com\/seo-tools\/admin\/ct\/reports\/view\/255565",
            "pdf_url": "https:\/\/tools.brightlocal.com\/seo-tools\/admin\/ct\/reports\/pdf\/255565",
            "csv_url": "https:\/\/tools.brightlocal.com\/seo-tools\/admin\/ct\/reports\/csv\/255565",
            "public_interactive_url": "<REPLACED>",
            "public_pdf_url": "<REPLACED>",
            "public_csv_url": "<REPLACED>"
            }
    }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/ct/get

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required

Run Report

Account Method

Run Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/ct/run', [
    'report-id' => 682
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=682' \ 
 https://tools.brightlocal.com/seo-tools/api/v2/ct/run
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
        parameters.Add("report-id", "682");

var success = request.put("/v2/ct/run", parameters);

Success (200 OK)

{
    "response":  {
        "status": "running"
    }
}

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/ct/run

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required

Delete Report

Account Method

Delete Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/ct/delete', [
    'report-id' => 682
]);
if($success) {
    echo 'Successfully deleted report.' . PHP_EOL;
}
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=682' \ 
 https://tools.brightlocal.com/seo-tools/api/v2/ct/delete
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-id", "682");

var success = request.Post("/v2/ct/delete", parameters);

Success (200 OK)

{
    "response":  {
        "status": "deleted"
    }
}

Warning: This action cannot be undone.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/ct/delete

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required

Get All Reports

Account Method

Get All Reports

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/ct/get-all');
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \ 
  https://tools.brightlocal.com/seo-tools/api/v2/ct/get-all
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();

var results = request.Get("/v2/ct/get-all", parameters);

Success (200 OK)

{
    "response":  {
        "results":  [
            {
                "report_id": "278",
                "customer_id": "35",
                "location_id": "5",
                "report_run_id": "2457",
                "report_name": "Test 1",
                "website_address": "http://www.test1.com",
                "business_name": "Test 1",
                "business_location": "Test location",
                "postcode": "TEST TEST",
                "country": "GBR",
                "state_code": null,
                "cancel_run": "0",
                "address1": "",
                "address2": "",
                "telephone": "0123456789",
                "business_type": "Pub",
                "primary_location": "Fulham",
                "old_business_name_1": "",
                "old_postcode_1": "",
                "old_business_name_2": "",
                "old_postcode_2": "",
                "currently_running": "No",
                "generation_error": "No",
                "terminal_fail": "No",
                "last_run": "2012-09-07 11:45:56",
                "report_status": null,
                "your_ct_count": "197",
                "your_ct_count_up": "0",
                "your_ct_count_down": "0",
                "total_ct_sources": "230",
                "total_ct_sources_up": "0",
                "competitor_ct_count": "76",
                "competitor_ct_count_diff": null,
                "old_ct_count": "0",
                "company_name": null,
                "branding_profile_id": null,
                "notify": "0",
                "email_addresses": "['test@test1.com']",
                "your_ct_count_diff": 0,
                "competitor_ct_count_up": 0,
                "competitor_ct_count_down": 0,
                "total_ct_sources_diff": 0,
                "successful_runs": "1"
            },
            {
                "report_id": "660",
                "customer_id": "35",
                "location_id": "0",
                "report_run_id": "2756",
                "report_name": "Test 2",
                "website_address": "",
                "business_name": "Test 2",
                "postcode": "chicago",
                "country": "USA",
                "state_code": "IL",
                "cancel_run": "0",
                "address1": "",
                "address2": "",
                "telephone": "0123456789",
                "business_type": "car hire",
                "primary_location": "chicago",
                "old_business_name_1": "",
                "old_postcode_1": "",
                "old_business_name_2": "",
                "old_postcode_2": "",
                "currently_running": "No",
                "generation_error": "No",
                "terminal_fail": "No",
                "last_run": "2013-05-21 11:18:31",
                "report_status": null,
                "your_ct_count": "633",
                "your_ct_count_up": "129",
                "your_ct_count_down": "0",
                "total_ct_sources": "356",
                "total_ct_sources_up": "100",
                "competitor_ct_count": "90",
                "competitor_ct_count_diff": "10",
                "old_ct_count": "0",
                "company_name": null,
                "branding_profile_id": null,
                "notify": "0",
                "email_addresses": "['test@test2.com']",
                "your_ct_count_diff": 0,
                "competitor_ct_count_up": 0,
                "competitor_ct_count_down": 0,
                "total_ct_sources_diff": 0,
                "successful_runs": "2"
            }
        ]
    }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/ct/get-all

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id

Get Report Results

Account Method

Get Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/ct/get-results', [
    'report-id' => 2457
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=2457' \
 https://tools.brightlocal.com/seo-tools/api/v2/ct/get-results
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-id", "2457");

var results = request.Get("/v2/ct/get-results", parameters);

Success (200 OK)

{
    "response":  {
        "results":  {
            "active":  [
                {
                    "id": "",
                    "citation_id": 182555,
                    "customer_id": "35",
                    "report_id": "2457",
                    "citation-status": "active",
                    "source": "carricktoday.co.uk",
                    "url": "http://www.carricktoday.co.uk/findit?action=showMap&placeid=68739",
                    "citation-notes": null,
                    "status": "Got it",
                    "date-identified-sorting": "2012-09-07T00:00:00+00:00",
                    "date-identified": "07 Sep 12",
                    "domain-authority": "38.75",
                    "citation-value": "Unknown",
                    "moz-rank": "Unknown",
                    "site-type": "Local Directory",
                    "listing-type": "Free Listing",
                    "seomoz-lookup-complete": "Yes",
                    "business-name": null,
                    "postcode": null
                }
            ],
            "pending":  [

            ],
            "possible": [

            ],
            "activeDomains":  {
                "facebook.com": true,
                "twitter.com": true,
                "yelp.com": true,
                "yell.com": true,
                "thomsonlocal.com": true,
                "beerintheevening.com": true,
                "hotfrog.co.uk": true,
                "cylex-uk.co.uk": true
            },
            "pendingDomains": {

            },
            "possibleDomains": {

            },
            "topDirectories":  [
                {
                    "citation_id": 182555,
                    "customer_id": "35",
                    "report_id": "2457",
                    "citation-status": "active",
                    "source": "carricktoday.co.uk",
                    "url": "http://www.carricktoday.co.uk/findit?action=showMap&placeid=68739",
                    "citation-notes": null,
                    "status": "Got it",
                    "date-identified-sorting": "2012-09-07T00:00:00+00:00",
                    "date-identified": "07 Sep 12",
                    "domain-authority": "38.75",
                    "citation-value": "Unknown",
                    "moz-rank": "Unknown",
                    "site-type": "Local Directory",
                    "listing-type": "Free Listing",
                    "seomoz-lookup-complete": "Yes",
                    "business-name": "John's business",
                    "address": "Lungomare Zara, 1234 Giulianova",
                    "postcode": "1234",
                    "website-url": "http://www.johns-s-business.co.uk/",
                    "telephone": "03 12345678"
                }
            ],
            "flags": {
                "customer":  {
                    "new":  [],
                    "disappeared":  []
                },
                "competitor":  {
                    "new":  [],
                    "disappeared":  []
                }
            },
            "competitors": {

            }
        }
    }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/ct/get-results

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required

Citation Burst

Create Campaign

Account Method

Create Campaign

<?php
use BrightLocal\Api;

$briefDescription = 'Born in Paris in 1972 by sibling duo Maguy and Gilbert Le Coze, Le Bernardin only served fish: Fresh, simple and prepared with respect. After receiving its first Michelin star in 1976, and two more in 1980, the Le Coze’s set to open Le Bernardin in New York in 1986.';
$fullDescription = 'The restaurant has held three stars from the Michelin Guide since its 2005 New York launch and currently ranks 24 on the World’s 50 Best Restaurants list. The New York Zagat Guide has recognized Le Bernardin as top rated in the category of “Best Food” for the last nine consecutive years, and in 2015 was rated by the guide as New York City’s top restaurant for food and service.  Le Bernardin has earned seven James Beard Awards since 1998 including “Outstanding Restaurant of the Year,” “Top Chef in New York City,” “Outstanding Service,” “Outstanding Chef in the United States,” “Outstanding Pastry Chef,” “Outstanding Wine Service,” and “Best Restaurant Design” in 2012. 
Most recently, the Foundation named Maguy Le Coze as Outstanding.';

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/cb/create', [
    'campaign_name'              => 'Le Bernardin CItation Burst',
    'business_name'              => 'Le Bernardin',
    'website_address'            => 'le-bernardin.com',
    'campaign_country'           => 'USA',
    'campaign_city'              => 'NY',
    'business_category_id'       => 605,
    'business_categories'        => '["restaurant", "cafe"]',
    'address1'                   => '155 West 51st Street',
    'address2'                   => '',
    'city'                       => 'New York',
    'region'                     => 'New York, USA',
    'postcode'                   => '10019',
    'contact_name'               => 'Bloggs',
    'contact_firstname'          => 'Joe',
    'contact_telephone'          => '+1 212-554-1515',
    'contact_email'              => 'joe.bloggs@test.com',
    'brief_description'          => $briefDescription,
    'full_description'           => $fullDescription,
    'employees_number'           => 35,
    'start_year'                 => 1976,
    'working_hours_apply_to_all' => 1,
    'working_hours_mon_start'    => 0800,
    'working_hours_mon_end'      => 2200,  
]);
print_r($success);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

string brief_description = "Born in Paris in 1972 by sibling duo Maguy and Gilbert Le Coze, Le Bernardin only served fish: Fresh, simple and prepared with respect. After receiving its first Michelin star in 1976, and two more in 1980, the Le Coze’s set to open Le Bernardin in New York in 1986.";
string full_description = "The restaurant has held three stars from the Michelin Guide since its 2005 New York launch and currently ranks 24 on the World’s 50 Best Restaurants list. The New York Zagat Guide has recognized Le Bernardin as top rated in the category of “Best Food” for the last nine consecutive years, and in 2015 was rated by the guide as New York City’s top restaurant for food and service.  Le Bernardin has earned seven James Beard Awards since 1998 including “Outstanding Restaurant of the Year,” “Top Chef in New York City,” “Outstanding Service,” “Outstanding Chef in the United States,” “Outstanding Pastry Chef,” “Outstanding Wine Service,” and “Best Restaurant Design” in 2012. 
Most recently, the Foundation named Maguy Le Coze as Outstanding.";

var parameters = new api.Parameters();
parameters.Add("campaign_name", "Sample Citation Burst Campaign");
parameters.Add("business_name", "Le Bernardin");
parameters.Add("website_address", "le-bernardin.com");
parameters.Add("campaign_country", "USA");
parameters.Add("campaign_city", "New York");
parameters.Add("campaign_state", "NY");
parameters.Add("business_category_id", 605);
parameters.Add("business_categories", "['restaurant', 'cafe']");
parameters.Add("address1", "155 West 51st Street");
parameters.Add("address2", "");
parameters.Add("city", "New York");
parameters.Add("region", "New York, USA");
parameters.Add("postcode", "10019");
parameters.Add("contact_name", "Bloggs");
parameters.Add("contact_firstname", "Joe");
parameters.Add("contact_telephone", "+1 212-554-1515";
parameters.Add("contact_email", "joe.bloggs@test.com");     
parameters.Add("brief_description", brief_description);
parameters.Add("full_description", full_description);
parameters.Add("employees_number", 35);
parameters.Add("start_year", 1976);            
parameters.Add("working_hours_apply_to_all", 0);
parameters.Add("working_hours_mon_start", 0800);
parameters.Add("working_hours_mon_end", 2200);
parameters.Add("working_hours_tue_start", 0800);
parameters.Add("working_hours_tue_end", 2200);
parameters.Add("working_hours_wed_start", 0800);
parameters.Add("working_hours_wed_end", 2200);
parameters.Add("working_hours_thu_start", 0800);
parameters.Add("working_hours_thu_end", 2200);
parameters.Add("working_hours_fri_start", 0800);
parameters.Add("working_hours_fri_end", 2400);
parameters.Add("working_hours_sat_start", 1000);
parameters.Add("working_hours_sat_end", 2400);
parameters.Add("working_hours_sun_start", 1000);
parameters.Add("working_hours_sun_end", 2400);          

var success = request.Post("/v2/cb/create", parameters);

Validation Failure

{
  "error": true,
  "errors": {
    "business_name": "Please enter business name",
    "campaign_name": "Please enter campaign name",
    "contact_firstname": "Please enter contact first name",
    "contact_name": "Please enter contact last name",
    "business_category_id": "Please select business category",
    "business_categories": "Please enter at least one business category or tag",
    "campaign_country": "Please select country",
    "campaign_state": "Please select state",
    "campaign_city": "Please select location",
    "address1": "Please enter street address",
    "postcode": "Please enter zip / postal code",
    "website_address": "Please enter the website address for the business",
    "contact_email": "Please enter correct email address",
    "contact_telephone": "Please check your entered telephone number. Only digits 0-9 and ( ) - + characters can be entered.",
    "brief_description": "Please enter short description",
    "full_description": "Please enter full description",
    "employees_number": "Please enter number of employees",
    "start_year": "Please enter starting year",
    "working_hours": "Your must provide Working Hours for at least one day in the week",
    "campaign_status": "Invalid campaign status",
    "location_id": "Location with ID 0 not found or doesn't belong to this customer"
  }
}

Success (200 OK)

{
  "error": false,
  "campaign-id": 280
}

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/cb/create

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location_id
business_name Required
campaign_name Required
website_address Required
campaign_country Required
campaign_state Required
campaign_city Required
business_category_id Required
business_categories Required
address1 Required
address2
postcode Required
contact_name Required
contact_firstname Required
contact_telephone Required
mobile_number
fax_number
brief_description Required
full_description Required
employees_number Required
start_year Required
service_name_1
service_name_2
service_name_3
service_name_4
service_name_5
working_hours_apply_to_all Required If this field has a value of Y you only need to specify working hours for Monday and these values are then also used for the other days of the week.
working_hours_mon_24hrs Y or N. Defaults to N. This can be used in place of working_hours_mon_start and working_hours_mon_end.
working_hours_tue_24hrs Y or N. Defaults to N. This can be used in place of working_hours_tue_start and working_hours_tue_end.
working_hours_wed_24hrs Y or N. Defaults to N. This can be used in place of working_hours_wed_start and working_hours_wed_end.
working_hours_thu_24hrs Y or N. Defaults to N. This can be used in place of working_hours_thu_start and working_hours_thu_end.
working_hours_fri_24hrs Y or N. Defaults to N. This can be used in place of working_hours_fri_start and working_hours_fri_end.
working_hours_sat_24hrs Y or N. Defaults to N. This can be used in place of working_hours_sat_start and working_hours_sat_end.
working_hours_sun_24hrs Y or N. Defaults to N. This can be used in place of working_hours_sun_start and working_hours_sun_end.
working_hours_mon_start Required
working_hours_mon_end Required
working_hours_tue_start Required
working_hours_tue_end Required
working_hours_wed_start Required
working_hours_thu_end Required
working_hours_thu_start Required
working_hours_fri_end Required
working_hours_fri_start Required
working_hours_sat_end Required
working_hours_sat_start Required
working_hours_sun_end Required
working_hours_sun_start Required
special_offer
special_offer_description
special_offer_expiry_date
payment_methods

String with ’|’ delimiter. E.g. cash|visa|mastercard|amex|cheque|atm|discover. Possible values - cash|visa|mastercard|amex|cheque|invoice|insurance|atm|travellers|financing|paypal|discover

receive-email-alerts
alert-email-addresses
old_business_name
old_lookup_data For e.g, old postcode
is_public Publish reports on a white label URL. Y or N.
campaign_notes Notes for any issues & concerns which you want our submission team to be aware of when they submit to directories

Update Campaign

Account Method

<?php
use BrightLocal\Api;

$campaignId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->put('/v2/cb/' .$campaignId, [
    'campaign_name'              => 'Le Bernardin CItation Burst',
    'business_name'              => 'Le Bernardin',
    'website_address'            => 'le-bernardin.com',
    'campaign_country'           => 'USA',
    'campaign_city'              => 'NY',
    'business_category_id'       => 605,
    'business_categories'        => '["restaurant", "cafe"]',
    'address1'                   => '155 West 51st Street',
    'address2'                   => '',
    'city'                       => 'New York',
    'region'                     => 'New York, USA',
    'postcode'                   => '10019',
    'contact_name'               => 'Bloggs',
    'contact_firstname'          => 'Joe',
    'contact_telephone'          => '+1 212-554-1515',
    'contact_email'              => 'joe.bloggs@test.com'   
]);
print_r($success);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var campaignId = 1;

var parameters = new api.Parameters();
parameters.Add("campaign_name", "Sample Citation Burst Campaign");
parameters.Add("business_name", "Le Bernardin");
parameters.Add("website_address", "le-bernardin.com");
parameters.Add("campaign_country", "USA");
parameters.Add("campaign_city", "New York");
parameters.Add("campaign_state", "NY");
parameters.Add("business_category_id", 605);
parameters.Add("business_categories", "['restaurant', 'cafe']");
parameters.Add("address1", "155 West 51st Street");
parameters.Add("address2", "");
parameters.Add("city", "New York");
parameters.Add("region", "New York, USA");
parameters.Add("postcode", "10019");
parameters.Add("contact_name", "Bloggs");
parameters.Add("contact_firstname", "Joe");
parameters.Add("contact_telephone", "+1 212-554-1515";
parameters.Add("contact_email", "joe.bloggs@test.com");     

var success = request.Put("/v2/cb/" + campaignId + "", parameters);

Validation Failure

{
  "success": false,
  "error": true,
  "errors": {
    "business_name": "Please enter business name",
    "campaign_name": "Please enter campaign name",
    "contact_firstname": "Please enter contact first name",
    "contact_name": "Please enter contact last name",
    "business_categories": "Please enter at least one business category or tag",
    "campaign_state": "Please select state",
    "campaign_city": "Please select location",
    "address1": "Please enter street address"  
  }
}

Success (200 OK)

{
  "error": false,
  "success": true,
  "result": "Campaign updated"
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v2/cb/<campaignId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
business_name
campaign_name
website_address
campaign_state
campaign_city
business_categories
address1
address2
postcode
contact_name
contact_firstname
contact_telephone
mobile_number
fax_number
brief_description
full_description
employees_number
start_year
service_name_1
service_name_2
service_name_3
service_name_4
service_name_5
working_hours_apply_to_all If this field has a value of Y you only need to specify working hours for Monday and these values are then also used for the other days of the week.
working_hours_mon_24hrs Y or N. Defaults to N. This can be used in place of working_hours_mon_start and working_hours_mon_end.
working_hours_tue_24hrs Y or N. Defaults to N. This can be used in place of working_hours_tue_start and working_hours_tue_end.
working_hours_wed_24hrs Y or N. Defaults to N. This can be used in place of working_hours_wed_start and working_hours_wed_end.
working_hours_thu_24hrs Y or N. Defaults to N. This can be used in place of working_hours_thu_start and working_hours_thu_end.
working_hours_fri_24hrs Y or N. Defaults to N. This can be used in place of working_hours_fri_start and working_hours_fri_end.
working_hours_sat_24hrs Y or N. Defaults to N. This can be used in place of working_hours_sat_start and working_hours_sat_end.
working_hours_sun_24hrs Y or N. Defaults to N. This can be used in place of working_hours_sun_start and working_hours_sun_end.
working_hours_mon_start
working_hours_mon_end
working_hours_tue_start
working_hours_tue_end
working_hours_wed_start
working_hours_thu_end
working_hours_thu_start
working_hours_fri_end
working_hours_fri_start
working_hours_sat_end
working_hours_sat_start
working_hours_sun_end
working_hours_sun_start
special_offer
special_offer_description
special_offer_expiry_date
payment_methods

String with ’|’ delimiter. E.g. cash|visa|mastercard|amex|cheque|atm|discover. Possible values - cash, visa, mastercard, amex, cheque, invoice, insurance, atm, travellers, financing, paypal, discover

receive-email-alerts
alert-email-addresses
old_business_name
old_lookup_data For e.g, old postcode
is_public Publish reports on a white label URL. Y or N.
campaign_notes Notes for any issues & concerns which you want our submission team to be aware of when they submit to directories

Upload Image

Account Method

Upload Image

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/cb/upload/<campaignId>/<imageType>', [
    'file' => fopen('/path/to/image.jpg', 'r')
]);
print_r($success);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var campaignId = 1;
var imageType = ".jpg";
var path = "/path/to/image.jpg";

var success = request.PostImage("/v2/cb/upload/" + campaignId + "/" + imageType "", path);

Success (200 OK)

{
  "success": true,
  "error":   false,
  "result":  "File companyLogo.jpg uploaded"
}

Upload an image to be used in CB campaign. is the id of existing campaign, is one of: logo, image1, image2, image3. Request must contain standard file upload. There should be exactly one file uploaded with size not exceeding 2 MB. Acceptable formats are: jpg, png.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/cb/upload/[campaignId]/[imageType]

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Example URL

http://tools.brightlocal.com/seo-tools/api/v2/cb/upload/5533/logo

Get Citations

Account Method

Get Citations

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/cb/citations', [
    'campaign_id' => 1 
]);
print_r($results);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var campaignId = 1;
var parameters = new api.Parameters();
parameters.Add("campaign-id", campaignId);

var citations = request.Get("/v2/cb/citations", parameters);

Success (200 OK)

{
    "error": false,
    "campaignId": 123,
    "citations": {
        "bing.com": {
            "citation_value": "Very High",
            "domain_authority": "99",
            "type": "General Directory",
            "phone_verification": "N",
            "client_verification": "Y",
            "notes": "Bingplaces will send you verification PIN at your registered postal address.",
            "no_update": "Y",
            "no_photos": "Y",
            "part_of_yext_network": "Y",
            "quick_listing": "N",
            "secondary_campaign_id": "b",
            "status": "To Do"
        }
    },
    "aggregators": [
        {
            "citation" : "factual",
            "domain_authority": "N/A",
            "type": "Aggregators",
            "phone_verification": "N/A",
            "client_verification": "N/A",
            "notes": "Factual will only contact the business if key data doesn’t align",
            "no_update": "N/A",
            "no_photos": "N/A",
            "part_of_yext_network": "N/A",
            "quick_listing": "N/A",
            "secondary_campaign_id": "b",
            "status": "To Do"
        }
    ]
}

Retrieve list of citations associated with campaign.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/cb/citations

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required

Confirm & Pay

Account Method

Confirm & Pay

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v2/cb/confirm-and-pay', [
    'campaign_id'       => 1,
    'package_id'        => 'cb15',
    'autoselect'        => 'N',
    'remove-duplicates' => 'Y',
    'aggregators'       => '["factual"]',
    'citations'         => '["brownbook.net", "bing.com", "manta.com", "yell.com", "accessplace.com", "bizfo.co.uk", "bizwiki.co.uk", "citylocal.co.uk", "cylex-uk.co.uk", "where2go.com", "yelp.co.uk", "scoot.co.uk", "restaurants.co.uk", "opendi.co.uk", "misterwhat.co.uk"]',
    'notes'             => 'Some very important notes'
]);
print_r($success);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var campaignId = 1;
var parameters = new api.Parameters();
parameters.Add("campaign_id", campaignId);
parameters.Add("package_id", "cb15");
parameters.Add("autoselect", "N");
parameters.Add("remove-duplicates", "Y");
parameters.Add("aggregators", "['factual']");
parameters.Add("citations", "['brownbook.net', 'bing.com', 'manta.com', 'yell.com', 'accessplace.com', 'bizfo.co.uk', 'bizwiki.co.uk', 'citylocal.co.uk', 'cylex-uk.co.uk', 'where2go.com', 'yelp.co.uk', 'scoot.co.uk', 'restaurants.co.uk', 'opendi.co.uk', 'misterwhat.co.uk']");
parameters.Add("notes", "Some very important notes");

var success = request.Post("/v2/cb/confirm-and-pay", parameters);

Validation Failure

{
  "error": true,
  "errors": {
    "citations": "No citations supplied",
    "package_id": "Invalid package id"
  }
}

Success (200 OK) json { "error": false }

Confirm and pay (using credits) for a CB campaign.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v2/cb/confirm-and-pay

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign_id Required
package_id Required CB package id corresponding to the number of ordered credits: ‘cb10’ for 10 citations, 'cb15’ for 15, then 25, 30, 50, 75, 100. To use only aggregators and ignore citations or package_id, please use 'cb0’ package only.
autoselect String. Possible values 'N’ or 'Y’. Default 'N’.
citations JSON Array. List of sites you require listings for. You can leave citations empty for auto selecting citations.
remove-duplicates String. Possible values 'N’ or 'Y’. Default 'N’. Find and Remove Duplicate Listings
aggregators JSON Array. List of aggregators you require listings for. Possible values are 'factual’, 'infogroup’, 'neustar’, 'acxiom’ for USA. The only possible value for all non USA countries is 'factual’.
notes Provide instructions to our submissions team with specifics about how you’d like your campaign handled.

Get Campaigns

Account Method

Get Campaigns

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->post('/v2/cb/get-all');
print_r($results);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();

var campaigns = request.Get("/v2/cb/get-all", parameters);

Success (200 OK)

{
    "response":  {
        "results":  [
            {
                "campaign_id": "4",
                "location_id": "7459",
                "campaign_name": "Test 1",
                "date_purchased": "2012-06-11 00:00:00",
                "date_completed": "2012-06-25 00:00:00",
                "email": "test@test1.com",
                "username": "",
                "password": "",
                "citations":  [
                    {
                        "name": "advertiserdirectory.co.uk",
                        "status": "Live",
                        "site_type": "Local Directory",
                        "citation_url": "advertiserdirectory.co.uk",
                        "domain_authority": "21/100",
                        "citation_value": "Low"
                    },
                    {
                        "name": "freeindex.co.uk",
                        "status": "Updated",
                        "site_type": "General Directory",
                        "citation_url": "freeindex.co.uk",
                        "domain_authority": "< 10/100",
                        "citation_value": "High"
                    }
                ],
                "aggregators":  [
                    {
                        "name": "infogroup",
                        "status": "Live",
                        "site_type": "Aggregator",
                        "citation_url": "infogroup.com",
                        "domain_authority": "NA",
                        "citation_value": "NA"
                    },
                    {
                        "name": "factual",
                        "status": "Updated",
                        "site_type": "Aggregator",
                        "citation_url": "factual.com",
                        "domain_authority": "NA",
                        "citation_value": "NA"
                    }
                ]                
            }
        ]
    }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/cb/get-all

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id

Get Campaign

Account Method

Get Campaign

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$campaign = $api->get('/v2/cb/get', [
    'campaign_id' => 1
]);
print_r($campaign);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var campaignId = 1;
var parameters = new api.Parameters();
parameters.Add("campaign-id", campaignId);

var campaign = request.Get("/v2/cb/get", parameters);

Success (200 OK)

{
    "response": {
        "results": {
            "campaign_id": "116225",
            "location_id": 522411,
            "campaign_name": "CUCINA urbana",
            "creation_date": "2017-01-11 14:56:56",
            "package_id": "1",
            "selection_type": "manual",
            "paid": "Yes",
            "status": "Complete",
            "submission_date": null,
            "purchase_date": "2017-01-11 15:06:18",
            "completion_date": "2017-01-25 00:00:00",
            "username": "",
            "email": "",
            "password": "",
            "campaign_note": "",
            "customer_note": "",
            "white_label_profile_id": "0",
            "num_citations": null,
            "package_price": "75",
            "website_address": "http:\/\/www.cucinaurbana.com\/",
            "campaign_country": "USA",
            "campaign_state": "CA",
            "campaign_city": "San Diego",
            "business_category_id": "2291",
            "business_category_name": "bar, liquor store, restaurant, food, store",
            "address": {
                "street_address_1": "505 Laurel Street",
                "street_address_2": null,
                "city": null,
                "region": null,
                "postcode": "92101"
            },
            "contact": {
                "last_name": "name",
                "first_name": "name",
                "email": "<hidden>",
                "telephone": "+1 619-239-2222"
            },
            "mobile_number": null,
            "fax_number": null,
            "descriptions": {
                "brief": "",
                "full": ""
            },
            "num_employees": "20",
            "start_year": "2000",
            "service_names": {
                "1": null,
                "2": null,
                "3": null,
                "4": null,
                "5": null
            },
            "working_hours": {
                "apply_to_all": "1",
                "days": {
                    "mon": {
                        "start": null,
                        "end": null,
                        "24_hours": "1"
                    },
                    "tue": {
                        "start": null,
                        "end": null,
                        "24_hours": "1"
                    },
                    "wed": {
                        "start": null,
                        "end": null,
                        "24_hours": "1"
                    },
                    "thu": {
                        "start": null,
                        "end": null,
                        "24_hours": "1"
                    },
                    "fri": {
                        "start": null,
                        "end": null,
                        "24_hours": "1"
                    },
                    "sat": {
                        "start": null,
                        "end": null,
                        "24_hours": "1"
                    },
                    "sun": {
                        "start": null,
                        "end": null,
                        "24_hours": "1"
                    }
                }
            },
            "payment_methods": {
                "cash": "on"
            },
            "company_logo": null,
            "photos": {
                "1": null,
                "2": null,
                "3": null
            },
            "email_alerts": {
                "enabled": "N",
                "addresses": [
                    "<hidden>",
                    "<hidden>",
                    "<hidden>",
                    "<hidden>",
                    "<hidden>"
                ]
            },
            "old_business_name": null,
            "specialist_info": [],
            "stats": [
                {
                    "start_date": "2017-01-11 15:06:18",
                    "citations_count": 25,
                    "scheduled": 0,
                    "submitted": 0,
                    "live": 25,
                    "updated": 0,
                    "replaced": 0
                }
            ],
            "citations": [
                {
                    "site": "google.com",
                    "type": "Local Directory",
                    "domain_authority": "100",
                    "status": "Live",
                    "link": "https:\/\/www.google.com\/search?q=CUCINA+urbana&npsic=0&gbv=2&gws_rd=cr&ludocid=1563397020059271303&hl=en&gl=us",
                    "notes": ""
                },
                {
                    "site": "mapsconnect.apple.com",
                    "type": "General Directory",
                    "domain_authority": "100",
                    "status": "Live",
                    "link": "mapsconnect.apple.com",
                    "notes": "We can't give you a link to your live listing in Apple Maps. You can find your listing by using the Apple Maps app of any iOS device."
                },
                {
                    "site": "bing.com",
                    "type": "General Directory",
                    "domain_authority": "99",
                    "status": "Live",
                    "link": "bing.com",
                    "notes": "Bingplaces will send you verification PIN at your registered postal address."
                },
                {
                    "site": "mapquest.com",
                    "type": "Local Map Site",
                    "domain_authority": "95",
                    "status": "Live",
                    "link": "https:\/\/www.mapquest.com\/us\/california\/italian-restaurants-san-diego\/cucina-urbana-265234833",
                    "notes": "This site does not allow images to be uploaded and displays limited information on company profile."
                },
                {
                    "site": "yellowpages.com",
                    "type": "General Directory",
                    "domain_authority": "92",
                    "status": "Live",
                    "link": "http:\/\/www.yellowpages.com\/san-diego-ca\/mip\/cucina-urbana-22866099",
                    "notes": ""
                },
                {
                    "site": "angieslist.com",
                    "type": "General Directory",
                    "domain_authority": "91",
                    "status": "Live",
                    "link": "angieslist.com",
                    "notes": "The site supports a limited number of cities in Canada only (no problem with US located businesses). Please don't be surprise if we end up replacing this site in your order; it means your city is not supported."
                },
                {
                    "site": "citysearch.com",
                    "type": "Local Directory",
                    "domain_authority": "90",
                    "status": "Live",
                    "link": "http:\/\/www.citysearch.com\/profile\/607571610\/san_diego_ca\/cucina_urbana.html",
                    "notes": "We list your business here via Expressupdate.com; site does not accept Toll Free phone. It takes 2-3 months before your listing goes live here."
                },
                {
                    "site": "superpages.com",
                    "type": "General Directory",
                    "domain_authority": "90",
                    "status": "Live",
                    "link": "http:\/\/www.superpages.com\/bp\/san-diego-ca\/cucina-urbana-L2129766314.htm",
                    "notes": "We submit your listing to this site via Dexmedia.com"
                },
                {
                    "site": "manta.com",
                    "type": "General Directory",
                    "domain_authority": "87",
                    "status": "Live",
                    "link": "http:\/\/www.manta.com\/c\/mtxfvs9\/cucina-urbana",
                    "notes": ""
                },
                {
                    "site": "switchboard.com",
                    "type": "Local Directory",
                    "domain_authority": "87",
                    "status": "Live",
                    "link": "switchboard.com",
                    "notes": "We list your business here via Expressupdate.com; site does not accept Toll Free phone. It takes 2-3 months before your listing goes live here."
                },
                {
                    "site": "tomtom.com",
                    "type": "GPS Data Provider",
                    "domain_authority": "85",
                    "status": "Live",
                    "link": "tomtom.com",
                    "notes": "We submit data to Tomtom once every quarter, so your data will be submitted the next round during the next round of submissions to Tomtom."
                },
                {
                    "site": "whowhere.com",
                    "type": "General Directory",
                    "domain_authority": "83",
                    "status": "Live",
                    "link": "whowhere.com",
                    "notes": "We submit your listing to this site via Dexmedia.com"
                },
                {
                    "site": "kudzu.com",
                    "type": "General Directory",
                    "domain_authority": "82",
                    "status": "Live",
                    "link": "http:\/\/www.kudzu.com\/m\/Cucina-Urbana-841435",
                    "notes": ""
                },
                {
                    "site": "local.com",
                    "type": "General Directory",
                    "domain_authority": "81",
                    "status": "Live",
                    "link": "local.com",
                    "notes": "We create basic listing on this site (no images) & create a new account. Client\/agency respond to email to put listing live. See campaign email inbox."
                },
                {
                    "site": "local.botw.org",
                    "type": "Local Directory",
                    "domain_authority": "80",
                    "status": "Live",
                    "link": "local.botw.org",
                    "notes": "This site does not display URL in live listing."
                },
                {
                    "site": "aboutus.com",
                    "type": "General Directory",
                    "domain_authority": "79",
                    "status": "Live",
                    "link": "aboutus.com",
                    "notes": ""
                },
                {
                    "site": "heraldtribune.com",
                    "type": "News \/ Content Site",
                    "domain_authority": "79",
                    "status": "Live",
                    "link": "heraldtribune.com",
                    "notes": ""
                },
                {
                    "site": "directory.wfaa.com",
                    "type": "Local Directory",
                    "domain_authority": "78",
                    "status": "Live",
                    "link": "directory.wfaa.com",
                    "notes": "This site does not allow images to be uploaded and displays limited information on company profile."
                },
                {
                    "site": "chamberofcommerce.com",
                    "type": "General Directory",
                    "domain_authority": "74",
                    "status": "Live",
                    "link": "https:\/\/chamberofcommerce.com\/san-diego-ca\/2736482-cucina-urbana",
                    "notes": "We can only list your business name, address, and phone number here. Please be guided before ordering a listing from this site."
                },
                {
                    "site": "hotfrog.com",
                    "type": "General Directory",
                    "domain_authority": "74",
                    "status": "Live",
                    "link": "hotfrog.com",
                    "notes": ""
                },
                {
                    "site": "411.com",
                    "type": "Local Directory",
                    "domain_authority": "72",
                    "status": "Live",
                    "link": "411.com",
                    "notes": "We list your business here via Expressupdate.com; site does not accept Toll Free phone. It takes 2-3 months before your listing goes live here."
                },
                {
                    "site": "tupalo.com",
                    "type": "General Directory",
                    "domain_authority": "70",
                    "status": "Live",
                    "link": "tupalo.com",
                    "notes": "Tupalo is notorious on auto updating address: for example, Suite to Ste, or North to just \"N\"."
                },
                {
                    "site": "brownbook.net",
                    "type": "General Directory",
                    "domain_authority": "64",
                    "status": "Live",
                    "link": "http:\/\/www.brownbook.net\/business\/11048772\/laurel-restaurant",
                    "notes": "We cannot update the business name in this site after submission. Ensure that you get the business name provided is correct from the very beginning."
                },
                {
                    "site": "citysquares.com",
                    "type": "General Directory",
                    "domain_authority": "57",
                    "status": "Live",
                    "link": "http:\/\/citysquares.com\/b\/cucina-urbana-19686169",
                    "notes": "This site does not display URL, description for free listing. They are reserved to paid listing only."
                },
                {
                    "site": "routeandgo.net",
                    "type": "General Directory",
                    "domain_authority": "22",
                    "status": "Live",
                    "link": "http:\/\/www.routeandgo.net\/place\/3118699\/united-states\/cucina-urbana",
                    "notes": ""
                }
            ],
            "aggregators": [],
            "urls": {
                "interactive_url": "<hidden>",
                "pdf_url": "<hidden>",
                "csv_url": "<hidden>"
            }
        }
    }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/cb/get

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
campaign-id Required

Get Credits Balance

Account Method

Get Credits

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v2/cb/credits');
print_r($results);
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var parameters = new api.Parameters();
var results = request.Get("/v2/cb/credits", parameters);

Success (200 OK)

{
    "success": true,
    "credits": 9000
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v2/cb/credits

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

ReviewFlow Reports

Add Report

Account Method

Add Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v4/rf/add', [
    'report-name'       => 'Le Bernardin', 
    'business-name'     => 'Le Bernardin',
    'contact-telephone' => '+1 212-554-1515',
    'address1'          => '155 West 51st Street',
    'address2'          => '',      
    'city'              => 'New York',
    'postcode'          => '10019',
    'country'           => 'USA' // USA only    
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \ 
 -d 'report-name=Le Bernardin' \
 -d 'business-name=Le Bernardin' \
 -d 'contact-telephone=+1 212-554-1515' \
 -d 'address1=155 West 51st Street' \ 
 -d 'address2=' \
 -d 'city=New York' \
 -d 'postcode=10019' \
 -d 'country=USA' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/add
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report-name", "Sample Citation Tracking Report");
parameters.Add("business-name", "Le Bernardin");            
parameters.Add("contact-telephone", "+1 212-554-1515");
parameters.Add("address1", "155 Weest 51st Street");
parameters.Add("address2", "");
parameters.Add("city", "New York");            
parameters.Add("postcode", "10019");
parameters.Add("country", "USA"); // USA only

var success = request.Post("/v4/rf/add", parameters);

Example of specifying directories

<?php
echo json_encode(array(
        'url'     => 'http://www.yellowbot.com/le-bernardin-new-york-ny.html',
        'include' => true
    ),
    'yellowpages' => array(
        'url'     => 'http://www.yellowpages.com/new-york-ny/mip/le-bernardin-9909153',
        'include' => true
    ),
    'yelp' => array(
        'url'     => 'http://www.yelp.com/biz/le-bernardin-new-york',
        'include' => true
    )
));
var directories = new List<dynamic>();
directories.Add(new
{
    yellowbot = new
    {
        url = "http://www.yellowbot.com/le-bernardin-new-york-ny.html",
        include = true
    },
    yellowpages = new
    {
        url = "http://www.yellowpages.com/new-york-ny/mip/le-bernardin-9909153",
        include = true
    },
    yelp = new
    {
        url = "",
        include = true
    }
});

Success (201 Created)

{
    "success": true,
    "report-id": "1"
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_NAME": "Please enter report name",
    "INVALID_BUSINESS_NAME": "Please enter business name",
    "INVALID_CONTACT_TELEPHONE": "Please enter phone number",
    "INVALID_ADDRESS1": "Please enter street address",
    "INVALID_CITY": "Please enter city",
    "INVALID_POSTCODE": "Please enter post code",
    "INVALID_COUNTRY": "Please select country"
  }
}

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/rf/add

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-name Required
location-id Associate this report with a location in your account. This ID needs to correspond to a valid location in your account.
white-label-profile-id Assign a white label profile to this report. The ID needs to correspond to a valid white label profile in your account.
business-name Required
contact-telephone Required
address1 Required
address2
city Required
postcode Required A valid postcode or ZIP.
country Required USA only.
schedule D (Daily), W (Weekly) or M (Monthly). You to purchase an add on before you can use daily reporting. Defaults to M (Monthly).
run-on Numeric day of week or day of month to run the report on (applicable to weekly and monthly schedules). Defaults to current day of month. If you create your report today it’ll be run on the 17th of each month unless you specify otherwise.
receive-email-alerts One of 1 or 0. If set to 1 we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Defaults to 0.
alert-email-addresses Supply a list of email addresses as a JSON string, e.g. [“user1@test.com”,“user2@test.com”,“user3@test.com”]
is-public Determines whether or not to make the report available on a public URL you can give to your customers. One of 1 or 0. Defaults to 0.
directories

By default we try and find profile URLs and reviews in all directories we support. If you’d like your report to contain only specific directories or already know the profile URLs for some directories you can supply them here. Please note that if you supply information for this parameter you need to give us all details of the directories you want included. If you have profile URLs for some but not others you can leave those URL fields empty and we’ll do our best to find them. Generally we recommend you run your report for the first time without this setting and then use our update method to add/change URLs or remove directories if needed.

The data for this parameter needs to be supplied as a JSON string. Local directory identifiers (the keys in the example below) are documented here. Here’s an example of how to generate suitable values in PHP:

Update Report

Account Method

Update Report

<?php
use BrightLocal\Api;
$reportId = 1;
$api = new Api(<INSERT_API_KEY>', '<INSERT_API_SECRET>);
$success = $api->put('/v4/rf/' .$reportId, [
     -d 'report-name=Le Bernardin' \
     -d 'business-name=Le Bernardin' \
     -d 'contact-telephone=+1 212-554-1515' \
]);
print_r($success);
curl -X PUT \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report_name=Le Bernardin' \
 -d 'business_names=Le Bernardin' \
 -d 'schedule=Adhoc' \
 -d 'day_of_month=2' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/1
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var reportId = 1;
var parameters = new api.Parameters();
parameters.Add("business-name", "Le Bernardin");
parameters.Add("contact-telephone", "+1 212-554-1515");

var success = request.Put("/v4/rf/" + reportId + "", parameters);

Example of modifying directories

<?php
echo json_encode(array(
        'url'     => 'http://www.yellowbot.com/le-bernardin-new-york-ny.html',
        'include' => true
    ),
    'yellowpages' => array(
        'url'     => 'http://www.yellowpages.com/new-york-ny/mip/le-bernardin-9909153',
        'include' => true
    ),
    'yelp' => array(
        'url'     => 'http://www.yelp.com/biz/le-bernardin-new-york',
        'include' => true
    )
));
var directories = new List<dynamic>();
directories.Add(new
{
    yellowbot = new
    {
        url = "http://www.yellowbot.com/le-bernardin-new-york-ny.html",
        include = true
    },
    yellowpages = new
    {
        url = "http://www.yellowpages.com/new-york-ny/mip/le-bernardin-9909153",
        include = true
    },
    yelp = new
    {
        url = "",
        include = true
    }
});


> Success (200 Created)

```json
{
    "success": true
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-name
white-label-profile-id Assign a white label profile to this report. The ID needs to correspond to a valid white label profile in your account.
schedule D (Daily), W (Weekly) or M (Monthly). You to purchase an add on before you can use daily reporting. Defaults to M (Monthly).
run-on Numeric day of week or day of month to run the report on (applicable to weekly and monthly schedules). Defaults to current day of month. If you create your report today it’ll be run on the 17th of each month unless you specify otherwise.
receive-email-alerts One of 1 or 0. If set to 1 we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Defaults to 0.
alert-email-addresses Supply a list of email addresses as a JSON string, e.g. [“user1@test.com”,“user2@test.com”,“user3@test.com”]
is-public Determines whether or not to make the report available on a public URL you can give to your customers. One of 1 or 0. Defaults to 0.
directories

If you need to add or change a profile URL you can do so here.

The data for this parameter needs to be supplied as a JSON string. Local directory identifiers (the keys in the example below) are documented here. Here’s an example of how to generate suitable values in PHP:

Get Report

Account Method

Get Report

<?php
use BrightLocal\Api;

$reportId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/rf/' .$reportId);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/1
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 1;
var parameters = new api.Parameters();
var results = request.Get("v4/rf/" + reportId + "", parameters);

Success (200 OK)

{
    "success": true,
    "report": {
        "report_id": "270",
        "report_name": "Le Bernardin",
        "location_id": "0",
        "customer_id": "35",
        "business_name": "Le Bernardin",
        "contact_telephone": "+1 212-554-1515",
        "address1": "155 West 51st Street",
        "address2": "",
        "city": "New York",
        "postcode": "10019",
        "country": "USA",
        "receive_email_alerts": false,
        "alert_email_addresses": [
            "<hidden>",
            "<hidden>",
            "<hidden>"
        ],
        "last_update": "2015-01-06 11:51:35",
        "created_at": "2015-01-06 11:43:57",
        "schedule": "M",
        "run_on": "1",
        "reviews_count": "2772",
        "rating": "4.49",
        "is_running": false,
        "white_label_profile_id": null,
        "is_public": true,
        "public_key": "<hidden>",
        "directories": {
            "botw": {
                "url": "http://local.botw.org/New_York/New_York/Ayza/1000053931.html",
                "searched": true,
                "include": true
            },
            "citysearch": {
                "url": "http://www.citysearch.com/profile/7143737/new_york_ny/le_bernardin.html",
                "searched": true,
                "include": true
            },
            "dexknows": {
                "url": "",
                "searched": true,
                "include": true
            },
            "foursquare": {
                "url": "https://foursquare.com/v/le-bernardin-new-york-ny/3fd66200f964a52066e31ee3",
                "searched": true,
                "include": true
            },
            "google": {
                "url": "https://plus.google.com/106100547192468577963/about?hl=en&rfmt=s",
                "searched": true,
                "include": true
            },
            "insiderpages": {
                "url": "http://www.insiderpages.com/b/15241026606/le-bernardin-new-york-1",
                "searched": true,
                "include": true
            },
            "judysbook": {
                "url": "http://www.judysbook.com/Le-Bernardin-Restaurant-Home-and-Garden-newyork-r29294246.htm",
                "searched": true,
                "include": true
            },
            "kudzu": {
                "url": "http://www.kudzu.com/m/Le-Bernardin-20063962",
                "searched": true,
                "include": true
            },
            "localcom": {
                "url": "http://www.local.com/business/details/new-york-ny/le-bernardin-117822808/",
                "searched": true,
                "include": true
            },
            "manta": {
                "url": "http://www.manta.com/c/mmgg127/le-bernardin-restaurant",
                "searched": true,
                "include": true
            },
            "merchantcircle": {
                "url": "http://www.merchantcircle.com/business/le.Bernardin.212-554-1515",
                "searched": true,
                "include": true
            },
            "superpages": {
                "url": "http://www.superpages.com/bp/New-York-NY/Le-Bernardin-L0500767889.htm",
                "searched": true,
                "include": true
            },
            "yahoo": {
                "url": "https://local.yahoo.com/info-27778787-le-bernardin-new-york",
                "searched": true,
                "include": true
            },
            "yellowbot": {
                "url": "http://www.yellowbot.com/le-bernardin-new-york-ny.html",
                "searched": true,
                "include": true
            },
            "yellowpages": {
                "url": "http://www.yellowpages.com/new-york-ny/mip/le-bernardin-9909153",
                "searched": true,
                "include": true
            },
            "yelp": {
                "url": "http://www.yelp.com/biz/le-bernardin-new-york",
                "searched": true,
                "include": true
            }
        },
        "urls": {
            "interactive_url": "https://tools.brightlocal.com/seo-tools/admin/rf/tracker/276",
            "pdf_url": "https://tools.brightlocal.com/seo-tools/admin/rf/pdf-report/276",
            "public_interactive_url": "http://www.local-marketing-reports.com/review-reports/<hidden>/tracker/276",
            "public_pdf_url": "http://www.local-marketing-reports.com/review-reports/<hidden>/276.pdf"
        }
    }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Delete Report

Account Method

Delete Report

<?php
use BrightLocal\Api;

$reportId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->delete('/v4/rf/' .$reportId);
if($success) {
    echo 'Successfully deleted report.' . PHP_EOL;
}
print_r($success);
curl -X DELETE \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/1
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 1;
var parameters = new api.Parameters();
var success = request.Delete("/v4/rf/" + reportId + "", parameters);

Success (200 OK)

{
    "success": true
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID": "Report ID missing"
  }
}

Failure when report running (400 Bad Request)

{
    "success": false,
    "errors":  {
      "REPORT_RUNNING": "Report is running"
    }
}

HTTP Request

DELETE https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Get Reports

Account Method

Get Reports

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/rf/');
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var parameters = new api.Parameters();
var results = request.Get("/v4/rf", parameters);

Success (200 OK)

{
    "success": true,
    "reports": [
        {
            "report_id": "270",
            "report_name": "Le Bernardin",
            "location_id": "0",
            "created_at": "2015-01-06 11:43:57",
            "last_update": "2015-01-06 11:51:35",
            "is_running": false,
            "running_message": "",
            "fetching": false,
            "complete": true
        },
        {
            "report_id": "141",
            "report_name": "Zuni cafe #2",
            "location_id": "0",
            "created_at": "2013-12-10 15:24:53",
            "last_update": "2014-12-15 02:07:38",
            "is_running": false,
            "running_message": "",
            "fetching": false,
            "complete": true
        },
        {
            "report_id": "119",
            "report_name": "Zuni Cafe",
            "location_id": "0",
            "created_at": "2013-10-21 10:23:00",
            "last_update": "2014-12-15 02:06:54",
            "is_running": false,
            "running_message": "",
            "fetching": false,
            "complete": true
        },
        {
            "report_id": "144",
            "report_name": "Slade & Baker Vision Center",
            "location_id": "0",
            "created_at": "2013-12-16 15:17:10",
            "last_update": "2014-12-15 02:05:48",
            "is_running": false,
            "running_message": "",
            "fetching": false,
            "complete": true
        }
    ]
}

Validation Failure (400 Bad Request)

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id Filter the list of reports returned by location ID. This ID must correspond to a valid location in your account.

Account Method

Search for a ReviewFlow Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/rf/search', [
    'q' => 'Le Bernardin'    
]);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'q=My+Sample+Query' \   
  https://tools.brightlocal.com/seo-tools/api/v4/rf/search
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 1;
var parameters = new api.Parameters();
parameters.Add("q", "Le Bernardin");            
var results = request.Get("/v4/rf/search", parameters);

Success (200 OK)

{
    "success": true,
    "reports": [
        {
            "report_id": "270",
            "report_name": "Le Bernardin",
            "location_id": "0",
            "created_at": "2015-01-06 11:43:57",
            "last_update": "2015-01-06 11:51:35",
            "is_running": false,
            "running_message": "",
            "fetching": false,
            "complete": true
        }
    ]
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_SEARCH": "Search string missing"
  }
}

Search for reports in your account.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/search

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
q Required Supply an arbitrary search string.

Get Reviews

Account Method

Get Reviews

<?php
use BrightLocal\Api;

$reportId = 141;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$reviews = $api->get('/v4/rf/' .$reportId. '/reviews');
print_r($reviews);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/141/reviews
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 141;
var parameters = new api.Parameters();
var results = request.Get(/"v4/rf/" + reportId + "/reviews", parameters);

Success (200 OK)

{
    "success": true,
    "reviews": [
        {
            "dt": "2014-12-15 02:04:16",
            "report_id": "141",
            "directory": "yelp",
            "timestamp": "2014-12-14 02:04:43",
            "rating": "1",
            "title": "",
            "author": "Stephen Z.",
            "text": "I have not been in a number of years. Went there this past Friday night and was beyond disappointed. Service was not great at the bar or during dinner. The squash appetizer was completely overwhelmed by a very strong garlic component. The size of the main courses were about the size of the appetizers. I had the pork which looked like dog food with a side of beans. The meat was over cooked and was over powered by one spice. The fish was the same and the pasta dish looked like it had four or five pieces. The desserts were not much better. It was a very sad, disappointing experience. Will not be back.",
            "link": "http://www.yelp.com/biz/zuni-cafe-san-francisco?hrid=O-VJJEgwqsi02q4YnOJ8Qw",
            "url": "http://www.yelp.com/biz/zuni-cafe-san-francisco",
            "source": "",
            "name": "Yelp",
            "report_run_id": "15608"
        },
        {
            "dt": "2014-12-15 02:04:16",
            "report_id": "141",
            "directory": "yelp",
            "timestamp": "2014-12-11 02:04:43",
            "rating": "4",
            "title": "",
            "author": "Carl A.",
            "text": "After years of 5 stars from me, we had our first so-so experience at Zuni. Is it slipping now?  I hope not. But the buzz was gone. The service was halting and off. Let's hope that it was just an off-night, but maybe the time has come to move on??",
            "link": "http://www.yelp.com/biz/zuni-cafe-san-francisco?hrid=0xdzL2swNvC6cQ8yUDL4XQ",
            "url": "http://www.yelp.com/biz/zuni-cafe-san-francisco",
            "source": "",
            "name": "Yelp",
            "report_run_id": "15608"
        },
        {
            "dt": "2014-12-15 02:04:16",
            "report_id": "141",
            "directory": "yelp",
            "timestamp": "2014-12-10 02:04:43",
            "rating": "3",
            "title": "",
            "author": "Mary B.",
            "text": "Very expensive over rated restaurant. I feel the city has lost its zest for good food and overcharges for the mediocre.  Maybe we all should start eating at the food trucks where people cook their hearts out and keep the prices affordable.  Pork chop (from Llano Secco) delicious. Nettles?  Isn't spinach just as good. My husband thought the Ceasar salad was one of the best he's ever had, but the spaghetti was inedible. Thought he should have stopped at the Caesar's.  I'm not going back. I can find better food at better prices in this city.",
            "link": "http://www.yelp.com/biz/zuni-cafe-san-francisco?hrid=SEB7nqhlzF8pg2PALEvI7Q",
            "url": "http://www.yelp.com/biz/zuni-cafe-san-francisco",
            "source": "",
            "name": "Yelp",
            "report_run_id": "15608"
        }
    ]
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

Fetch all reviews associated with a report.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>/reviews

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
directory Fetch reviews for a specific directory. See directory identifiers in appendix below.
stars Fetch reviews for a specific star rating (0-5).
sort By date “asc” or “desc”. Default is “asc”
from Fetch reviews from specified date. Format yyyy-mm-dd.
to Fetch reviews up until specified date. Format yyyy-mm-dd.
offset By default 20 reviews are returned at once. Use in combination with limit to page results. Defaults to 0.
limit Defaults to 20.

Response Fields Explained

A few of the fields are explained below:

Field Explanation
source Determines where a review came from. Yahoo!, for example, can contain reviews that were posted directly on Yahoo! and reviews that have been sourced from Yelp.
source_link Link to the site where the review was originally written.
hash Unique identifier based on directory, author and review text. This can be used when storing reviews locally to prevent duplicates.

Get Reviews Count

Account Method

Get Reviews Count

<?php
use BrightLocal\Api;

$reportId = 141;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$count = $api->get('/v4/rf/' .$reportId. '/reviews/count');
print_r($count);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/141/reviews/count
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 141;
var parameters = new api.Parameters();
var results = request.Get("/v4/rf/" + reportId + "/reviews/count", parameters);

Success (200 OK)

{
    "success": true,
    "count": "2770"
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>/reviews/count

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Get Growth

Account Method

Get Growth

<?php
use BrightLocal\Api;

$reportId = 141;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$growth = $api->get('/v4/rf/' .$reportId. '/reviews/growth');
print_r($growth);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/141/reviews/growth
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 141;
var parameters = new api.Parameters();
var growth = request.Get("v4/rf/" + reportId + "/reviews/growth", parameters);

Get count and percentage of new reviews since last report run.

Success (200 OK)

{
    "success": true,
    "growth": {
        "number": "1",
        "percent": "0.03"
    }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>/reviews/growth

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Get Directories

Account Method

Get Directories

<?php
use BrightLocal\Api;

$reportId = 141;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$directories = $api->get('/v4/rf/' .$reportId. '/directories');
print_r($directories);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/141/directories
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 141;
var parameters = new api.Parameters();
var directories = request.Get("/v4/rf/" + reportId + "/directories", parameters);

Success (200 OK)

{
    "success": true,
    "directories": {
        "citysearch": {
            "directory": "citysearch",
            "name": "Citysearch",
            "use": true,
            "url": "http://www.citysearch.com/profile/612944020/los_angeles_ca/pizzeria_mozza.html",
            "searched": true,
            "reviews": 117
        },
        "dexknows": {
            "directory": "dexknows",
            "name": "DexKnows",
            "use": true,
            "url": "http://www.dexknows.com/business_profiles/pizzeria_mozza_los_angeles-l900211841",
            "searched": true,
            "reviews": 0
        },
        "google": {
            "directory": "google",
            "name": "Google+ Local",
            "use": true,
            "url": "https://plus.google.com/116883746235536288122/about?hl=en&rfmt=s",
            "searched": true,
            "reviews": 145
        },
        "insiderpages": {
            "directory": "insiderpages",
            "name": "Insider Pages",
            "use": true,
            "url": "http://www.insiderpages.com/b/15240159890/pizzeria-mozza-los-angeles",
            "searched": true,
            "reviews": 5
        },
        "judysbook": {
            "directory": "judysbook",
            "name": "Judy's Book",
            "use": true,
            "url": "http://www.judysbook.com/Pizzeria-Mozza-Restaurants-losangeles-r26871385.htm",
            "searched": true,
            "reviews": 127
        },
        "kudzu": {
            "directory": "kudzu",
            "name": "Kudzu",
            "use": true,
            "url": "http://www.kudzu.com/m/Pizzeria-Mozza-20924094",
            "searched": true,
            "reviews": 117
        },
        "localcom": {
            "directory": "localcom",
            "name": "Local.com",
            "use": true,
            "url": "http://www.local.com/business/details/los-angeles-ca/mozza-cafe-105106399/",
            "searched": true,
            "reviews": 1
        },
        "manta": {
            "directory": "manta",
            "name": "Manta",
            "use": true,
            "url": "http://www.manta.com/c/mrsy0q6/falbo-bros-pizzeria",
            "searched": true,
            "reviews": 0
        },
        "merchantcircle": {
            "directory": "merchantcircle",
            "name": "Merchant Circle",
            "use": true,
            "url": "http://www.merchantcircle.com/business/Pizzeria.Mozza.323-297-0101",
            "searched": true,
            "reviews": 42
        },
        "superpages": {
            "directory": "superpages",
            "name": "Super Pages",
            "use": true,
            "url": "http://www.superpages.com/bp/Los-Angeles-CA/Pizzeria-Mozza-L0136883359.htm",
            "searched": true,
            "reviews": 3
        },
        "yahoo": {
            "directory": "yahoo",
            "name": "Yahoo! Local",
            "use": true,
            "url": "http://local.yahoo.com/info-36089572-pizzeria-mozza-los-angeles;_ylt=A0oG7hXne95SMD4AyqhXNyoA;_ylu=X3oDMTBybnZlZnRlBHNlYwNzcgRwb3MDMQRjb2xvA2FjMgR2dGlkAw--",
            "searched": true,
            "reviews": 2
        },
        "yellowbot": {
            "directory": "yellowbot",
            "name": "Yellow Bot",
            "use": true,
            "url": "http://www.yellowbot.com/pizzeria-mozza-los-angeles-ca.html",
            "searched": true,
            "reviews": 324
        },
        "yellowpages": {
            "directory": "yellowpages",
            "name": "Yellow Pages",
            "use": true,
            "url": "http://www.yellowpages.com/los-angeles-ca/mip/pizzeria-mozza-18463301",
            "searched": true,
            "reviews": 108
        },
        "yelp": {
            "directory": "yelp",
            "name": "Yelp",
            "use": true,
            "url": "http://www.yelp.com/biz/pizzeria-mozza-los-angeles",
            "searched": true,
            "reviews": 2966
        }
    }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

Get a list of directories associated with a report. Results contain directory details, profile URLs and review counts.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>/directories

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Get Directory Stats

Account Method

Fetch stats showing average rating and review count for every directory in a given report.

Get Directory Stats

<?php
use BrightLocal\Api;

$reportId = 141;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$stats = $api->get('/v4/rf/' .$reportId. '/directories/stats');
print_r($stats);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/141//directories/stats
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 141;
var parameters = new api.Parameters();
var stats = request.Get("/v4/rf/" + reportId + "/directories/stats", parameters);

Success (200 OK)

{
  "success": true,
  "stats":  {
    "botw":  {
      "directory": "botw",
      "name": "Best of the Web",
      "use": true,
      "url": "http://local.botw.org/New_York/New_York/Ayza/1000053931.html",
      "searched": true,
      "rating": 0,
      "reviews": 0
    },
    "citysearch":  {
      "directory": "citysearch",
      "name": "Citysearch",
      "use": true,
      "url": "http://www.citysearch.com/profile/7143737/new_york_ny/le_bernardin.html",
      "searched": true,
      "rating": "4.00",
      "reviews": 91
    },
    "foursquare":  {
      "directory": "foursquare",
      "name": "FourSquare",
      "use": true,
      "url": "https://foursquare.com/v/le-bernardin-new-york-ny/3fd66200f964a52066e31ee3",
      "searched": true,
      "rating": "0.00",
      "reviews": 190
    }
  }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>/directories/stats

Fetch stats showing average rating and review count for every directory in a given report.

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Get Star Counts

Account Method

Get Start Counts

<?php
use BrightLocal\Api;

$reportId = 141;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$stars = $api->get('/v4/rf/' .$reportId. '/stars/count');
print_r($stars);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/rf/141//stars/count
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");
var reportId = 141;
var parameters = new api.Parameters();
var stars = request.Get("/v4/rf/" + reportId + "/stars/count", parameters);

Success (200 OK)

{
    "success": true,
    "counts": {
        "0star": "91",
        "1star": "223",
        "2star": "180",
        "3star": "394",
        "4star": "704",
        "5star": "1178"
    }
}

Validation Failure 400 Bad Request

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing"
  }
}

Get count of reviews for each star rating for a given report.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/rf/<reportId>/stars/count

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Google+ Local Wizard Reports

Add Report

Account Method

Add Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->post('/v4/gpw/add', [
    'report_name'    => 'Le Bernardin', 
    'business_names' => 'Le Bernardin',
    'schedule'       => 'Adhoc',
    'day_of_month'   => '2',
    'report_type'    => 'with',
    'address1'       => '155 West 51st Street',
    'address2'       => '',
    'city'           => 'New York',
    'state_code'     => 'NY',
    'postcode'       => '10019',
    'phone_number'   => '+1 212-554-1515',
    'country'        => 'USA',
    'search_terms'   => '["restaurant manhattan","cafe new york"]'
]);
print_r($success);
curl -X POST \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \ 
 -d 'report_name=Le Bernardin' \
 -d 'business_names=Le Bernardin' \
 -d 'schedule=Adhoc' \
 -d 'day_of_month=2' \
 -d 'report_type=with' \ 
 -d 'address1=155 West 51st Street' \ 
 -d 'address2=' \
 -d 'city=New York' \
 -d 'state_code=NY' \
 -d 'postcode=10019' \
 -d 'phone_number=+1 212-554-151' \
 -d 'country=USA' \
 -d 'search_terms=["restaurant manhattan","cafe new york"]'
 https://tools.brightlocal.com/seo-tools/api/v4/gpw/add
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
parameters.Add("report_name", "Sample SEO Check-Up Report");
parameters.Add("business_names", "Le Bernardin");
parameters.Add("schedule", "Adhoc");
parameters.Add("day_of_month", "2");
parameters.Add("report_type", "with");
parameters.Add("address1", "155 Weest 51st Street");
parameters.Add("address2", "");
parameters.Add("city", "New York");
parameters.Add("state_code", "NY");
parameters.Add("postcode", "10019");
parameters.Add("phone_number", "+1 212-554-1515");
parameters.Add("country", "USA");
parameters.Add("business-category", "Restaurant");
parameters.Add("search-terms", "['restaurant manhattan', 'cafe new york']");

var success = request.Post("/v4/gpw/add", parameters);

Success (201 Created)

{
    "success": true,
    "report-id": "1"
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "run": "You don\'t have any credits left",
    "business_names": "Please enter one business name",
    "report_type": "Report type is not available",
    "phone_number": "Please enter a telephone number",
    "postcode": "Please enter a postcode",
    "address1": "Please enter an address",
    "city": "Please enter a city",
    "search_terms": "Please enter at least one search term",
    "country": "Please choose country from the list",
    "report_name": "Please enter a report name",
    "google_location": "The location was not recognized. Please enter a correct location",
    "schedule": "Please select schedule",
    "white_label_profile_id": "Such White Label Profile doesn't exists"
  }
}

Adds a new Google+ Local Wizard report to your account.

HTTP Request

POST https://tools.brightlocal.com/seo-tools/api/v4/gpw/add

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report_name Required
location_id Associate this report with a location in your account. This ID needs to correspond to a valid location in your account.
white_label_profile_id Assign a white label profile to this report. The ID needs to correspond to a valid white label profile in your account.
business_names Required Supply one business name. For example, Greens Restaurant.
schedule Required One of Adhoc or Monthly
day_of_month Required One of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, -1 (last day of month).
report_type Required One of with or without. ‘with’ - the business has a Google Local profile. 'without’ - Ignore this business, just display competitor information. Defaults to with.
address1 Required 80 characters max. Optional for report_type=without
address2 80 characters max.
city Required Optional for report_type=without
state_code Required (USA, CAN:EN and AUS)
google_location Required A valid google search location. Please refer to our location check method.
is_public Determines whether or not to make the report available on a public URL you can give to your customers. One of Yes or No. Defaults to No.
postcode Required A valid postcode or ZIP. 80 characters max. Optional for report_type=without
phone_number Required Optional for report_type=without
country Required One of USA, CAN:EN, GBR or AUS.
search_terms Required Supply one or more search terms (max 5) as a JSON string. For example, [“restaurant san francisco”,“cafe san francisco”].
notify One of Yes or No. If set to yes we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Default is No.
email_addresses Supply one or more (max 5) email addresses for us to send report alerts to. This only takes effect if notify is set to Yes. JSON string. For example, [“email1@test.com”,“email2@test.com”].
run One of Yes or No. Runs the report after adding. Defaults to Yes.

Update Report

Account Method

Update Report

<?php
use BrightLocal\Api;
$reportId = 1;
$api = new Api(<INSERT_API_KEY>', '<INSERT_API_SECRET>);
$success = $api->put('/v4/gpw/' .$reportId, [
    'business-name'     => 'Le Bernardin',
    'contact-telephone' => '+1 212-554-1515'
]);
print_r($success);
curl -X PUT \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report_name=Le Bernardin' \
 -d 'business_names=Le Bernardin' \
 -d 'schedule=Adhoc' \
 -d 'day_of_month=2' \
 https://tools.brightlocal.com/seo-tools/api/v4/gpw/1
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var reportId = 1;
var parameters = new api.Parameters();
parameters.Add("report_name", "Sample SEO Check-Up Report");
parameters.Add("business_names", "Le Bernardin");
parameters.Add("schedule", "Adhoc");
parameters.Add("day_of_month", "2");
parameters.Add("report_type", "with");
parameters.Add("address1", "155 Weest 51st Street");
parameters.Add("address2", "");
parameters.Add("city", "New York");
parameters.Add("state_code", "NY");
parameters.Add("postcode", "10019");
parameters.Add("phone_number", "+1 212-554-1515");
parameters.Add("country", "USA");
parameters.Add("business-category", "Restaurant");
parameters.Add("search-terms", "['restaurant manhattan', 'cafe new york']");

var success = request.Put("/v4/gpw/" + reportId + "", parameters);

Success (200 OK)

{
    "success": true
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID": "Report ID invalid"
  }
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v4/gpw/<reportId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-ID Required
report_name
location_id Associate this report with a location in your account. This ID needs to correspond to a valid location in your account.
white_label_profile_id Assign a white label profile to this report. The ID needs to correspond to a valid white label profile in your account.
business_names Supply one business name. For example, Greens Restaurant.
schedule One of Adhoc or Monthly
day_of_month One of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, -1 (last day of month).
report_type One of with or without. 'with’ - the business has a Google Local profile. 'without’ - Ignore this business, just display competitor information. Defaults to with.
address1 80 characters max.
address2 80 characters max.
city
state_code (USA, CAN:EN and AUS)
postcode A valid postcode or ZIP. 80 characters max.
phone_number
country One of USA, CAN:EN, GBR or AUS.
search_terms Supply one or more search terms (max 5) as a JSON string. For example, [“restaurant san francisco”,“cafe san francisco”].
notify One of Yes or No. If set to yes we will send report alerts to all email addresses specified (see field below). If you include customer email addresses when setting up your report we’ll also email them the alerts so please be sure this is what you want before adding their addresses. Default is No.
email_addresses Supply one or more (max 5) email addresses for us to send report alerts to. This only takes effect if notify is set to Yes. JSON string. For example, [“email1@test.com”,“email2@test.com”].
google_location A valid google search location. Please refer to our location check method.
is_public Determines whether or not to make the report available on a public URL you can give to your customers. One of Yes or No. Defaults to No.
run One of Yes or No. Runs the report after adding. Defaults to Yes.

Get Report

Account Method

Get Report

<?php
use BrightLocal\Api;

$reportId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/gpw/' . $reportId);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/gpw/1
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var reportId = 1;
var parameters = new api.Parameters();

var results = request.Get("/v4/gpw/" + reportId + "", parameters);

Success (200 OK)

{
  "success": true,
      "report": {
          "report_id": "1",
          "report_name": "Report name",
          "customer_id": "1",
          "location_id": "1000",
          "schedule": "Adhoc",
          "day_of_month": "0",
          "white_label_profile_id": "24",
          "report_type": "without",
          "business_names": [
              "Business name1"
          ],
          "postcode": "90210",
          "country": "USA",
          "state_code": "IL",
          "address1": "email@test.com",
          "address2": null,
          "city": "Chicago, IL",
          "telephone": null,
          "profile_url": null,
          "search_terms": [
              "search_term1",
              "search_term2",
              "search_term3"
          ],
          "google_location": "Chicago, IL",
          "notify": "No",
          "email_addresses": [
              "email@company.com"
          ],
          "last_run_id": "626",
          "is_public": "Yes",
          "public_key": "<hidden>",
          "status": "Enabled"
      }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID invalid"
  }
}

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/gpw/<reportId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Delete Report

Account Method

Delete Report

<?php
use BrightLocal\Api;

$reportId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$result = $api->delete('/v4/gpw/' . $reportId);
if (!empty($result['success'])) {
    echo 'Successfully deleted report.' . PHP_EOL;
}
print_r($success);
curl -X DELETE \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/gpw/1
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var reportId = 1;
var parameters = new api.Parameters();
var success = request.Delete("/v4/gpw/" + reportId + "", parameters);

Success (200 OK)

{
    "success": true
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID": "Report ID invalid"
  }
}

HTTP Request

DELETE https://tools.brightlocal.com/seo-tools/api/v4/gpw/<reportId>

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Get All Reports

Account Method

Get All Reports

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/gpw/');
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/gpw
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();

var results = request.Get("/v4/gpw", parameters);

Success (200 OK)

{
    "response":  {
        "results":  [
            {
                "report_id": "49",
                "report_name": "Test 1",
                "schedule": "Weekly",
                "is_running": "Yes",
                "running_message": "Identifying your top Google Local competitors"
            },
            {
                "report_id": "50",
                "report_name": "Test 2",
                "schedule": "Monthly",
                "is_running": "No",
                "running_message": ""
            }
        ]
    }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_LOCATION_ID": "Invalid location ID supplied"
  }
}

Returns basic details about all reports associated with your account.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/gpw

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
location-id

Run Report

Account Method

Run Report

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$success = $api->put('/v4/gpw/run', [
    'report-id' => 860
]);
print_r($success);
curl -X PUT \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 -d 'report-id=860' \
  https://tools.brightlocal.com/seo-tools/api/v4/gpw/run
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var parameters = new api.Parameters();
        parameters.Add("report-id", "1");

var success = request.Put("/v4/gpw/run", parameters);

Success (200 OK)

{
    "success": true
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_REPORT_ID" : "Report ID missing",
    "NO_CREDITS" : "You don't have any credits left"
  }
}

Failure when report already running (400 Bad Request)

{
    "success": false,
    "errors":  {
      "REPORT_RUNNING": "Report is already running"
    }
}

HTTP Request

PUT https://tools.brightlocal.com/seo-tools/api/v4/gpw/run

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.
report-id Required The unique ID for the report in your account.

Get Report Results

Account Method

Get Report Results

<?php
use BrightLocal\Api;

$reportId = 1;
$api = new Api('<INSERT_API_KEY>', '<INSERT_API_SECRET>');
$results = $api->get('/v4/gpw/' . $reportId . '/results');
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
 -d 'sig=<INSERT_API_SIG>' \
 -d 'expires=<INSERT_API_EXPIRES>' \
 https://tools.brightlocal.com/seo-tools/api/v4/gpw/1/results
api request = new api("<INSERT_API_KEY>", "<INSERT_API_SECRET>");

var reportId = 1;
var parameters = new api.Parameters();

var results = request.Get("/v4/gpw/" + reportId + "/results", parameters);

Success (200 OK)

{
  "success": true,
  "results": {
    "summary": {
      "business_name": "Iron Galaxy Studios LLC",
      "address": "300 E Colorado Blvd, Pasadena, CA 91101, United States",
      "telephone": "+1 123-456-7890",
      "website_address": "http://www.example.com",
      "opening_hours": [
        "Wednesday 4PM–1AM",
        "Thursday 4PM–1AM",
        "Friday 4PM–1AM",
        "Saturday 4PM–1AM",
        "Sunday(Easter) 4PM–1AM Hours might differ",
        "Monday 4PM–1AM",
        "Tuesday 4PM–1AM"
      ],
      "profile_url": "https://www.google.co.uk/search?q=Iron+Galaxy+Studios+LLC&oq=Iron+Galaxy+Studios+LLC",
      "claimed": false,
      "citations_count": 74,
      "domain_authority": 37.65,
      "backlinks": 1395,
      "num_reviews": 6,
      "star_rating": 4,
      "review_content": "The Hotel is very conveniently located and the room nice",
      "num_photos": 0,
      "categories": [
                    "Financial Planner"
                  ]
     },          
    "keywords": {
      "iron": {
        "client_rank": 1,
        "top_10": [
          {
            "business_name": "Iron Galaxy Studios LLC",
            "rank": "A",
            "client_business": true,
            "profile_url": "https://www.google.co.uk/search?q=Iron+Galaxy+Studios+LLC&oq=Iron+Galaxy+Studios+LLC",
            "claimed": false,
            "citations_count": 74,
            "domain_authority": "37/100",
            "backlinks": 1395,
            "num_reviews": 4,
            "star_rating": "5/5",
            "num_photos": 0,
            "categories": [
              "Hotel"
            ]
          },
          {
            "business_name": "Iron Financial Management Inc",
            "rank": "B",
            "client_business": false,
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&q=Iron+Financial+Management+Inc",
            "claimed": false,
            "citations_count": 118,
            "domain_authority": "22/100",
            "backlinks": 86,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Financial Planner"
            ]
          },
          {
            "business_name": "Chicago Tube and Iron Company",
            "rank": "C",
            "client_business": false,            
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&q=Chicago+Tube+and+Iron+Company+Chicago",
            "claimed": false,
            "citations_count": 106,
            "domain_authority": "30/100",
            "backlinks": 190,
            "num_reviews": 2,
            "star_rating": "1/5",
            "num_photos": 0,
            "categories": [
              "Hotel",
              "Hotel",
              "Hotel",
              "Hotel"
            ]
          },
          {
            "business_name": "Acorn Wire &amp; Iron Works LLC",
            "rank": "D",
            "client_business": false,                   
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&gbv=2&q=Acorn+Wire+%26+Iron+Works+LLC%2C+chicago",
            "claimed": false,
            "citations_count": 56,
            "domain_authority": "29/100",
            "backlinks": 80,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 1,
            "categories": [
              "Fence Supply Store"
            ]
          },
          {
            "business_name": "Iron &amp; Wire Custom Metal Studio LLC",
            "rank": "E",
            "client_business": false,                   
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&gbv=2&q=Iron+%26+Wire+Custom+Metal+Studio+LLC%2C+chicago",
            "claimed": true,
            "citations_count": 25,
            "domain_authority": "18/100",
            "backlinks": 18,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 2,
            "categories": [
              "Metal Fabricator",
              "Interior Designer",
              "Steel Fabricator"
            ]
          },
          {
            "business_name": "Adams Street Iron Inc",
            "rank": "F",
            "client_business": false,                   
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&biw=1277&bih=573&q=Adams+Street+Iron+Inc%2C+Chicago",
            "claimed": false,
            "citations_count": 66,
            "domain_authority": "10/100",
            "backlinks": 7,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Hotel",
              "General Contractor"
            ]
          },
          {
            "business_name": "Iron Workers Union",
            "rank": "G",
            "client_business": false,                   
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&gbv=2&q=Iron+Workers+Union%2C+chicago+60130",
            "claimed": false,
            "citations_count": 39,
            "domain_authority": "48/100",
            "backlinks": 5037,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Hotel",
              "Non-Profit Organization"
            ]
          },
          {
            "business_name": "Shaw Environmental/Infrstrctr",
            "rank": "H",
            "client_business": false,                   
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&gbv=2&q=Shaw+Environmental%2FInfrstrctr%2C+chicago",
            "claimed": false,
            "citations_count": 52,
            "domain_authority": "60/100",
            "backlinks": 8884,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Hotel"
            ]
          }
        ],
        "citations_matrix": [
          {
            "domain": "facebook.com",
            "authority": "100/100",
            "count": 5,
            "businesses": [
              {
                "business_name": "Iron Galaxy Studios LLC",
                "citations_count": "74",
                "url": "https://www.facebook.com/103101903089752"
              },
              {
                "business_name": "Iron Financial Management Inc",
                "citations_count": "118",
                "url": null
              },
              {
                "business_name": "Chicago Tube and Iron Company",
                "citations_count": "106",
                "url": "https://www.facebook.com/pages/Law-Offices-of-Bernard-D-Ward-PC-708-349-5600-815-834-2000/143994815665091"
              },
              {
                "business_name": "Acorn Wire &amp; Iron Works LLC",
                "citations_count": "56",
                "url": null
              },
              {
                "business_name": "Iron &amp; Wire Custom Metal Studio LLC",
                "citations_count": "25",
                "url": "https://www.facebook.com/pages/Iron-Wire/104803202926726?sk=info"
              },
              {
                "business_name": "Adams Street Iron Inc",
                "citations_count": "66",
                "url": "https://www.facebook.com/pages/Adams-Street-Iron/117016575024837"
              },
              {
                "business_name": "Iron Workers Union",
                "citations_count": "39",
                "url": null
              },
              {
                "business_name": "Shaw Environmental/Infrstrctr",
                "citations_count": "52",
                "url": "https://www.facebook.com/pages/International-Technology-Corp/154765177895978"
              }
            ]
          },
          {
            "domain": "linkedin.com",
            "authority": "100/100",
            "count": 2,
            "businesses": [
              {
                "business_name": "Iron Galaxy Studios LLC",
                "citations_count": "74",
                "url": "https://www.linkedin.com/in/michaelpickens"
              },
              {
                "business_name": "Iron Financial Management Inc",
                "citations_count": "118",
                "url": "https://www.linkedin.com/pub/miles-muslin/18/287/950"
              },
              {
                "business_name": "Chicago Tube and Iron Company",
                "citations_count": "106",
                "url": null
              },
              {
                "business_name": "Acorn Wire &amp; Iron Works LLC",
                "citations_count": "56",
                "url": null
              },
              {
                "business_name": "Iron &amp; Wire Custom Metal Studio LLC",
                "citations_count": "25",
                "url": null
              },
              {
                "business_name": "Adams Street Iron Inc",
                "citations_count": "66",
                "url": null
              },
              {
                "business_name": "Iron Workers Union",
                "citations_count": "39",
                "url": null
              },
              {
                "business_name": "Shaw Environmental/Infrstrctr",
                "citations_count": "52",
                "url": null
              }
            ]
          }
        ],
        "nap_comparison": [
          {
            "taken_from": "User supplied",
            "business_name": "Example & Co",
            "address": "email@example.com  Chicago, IL IL",
            "postcode": "90210",
            "telephone": "4234324234"
          },
          {
            "taken_from": "Google+ Listing",
            "business_name": null,
            "address": "",
            "postcode": null,
            "telephone": null
          }
        ],
        "top_categories": {
          "Hotel": 8,
          "General Contractor": 1,
          "Non-Profit Organization": 1,
          "Steel Fabricator": 1,
          "Metal Fabricator": 1
        },
        "other_ranking_factors": []
      },
      "gold": {
        "top_10": [
          {
            "business_name": "Gold Eagle",
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&site=&source=hp&q=gold+eagle+chicago",
            "claimed": true,
            "citations_count": 62,
            "domain_authority": "45/100",
            "backlinks": 9918,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Shipping Company"
            ]
          },
          {
            "business_name": "Rickey Gold Associates",
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&q=Rickey+Gold+Associates",
            "claimed": false,
            "citations_count": 96,
            "domain_authority": "26/100",
            "backlinks": 57,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Marketing Consultant"
            ]
          },
          {
            "business_name": "Bentley Gold Coast",
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&q=Bentley+Gold+Coast%2C+Chicago&oq=Bentley+Gold+Coast%2C+Chicago",
            "claimed": false,
            "citations_count": 89,
            "domain_authority": "32/100",
            "backlinks": 87,
            "num_reviews": 58,
            "star_rating": "4.2/5",
            "num_photos": 5,
            "categories": [
              "Car Dealer"
            ]
          },
          {
            "business_name": "Gold Coast Tickets",
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&q=Gold+Coast+Tickets%2C+Chicago",
            "claimed": false,
            "citations_count": 47,
            "domain_authority": "34/100",
            "backlinks": 1362,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Event Ticket Seller"
            ]
          },
          {
            "business_name": "Gold Canyon Candles",
            "profile_url": "https://www.google.co.uk/search?newwindow=1&safe=active&q=Gold+Canyon+Candles%2C+Schaumburg%2C+IL+60193",
            "claimed": true,
            "citations_count": 19,
            "domain_authority": "n/a",
            "backlinks": 0,
            "num_reviews": 0,
            "star_rating": "0/5",
            "num_photos": 0,
            "categories": [
              "Gift Basket Store",
              "Hotel"
            ]
          }
        ],
        "citations_matrix": [
          {
            "domain": "facebook.com",
            "authority": "100/100",
            "count": 6,
            "businesses": [
              {
                "business_name": "Iron Galaxy Studios LLC",
                "citations_count": "74",
                "url": "https://www.facebook.com/103101903089752"
              },
              {
                "business_name": "Iron Financial Management Inc",
                "citations_count": "118",
                "url": null
              },
              {
                "business_name": "Chicago Tube and Iron Company",
                "citations_count": "106",
                "url": "https://www.facebook.com/pages/Law-Offices-of-Bernard-D-Ward-PC-708-349-5600-815-834-2000/143994815665091"
              },
              {
                "business_name": "Acorn Wire &amp; Iron Works LLC",
                "citations_count": "56",
                "url": null
              },
              {
                "business_name": "Iron &amp; Wire Custom Metal Studio LLC",
                "citations_count": "25",
                "url": "https://www.facebook.com/pages/Iron-Wire/104803202926726?sk=info"
              },
              {
                "business_name": "Adams Street Iron Inc",
                "citations_count": "66",
                "url": "https://www.facebook.com/pages/Adams-Street-Iron/117016575024837"
              },
              {
                "business_name": "Iron Workers Union",
                "citations_count": "39",
                "url": null
              },
              {
                "business_name": "Shaw Environmental/Infrstrctr",
                "citations_count": "52",
                "url": "https://www.facebook.com/pages/International-Technology-Corp/154765177895978"
              },
              {
                "business_name": "Gold Eagle",
                "citations_count": "62",
                "url": null
              },
              {
                "business_name": "Rickey Gold Associates",
                "citations_count": "96",
                "url": null
              },
              {
                "business_name": "Bentley Gold Coast",
                "citations_count": "89",
                "url": "https://www.facebook.com/pages/Bentley-Gold-Coast/135572886504845"
              },
              {
                "business_name": "Gold Coast Tickets",
                "citations_count": "47",
                "url": null
              },
              {
                "business_name": "Gold Canyon Candles",
                "citations_count": "19",
                "url": null
              }
            ]
          },
          {
            "domain": "linkedin.com",
            "authority": "100/100",
            "count": 2,
            "businesses": [
              {
                "business_name": "Iron Galaxy Studios LLC",
                "citations_count": "74",
                "url": "https://www.linkedin.com/in/michaelpickens"
              },
              {
                "business_name": "Iron Financial Management Inc",
                "citations_count": "118",
                "url": "https://www.linkedin.com/pub/miles-muslin/18/287/950"
              },
              {
                "business_name": "Chicago Tube and Iron Company",
                "citations_count": "106",
                "url": null
              },
              {
                "business_name": "Acorn Wire &amp; Iron Works LLC",
                "citations_count": "56",
                "url": null
              },
              {
                "business_name": "Iron &amp; Wire Custom Metal Studio LLC",
                "citations_count": "25",
                "url": null
              },
              {
                "business_name": "Adams Street Iron Inc",
                "citations_count": "66",
                "url": null
              },
              {
                "business_name": "Iron Workers Union",
                "citations_count": "39",
                "url": null
              },
              {
                "business_name": "Shaw Environmental/Infrstrctr",
                "citations_count": "52",
                "url": null
              },
              {
                "business_name": "Gold Eagle",
                "citations_count": "62",
                "url": null
              },
              {
                "business_name": "Rickey Gold Associates",
                "citations_count": "96",
                "url": null
              },
              {
                "business_name": "Bentley Gold Coast",
                "citations_count": "89",
                "url": null
              },
              {
                "business_name": "Gold Coast Tickets",
                "citations_count": "47",
                "url": null
              },
              {
                "business_name": "Gold Canyon Candles",
                "citations_count": "19",
                "url": null
              }
            ]
          }
        ],
        "nap_comparison": [
          {
            "taken_from": "User supplied",
            "business_name": "Example & Co",
            "address": "email@example.com  Chicago, IL IL",
            "postcode": "85300",
            "telephone": "4234324234"
          },
          {
            "taken_from": "Google+ Listing",
            "business_name": null,
            "address": "",
            "postcode": null,
            "telephone": null
          }
        ],
        "top_categories": {
          "Gift Basket Store": 1,
          "Hotel": 1,
          "Event Ticket Seller": 1,
          "Car Dealer": 1,
          "Marketing Consultant": 1
        },
        "other_ranking_factors": []
      }
    },
    "urls": {
      "report_url": "https://tools.brightlocal.com/seo-tools/admin/gpw/reports/view/275",
      "wl_url": "http://local-marketing-reports.com/google-plus-reports/<hidden>/275"
    }
  }
}

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
    "INVALID_LOCATION_ID": "Invalid location ID supplied"
  } 
}

Return report URLs and raw data.

HTTP Request

GET https://tools.brightlocal.com/seo-tools/api/v4/gpw/<reportId>/results

Query Parameters

Parameter Notes
api-key Required
sig Required See above for how to generate signature and expires values.
expires Required See above for how to generate signature and expires values.

Business Categories

Fetch Business Categories

Account Method

<?php
use BrightLocal\Api;

$api = new Api('<INSERT_API_KEY>');
$country = 'USA';
$results = $api->get('/v1/business-categories/' . $country);
print_r($results);
curl -X GET \
 -d 'api-key=<INSERT_API_KEY>' \
  https://tools.brightlocal.com/seo-tools/api/v1/business-categories/USA
api request = new api("<INSERT_API_KEY>");
var results = request.Get("/seo-tools/api/v1/business-categories/USA");

Success (200 OK)

[
    {
        "id": 503,
        "name": "Advertising Agency"
    }
]

Validation Failure (400 Bad Request)

{
  "success": false,
  "errors":  {
     "INVALID_COUNTRY": "Country is not supported"
  }
}

HTTP Request

Get all business categories for certain country. See here for a full list of supported countries.

GET https://tools.brightlocal.com/seo-tools/api/v1/business-categories/<country>

Useful Tools

Apigee produces a free API testing tool which may help you to interactively query our API.

Appendix

Constructing Google+ URLs

<?php
$url = 'https://www.google.com/search?' . http_build_query([
    'q'    => sprintf('"%s" "%s" %s', 'Hub Plumbing & Mechanical Inc', 'New York', '212-482-8500'),
]);
<?php
$url = 'https://www.google.com/search?' . http_build_query([
    'q'   => sprintf('"%s" "%s"', 'Pizza Hut', '67337'),
]);    

Google recently simplified their Google+ profile pages and removed much of the useful profile information that we normally gather through APIs documented here, such as NAP and reviews. Consequently we have stopped using Google+ Local listings and have instead started tracking business profile information via Google SERP pages. This means that when requesting Google profile data or reviews via our API you need to supply us with a pre-formatted search URL rather than the plus URL that corresponds to that business. Your search URL should be constructed with one of the following formats:

Business names (in quotes) + zip code (in quotes) and phone number (without quotes)

https://www.google.com/search?q="Hub+Plumbing+%26+Mechanical+Inc"+"New+York"+212-482-8500

Business name (in quotes) + zipcode (in quotes)

https://www.google.com/search?q="Pizza+Hut"+"67337"

One format may work better than another for a specific business so we recommend testing both approaches to find the optimal profile URL. The code snippets on the right give examples of how to generate each type of URL.

Supported Local Directories

The following tables provide details of the local directories we support for looking up profile URLs, profile details and/or reviews. For some directories we are able to grab all information and for others only partial information due to restrictions on certain sites or due to complications in the data gathering process (e.g. site uses JS to mask certain data points or doesn’t present listing on separate, distinct URLs)

Key for tables

United States (USA)

Identifier NAP Reviews Find Profile URL Website URL Notes
2findlocal Yes Yes
411com Yes Yes Yes
aboutus Yes Yes
acxiom Yes No longer available
agreatertown Yes Yes
allpages Yes Yes Yes Yes No longer available
angies Yes Yes Yes
b2byellowpages Yes Yes Yes
bbb Yes Yes Yes Yes
bizdays Yes Yes
bizexposed Yes Yes Yes
bizvotes Yes Yes
botw Yes Yes Yes Yes
brownbook Yes Yes Yes Yes
businessnetpages Yes Yes
callupcontact Yes Yes Yes
cbsyellowpages Yes Yes Yes
chamberofcommerce Yes Yes Yes
checkmyreview Yes Yes Yes
cityfos Yes Yes Yes
citysearch Yes Yes Yes
citysquares Yes Yes Yes
cmac