Analyze web presence

Use a Middesk website order to receive a detailed analysis of a business’s web presence and evaluate a business’s web presence quality.

Web Analysis can be ordered independently as a standalone product or alongside other Middesk products. A Verify report is not required to order Web Analysis.

How to order web analysis

  • Ensure that you can authenticate against the Middesk API and create businesses
  • Review the Middesk Postman collection for request examples
1

Create a business and order Web Analysis

Web Analysis is a subproduct of the Website order. To create a business with a website order, submit a Create Business request:

1require 'uri'
2require 'net/http'
3
4url = URI("https://api.middesk.com/v1/businesses")
5
6http = Net::HTTP.new(url.host, url.port)
7
8request = Net::HTTP::Post.new(url)
9request["Content-Type"] = 'application/json'
10request["Authorization"] = '<Your Auth Token>'
11request.body = "{\n \"name\": \"Joe's Bakery\",\n \"addresses\": [\n\t {\n\t\t \"full_address\": \"123 Main Street, Tampa, FL 33626\"\n\t }\n ],\n \"website\": {\n\t \"url\": \"www.joesbakery.com\"\n },\n\t\"orders\": [\n\t\t{\n\t\t \"product\": \"website\",\n\t\t \"subproducts\": [\"web_analysis\"]\n\t\t}\n\t]\n}"
12
13response = http.request(request)
14puts response.read_body

Middesk determines which subproducts to order based on what’s included in your API request.

The name and address are required for web analysis. website_url is optional. If you don’t submit website_url, Middesk discovers the business’s website to perform further analysis.

Website URL in payload?Website package specified?Subproducts specified?What gets ordered
✅ Yes❌ NoN/AAll enabled subproducts
✅ Yes✅ Yes✅ YesOnly specified subproducts
✅ Yes✅ Yes❌ NoAll enabled subproducts
❌ No✅ Yes✅ YesOnly specified subproducts
❌ No✅ Yes❌ NoAll enabled subproducts
2

Review the analysis results

Once your order completes, see the results in the GET /business payload or the business.updated webhook, depending on your integration.

For a high-level summary of the outcome, review these review tasks:

SummaryKey
Is the website purchased but has no content?website_parked
Is the website online?website_status
Is the website URL submitted or discovered?website_url_discovered
Was there a match identified to the submitted office address?web_address_verification
Was there a match identified to the submitted business name?web_business_name_verification
Was there a match identified to the submitted person?web_person_verification
Was there a match identified to the submitted phone number?web_phone_number_verification
Was there a match identified to the submitted email address?web_email_address_verification
What is the web presence quality rating?web_presence_quality
Does the submitted website URL belong to the business?website_url_domain_ownership
Does the web presence include any risky keyword hits?risky_keywords

To see the results in more detail, look at the Website object in the payload as well as the specific Web Analysis review tasks.

Additionally, any third-party profiles associated with the business are returned here as Profile objects under the top level profiles key. This includes platforms such as Google, Facebook, LinkedIn, and more.

Check the business’s review tasks by requesting the full business payload using the GET /businesses endpoint.

For example, use the Website Status review task to evaluate whether website is online.

1require 'net/http'
2require 'net/https'
3require 'json'
4
5def send_request
6 business_id = "<business_id>"
7 uri = URI("https://api.middesk.com/v1/businesses/#{business_id}")
8
9 # Create client
10 http = Net::HTTP.new(uri.host, uri.port)
11 http.use_ssl = true
12 http.verify_mode = OpenSSL::SSL::VERIFY_PEER
13
14 # Create Request
15 req = Net::HTTP::Get.new(uri)
16 # Add headers
17 req.add_field "Accept", "application/json"
18 # Add headers
19 req.add_field "Authorization", "Basic <api_key>"
20
21 # Fetch Request
22 res = http.request(req)
23
24 response = JSON.parse(res.body)
25 website_status_task = response['review']['tasks'].find { |task| task['key'] == 'website_status' }
26
27 if website_status_task['status'] == 'success'
28 puts 'Website online'
29 else
30 puts 'Website offline'
31 end
32rescue StandardError => e
33 puts "HTTP Request failed (#{e.message})"
34end
3

Inspect individual quality indicators

Use web_presence_quality to determine an overall quality rating of High, Moderate, Low, or Not Available of the business’s web presence. Going one step further, inspect each quality indicator used to determine the overall quality rating and optionally, derive an outcome based on your own defined heuristics.

One example of a potential use case for directly inspecting the indicators is in the case of evaluating new businesses. Naturally a newly formed business may have a recently registered domain and possibly is perfectly okay for the site to not display a high amount of content diversity, given its recent inception. If that is the case, you may wish to explicitly ignore those ratings to determine your desired outcome.

Here’s a look at the current quality indicators and their respective keys within the website object. Each indicator includes a rating field of its own, yielding a positive, neutral, or negative rating for each category type. If the indicator cannot be accurately determined for any reason, the indicator is absent from the payload.

Quality IndicatorDescriptionKey
Broken linksAn evaluation of links found on the website leading to errors or nonexistent pagesbroken_links
Compliance infoAn evaluation of compliance-related information, such as terms of service and privacy policy, that can be found on the business’s websitecompliance_info
Contact infoAn evaluation of contact information found within the content. You can leverage the other review tasks associated with the Website order to determine matches with submitted contact information.contact_info
Content diversityAn evaluation of the variation and type of information the website presentscontent_diversity
Domain ageAn evaluation of how long the domain has been registereddomain_age
Domain consistencyAn evaluation of whether the domain matches the business name and brandingdomain_consistency
Domain ownershipAn evaluation of how likely it is the domain belongs to the businessdomain_ownership
Filler textAn evaluation of content for any placeholder or filler text, like Lorem Ipsumfiller_text
HttpsAn evaluation of HTTPS/TLS supporthttps
Image qualityAn evaluation of images to identify blurry or stock imagesimage_quality
Last updatedAn evaluation of how long ago was the website last modifiedlast_updated
Page countAn evaluation of the total number of internal pages found on the websitepage_count
Spelling and grammarAn evaluation of spelling and grammatical mistakes and inconsistenciesspelling_and_grammar
TestimonialsAn evaluation of customer testimonials or reviews found on the websitetestimonials
Third party profile linksAn evaluation of links to third-party profiles (social media, review sites, and so on) found on the websitethird_party_profile_links
Top Level DomainAn evaluation of the TLD with respect to the website’s qualitytop_level_domain
Update frequencyAn evaluation of how often the website’s content is updatedupdate_frequency
US Business PresenceAn evaluation of website signals that suggest the business operates within the United Statesus_business_presence

You can retrieve these additional website details via the GET /businesses/{id}/website endpoint. Here’s an example iterating and printing out the sample business’s website’s quality indicator ratings:

1require 'net/http'
2require 'uri'
3require 'json'
4require 'base64'
5
6def print_indicators_quality_ratings
7 # Replace with your actual business ID and API key
8 business_id = "51c4b91e-f324-467b-86b5-9e0155bcc251" # Example business ID
9 api_key = "YOUR_API_KEY_HERE" # Replace with your actual API key
10
11 uri = URI.parse("https://api.middesk.com/v1/businesses/#{business_id}/website")
12
13 # Create the HTTP Basic Auth header
14 auth = Base64.strict_encode64("#{api_key}:")
15
16 headers = {
17 "Accept" => "application/json",
18 "Authorization" => "Basic #{auth}"
19 }
20
21 # Create the HTTP request
22 http = Net::HTTP.new(uri.host, uri.port)
23 http.use_ssl = true
24 request = Net::HTTP::Get.new(uri.request_uri, headers)
25
26 begin
27 # Make the request
28 response = http.request(request)
29
30 # Raise an error if the response is not successful
31 unless response.is_a?(Net::HTTPSuccess)
32 puts "HTTP Request failed (#{response.code} #{response.message})"
33 return
34 end
35
36 # Parse the JSON response
37 data = JSON.parse(response.body)
38
39 # Navigate to the indicators
40 indicators = data.dig('rating', 'indicators') || []
41
42 if indicators.empty?
43 puts "No indicators found in the response."
44 return
45 end
46
47 # Print each indicator's name and rating
48 puts "Indicators' Quality Ratings:"
49 puts "----------------------------"
50 indicators.each do |indicator|
51 name = indicator['name'] || 'Unknown Indicator'
52 rating = indicator['rating'] || 'No Rating'
53 description = indicator['description'] || ''
54
55 puts "#{name}: #{rating} (#{description})"
56 end
57 rescue JSON::ParserError
58 puts "Error parsing JSON response."
59 rescue StandardError => e
60 puts "An error occurred: #{e.message}"
61 end
62end
63
64print_indicators_quality_ratings
65
66# Sample Output:
67# Indicators' Quality Ratings:
68# ----------------------------
69# Domain age: positive (3 to 10 years old)
70# Domain ownership: positive (High confidence)
71# Compliance info: positive (Found)
72# Spelling and grammar: positive (Good)
73# Contact info: positive (Found)
74# Content diversity: positive (High)
75# Https: positive (Enabled)
76# Broken links: negative (Some broken)
77# Filler text: positive (Minimal)
78# Page count: positive (High)
79# Image quality: positive (Good)

Access more details

The API also exposes a source object for each indicator to illustrate how the indicator quality rating was derived. This includes a human-readable explanation and, when relevant, examples from the retrieved dataset respective to the indicator returned. For example, the image_quality indicator returns a list of source URLs for any stock images detected, the spelling_and_grammar indicator lists citations for any found mistakes or inconsistencies, and the broken_links indicator returns a list of URLs found on the website that do not resolve.

To access this expanded view, add the query parameter include with the value indicator_details to the aforementioned business website endpoint.

For example: https://api.middesk.com/businesses/{id}/website?include=indicator_details

Here is an example of the expanded quality rating indicator with new source key:

JSON
1{
2 "type": "image_quality",
3 "name": "Image quality",
4 "rating": "negative",
5 "source": {
6 "examples": [
7 {
8 "link": "https://images.unsplash.com/photo-1637684666451-423047d6bf5e?ixid=M3wzOTE5Mjl8MHwxfHNlYXJjaHw4fHxzdGFydHVwfGVufDB8fHx8MTcxNDg3ODI0Nnww\u0026ixlib=rb-4.0.3\u0026auto=format\u0026fit=crop\u0026w=1920",
9 "location": "https://example.com/contact",
10 "classification": "stock_image"
11 },
12 {
13 "link": "https://images.unsplash.com/photo-1588856122867-363b0aa7f598?ixid=M3wzOTE5Mjl8MHwxfHNlYXJjaHw1fHxzdGFydHVwfGVufDB8fHx8MTcxNDg3ODI0Nnww\u0026ixlib=rb-4.0.3\u0026auto=format\u0026fit=crop\u0026w=328\u0026h=332",
14 "location": "https://example.com/",
15 "classification": "stock_image"
16 },
17 {
18 "link": "https://images.unsplash.com/photo-1519389950473-47ba0277781c?ixid=M3wzOTE5Mjl8MHwxfHNlYXJjaHwyfHxzdGFydHVwfGVufDB8fHx8MTcxNDg3ODI0Nnww\u0026ixlib=rb-4.0.3\u0026auto=format\u0026fit=crop\u0026w=1224\u0026h=400",
19 "location": "https://example.com/",
20 "classification": "stock_image"
21 },
22 {
23 "link": "https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?ixid=M3wzOTE5Mjl8MHwxfHNlYXJjaHw2fHxzdGFydHVwfGVufDB8fHx8MTcxNDg3ODI0Nnww\u0026ixlib=rb-4.0.3\u0026auto=format\u0026fit=crop\u0026w=606\u0026h=304",
24 "location": "https://example.com/about",
25 "classification": "stock_image"
26 },
27 {
28 "link": "https://images.unsplash.com/photo-1553729459-efe14ef6055d?auto=format\u0026fit=crop\u0026w=328\u0026h=264",
29 "location": "https://example.com/company",
30 "classification": "stock_image"
31 }
32 ],
33 "explanation": "Many stock images were found."
34 },
35 "value": "poor",
36 "description": "Poor"
37}
Get a demo
Contact your account manager or contact sales to inquire about access.