Site

A Site is the primary object in the Scanerr application and represents the primary domain name all pages of that Site share. The Site object is how the Scanerr platform organizes all subsequent objects including Pages, Scans, Tests, Schedules, Automations, and Testcases.

Site object

{
   "id":"46053956-761b-4ca5-8cec-3be796695d12",            // uuid specific to the Site
   "user":"example@gmail.com",                             // user denoted by email
   "site_url":"https://example.com",                       // Site's url begining with https:// or http://
   "time_created":"2021-11-18T15:58:42.821177Z",           // timestamp of object creation
   "time_crawl_started":"2021-11-18T15:58:42.821177Z",     // timestamp of when last site crawl began
   "time_crawl_completed":"2021-11-18T15:58:42.821177Z",   // timestamp of when last site crawl completed
   "tags": ["tag1", "tag2"],                               // <optional> list of info for user to track data
   "info":{ 
      "status":{
         "badge":"success",   // info for front-end badge coloring
         "score": 69.25,      // health score, combination of yellowlab and lighthouse. Type -> float
         "health":"Good"      // health status (Good, Okay, Poor)
      },
      "yellowlab":{           // high level Yellow Lab scores
         "fonts": 100,
         "badCSS": 95,
         "jQuery": 100,
         "images": 100,
         "pageWeight": 94,
         "globalScore": 67,
         "serverConfig": 100,
         "badJavascript": -5,
         "cssComplexity": 99,
         "domComplexity": 100,
         "javascriptComplexity": -28
      },
      "lighthouse":{          // high level Lighthouse scores
         "seo": 85,    
         "average": 78.25,  
         "performance": 60,  
         "accessibility": 75,   
         "best_practices": 93,   
         "pwa": 89,
         "crux": 90
      },
      
      "latest_scan":{
         "id":"fdbfea8a-d049-45df-8085-2be020e3e193",          // most recent Scan uuid
         "time_created":"2021-11-19 19:35:54.297510+00:00",    // timestamp of most recent Scan creation
         "time_completed":"2021-11-19 19:38:58.345660+00:00",  // timestamp of most recent Scan completion
      },
      "latest_test":{
         "id":"eff40980-a9c2-45d6-8929-99564715a216",          // most recent Test uuid
         "score": 97,                                          // most recent Test score (out of 100)
         "time_created":"2021-11-19 19:35:28.315063+00:00",    // timestamp of most recent Test creation
         "time_completed":"2021-11-19 19:38:58.345660+00:00",  // timestamp of most recent Test completion
      }
   }
}

Create a Site

There are two endpoints for creating a Site. The most commonly used is the delay endpoint which allows the creation task to run asynchronously on the server and resolves quickly. Alternatively, you may use the traditional endpoint which may take several minutes to resolve as the server is actively crawling your site for Pages and creating initial base-line Scans for each.

data in this request:

"data": {
   
   "site_url": "https://example.com",     // <required> 
   "page_urls": [                         // <optional> an array of page urls you want to add to the site. This prevents the site from being crawled
      "https://example.com",
      "https://example.com/blog",
      "https://example.com/terms"
   ],    
   "tags": ["tag1", "tag2"],              // <optional> for user to track data
   "no_scan": false,                      // <optional> bool parameter which, when true, will skip the initial Scan creation (defaults to false)
   
   "configs": {                           // <optional> Configurations for webdriver (only needed if no_scan == False)
      "driver": "selenium",               // webdriver type - one of selenium or puppeteer
      "device": "desktop",                // sets the user-Agent, one of dekstop or mobile
      "mask_ids": null,                   // element id's you wish to mask when taking a screenshot (seperated by comma)
      "interval": 5,                      // time (seconds) the driver will wait between checking if page has loaded
      "window_size": "1920,1080",         // dimensions of webdriver window. format -> (width,height)
      "max_wait_time": 60,                // maximum time (seconds) the driver will wait before moving on to next task
      "min_wait_time": 10,                // minimum time (seconds) the driver will wait before checking if page has loaded and or moving on to next task
      "disable_animations": false,        // bool which, when true, will disable all animations and videos on the site during a Scan
      "timeout": 300                      // maximum time (seconds) the driver will run before completely timing out during an the VRT process
   }

}

WARNING

Passing the configs object is optional. However, if you do pass the object you must specify all sub-components.

POST - /site/delay

# import env vars
SCANERR_API_BASE_URL = os.environ.get('SCANERR_API_BASE_URL')
SCANERR_API_TOKEN = os.environ.get('SCANERR_API_BASE_URL')

# setup configs
url = f'{SCANERR_API_BASE_URL}/site/delay'
headers = {
   "content-type": "application/json",
   "Authorization" : SCANERR_API_TOKEN
}
data = {
   "site_url": "https://example.com"   # <required>
   "page_urls": [                      # <optional> an array of page urls you want to add to the site. This prevents the site from being crawled
      "https://example.com",
      "https://example.com/blog",
      "https://example.com/terms"
   ], 
   "tags": ["tag1", "tag2"]         # <optional> list of info for user to track data
   "no_scan": False,                # <optional> bool parameter which, when true, will skip the initial Scan creation (defaults to false)
   "configs": {                     # <optional> Configurations for webdriver (only needed if no_scan == False)
      "driver": "selenium",         # webdriver type - one of selenium or puppeteer
      "device": "desktop",          # sets the user-Agent, one of dekstop or mobile
      "mask_ids": None,             # element id's you wish to mask when taking a screenshot (seperated by comma)
      "interval": 5,                # time (seconds) the driver will wait between checking if page has loaded
      "window_size": "1920,1080",   # dimensions of webdriver window. format -> (width,height)
      "max_wait_time": 60,          # maximum time (seconds) the driver will wait before moving on to next task
      "min_wait_time": 10           # minimum time (seconds) the driver will wait before checking if page has loaded and or moving on to next task
   }
}

# send the request
res = requests.post(
   url=url, 
   headers=headers, 
   data=json.dumps(data)
)

# retrieve response data
json_response = res.json()
print(json_response)

View Full Output

Output:


{
    "id":"188b882a-f644-4304-b2b9-def9d8c76b57",
    "user":"example@gmail.com",
    "site_url":"https://example.com",
    "time_created":"2021-11-22T14:54:19.134671Z",
    "tags": ["tag1", "tag2"],
    "info":{
        "latest_scan":{
            "id": null,
            "time_created": null,
            "time_completed": null,
         },
        "latest_test":{
            "id": null,
            "time_created": null,
            "score": null
        },
        "yellowlab":{
         "fonts": null,
         "badCSS": null,
         "jQuery": null,
         "images": null,
         "pageWeight": null,
         "globalScore": null,
         "serverConfig": null,
         "badJavascript": null,
         "cssComplexity": null,
         "domComplexity": null,
         "javascriptComplexity": null
         },
         "lighthouse":{   
            "seo": null,    
            "average": null,  
            "performance": null,  
            "accessibility": null,   
            "best_practices": null,
            "pwa": null,
            "crux": null    
         },
         "status":{
            "score": null,
            "health": null,
            "badge": "neutral"
         }
    }
}


Retrieve a Site

This endpoint returns a single Site object and is useful as a simple "detailed view" of the site.

GET - /site/<site:id>

import requests, os

# import env vars
SCANERR_API_BASE_URL = os.environ.get('SCANERR_API_BASE_URL')
SCANERR_API_TOKEN = os.environ.get('SCANERR_API_BASE_URL')

# setup configs
url = f'{BASE_URL}/site/<site:id>'
headers = {
    "content-type": "application/json",
    "Authorization" : SCANERR_API_TOKEN
}

# send the request
res = requests.get(
    url=url, 
    headers=headers, 
)

# retrieve response data
json_response = res.json()
print(json_response)

View Full Output

Output:

{
   "id":"46053956-761b-4ca5-8cec-3be796695d12",
   "user":"example@gmail.com",
   "site_url":"https://example.com",
   "time_created":"2021-11-18T15:58:42.821177Z",
   "tags": ["tag1", "tag2"],
   "info":{
      "status":{
         "badge":"success",
         "health":"Good",
         "score": 80,
      },
      "yellowlab":{ 
         "fonts": 100,
         "badCSS": 95,
         "jQuery": 100,
         "images": 100,
         "pageWeight": 94,
         "globalScore": 67,
         "serverConfig": 100,
         "badJavascript": -5,
         "cssComplexity": 99,
         "domComplexity": 100,
         "javascriptComplexity": -28
      },
      "lighthouse":{
         "seo": 85,
         "average": 78.25,
         "performance": 60,
         "accessibility": 75,
         "best_practices": 93,
         "pwa": 89,
         "crux": 90,
      },
      "latest_scan":{
         "id":"fdbfea8a-d049-45df-8085-2be020e3e193",
         "time_created":"2021-11-19 19:35:54.297510+00:00",
         "time_completed":"2021-11-19 19:38:58.345660+00:00",
      },
      "latest_test":{
         "id":"eff40980-a9c2-45d6-8929-99564715a216",
         "score": 97,
         "time_created":"2021-11-19 19:35:28.315063+00:00",
         "time_completed":"2021-11-19 19:38:58.345660+00:00",
      }
   }
}

Retrieve many Sites

This endpoint returns a paginated response with all Site objects filtered by your account and ordered by time_created. This endpoint is useful when needing to displaying your sites in a table view for example. The limit parameter specifies the total number of objects you want returned per "group" (we recomend keeping this under 10 for best performance). The offset parameter specfies which "group" to return. For example, limit=10&offset=10 in a total dataset of 30 objects would return 10 sites in range site #10 - site #20.

GET - /site?limit=10&offset=0

import requests, os

# import env vars
SCANERR_API_BASE_URL = os.environ.get('SCANERR_API_BASE_URL')
SCANERR_API_TOKEN = os.environ.get('SCANERR_API_BASE_URL')

# setup configs
url = f'{BASE_URL}/site?limit=10&offset=0'
headers = {
    "content-type": "application/json",
    "Authorization" : SCANERR_API_TOKEN
}

# send the request
res = requests.get(
    url=url, 
    headers=headers, 
)

# retrieve response data
json_response = res.json()
print(json_response)

View Full Output

Output:

{
   "count":30,
   "next":"https://api.scanerr.io/v1/ops/site?limit=10&offset=20",
   "previous":"https://api.scanerr.io/v1/ops/site?limit=10&offset=10",
   "results":[
      {
         "id":"46053956-761b-4ca5-8cec-3be796695d12",
         "user":"example@gmail.com",
         "site_url":"https://example.com",
         "time_created":"2021-11-18T15:58:42.821177Z",
         "tags": ["tag1", "tag2"],
         "info":{
            "status":{
               "badge":"success",
               "health":"Good",
               "score": 80,
            },
            "yellowlab":{ 
               "fonts": 100,
               "badCSS": 95,
               "jQuery": 100,
               "images": 100,
               "pageWeight": 94,
               "globalScore": 67,
               "serverConfig": 100,
               "badJavascript": -5,
               "cssComplexity": 99,
               "domComplexity": 100,
               "javascriptComplexity": -28
            },
            "lighthouse":{
               "seo": 85,
               "average": 78.25,
               "performance": 60,
               "accessibility": 75,
               "best_practices": 93,
               "pwa": 89,
               "crux": 90,
            },
            "latest_scan":{
               "id":"fdbfea8a-d049-45df-8085-2be020e3e193",
               "time_created":"2021-11-19 19:35:54.297510+00:00",
               "time_completed":"2021-11-19 19:38:58.345660+00:00",
            },
            "latest_test":{
               "id":"eff40980-a9c2-45d6-8929-99564715a216",
               "score": 97,
               "time_created":"2021-11-19 19:35:28.315063+00:00",
               "time_completed":"2021-11-19 19:38:58.345660+00:00",
            }
         }
      },
      {
         "id":"46053956-761b-4ca5-8cec-3be796695d12",
         "user":"example@gmail.com",
         "site_url":"https://exampletwo.com",
         "time_created":"2021-11-18T15:58:42.821177Z",
         "tags": ["tag1", "tag2"],
         "info":{
            "status":{
               "badge":"success",
               "health":"Good",
               "score": 80,
            },
            "yellowlab":{ 
               "fonts": 100,
               "badCSS": 95,
               "jQuery": 100,
               "images": 100,
               "pageWeight": 94,
               "globalScore": 67,
               "serverConfig": 100,
               "badJavascript": -5,
               "cssComplexity": 99,
               "domComplexity": 100,
               "javascriptComplexity": -28
            },
            "lighthouse":{
               "seo": 85,
               "average": 78.25,
               "performance": 60,
               "accessibility": 75,
               "best_practices": 93
               "pwa": 89,
               "crux": 90
            },
            "latest_scan":{
               "id":"fdbfea8a-d049-45df-8085-2be020e3e193",
               "time_created":"2021-11-19 19:35:54.297510+00:00",
               "time_completed":"2021-11-19 19:38:58.345660+00:00",
            },
            "latest_test":{
               "id":"eff40980-a9c2-45d6-8929-99564715a216",
               "score": 97,
               "time_created":"2021-11-19 19:35:28.315063+00:00",
               "time_completed":"2021-11-19 19:38:58.345660+00:00",
            }
         }
      },
      {
         "id":"46053956-761b-4ca5-8cec-3be796695d12",
         "user":"example@gmail.com",
         "site_url":"https://examplethree.com",
         "time_created":"2021-11-18T15:58:42.821177Z",
         "tags": ["tag1", "tag2"],
         "info":{
            "status":{
               "badge":"success",
               "health":"Good",
               "score": 80,
            },
            "yellowlab":{ 
               "fonts": 100,
               "badCSS": 95,
               "jQuery": 100,
               "images": 100,
               "pageWeight": 94,
               "globalScore": 67,
               "serverConfig": 100,
               "badJavascript": -5,
               "cssComplexity": 99,
               "domComplexity": 100,
               "javascriptComplexity": -28
            },
            "lighthouse":{
               "seo": 85,
               "average": 78.25,
               "performance": 60,
               "accessibility": 75,
               "best_practices": 93,
               "pwa": 89,
               "crux": 90
            },
            "latest_scan":{
               "id":"fdbfea8a-d049-45df-8085-2be020e3e193",
               "time_created":"2021-11-19 19:35:54.297510+00:00",
               "time_completed":"2021-11-19 19:38:58.345660+00:00",
            },
            "latest_test":{
               "id":"eff40980-a9c2-45d6-8929-99564715a216",
               "score": 97,
               "time_created":"2021-11-19 19:35:28.315063+00:00",
               "time_completed":"2021-11-19 19:38:58.345660+00:00",
            }
         }
      },
      ### SHORTENED FOR DISPLAY PURPOSES ###
   ]
}

Delete a Site

Because Sites are the primary objects within the Scanerr API, once a Site is deleted a cascade effect ensues and all assocaited Scans , Tests, Schedules, and Automations are subsequently deleted.

DANGER

Please use caution with this endpoint as it is irreversible.

DELETE - /site/<site:id>

import requests, os

# import env vars
SCANERR_API_BASE_URL = os.environ.get('SCANERR_API_BASE_URL')
SCANERR_API_TOKEN = os.environ.get('SCANERR_API_BASE_URL')

# setup configs
url = f'{BASE_URL}/site/<site:id>'
headers = {
    "content-type": "application/json",
    "Authorization" : SCANERR_API_TOKEN
}

# send the request
res = requests.delete(
    url=url, 
    headers=headers, 
)

# retrieve response data
json_response = res.json()
print(json_response)

View Full Output

Output:

    {
        "message": "site deleted successfully"
    }

Delete many Sites

This endpoint allows the user to send an array of Site id's to be deleted. Scanerr will iterate through the id's and respond with an object detailing which Sites were successfully deleted and which were not.

DANGER

Please use caution with this endpoint as it is irreversible.

POST - /sites/delete

import requests, os

# import env vars
SCANERR_API_BASE_URL = os.environ.get('SCANERR_API_BASE_URL')
SCANERR_API_TOKEN = os.environ.get('SCANERR_API_BASE_URL')

# setup configs
url = f'{BASE_URL}/sites/delete'
headers = {
    "content-type": "application/json",
    "Authorization" : SCANERR_API_TOKEN
}

data = {
   "ids": ['<site:id1>', '<site:id2>', '<site:id3>']
}

# send the request
res = requests.post(
    url=url, 
    headers=headers, 
    data=data,
)

# retrieve response data
json_response = res.json()
print(json_response)

View Full Output

Output:

    {
      "status": true,
      "num_succeeded": 3,
      "succeeded": [
         '<site:id1>', 
         '<site:id2>', 
         '<site:id3>'
      ],
      "num_failed": 0,
      "failed": []
    }

Last Updated:
Contributors: landon, Landon