API v3.0 Introduction
Your API Endpoint
https://{your_name}.api.creativeqa.net/v3.0/
Hook up your server and automatically scan creatives before they go live. The API is organized around REST, and returns JSON for all responses.
Find your API endpoint URL here at the right.
Getting an API Key
To get an API Key, please sign up here. A key will be emailed within minutes.
Authentication
Add your API Key as a header
# Add the Authorization header to each request
curl "https://{your_name}.api.creativeqa.net/v3.0/"
-H "X-ApiKey: {api_key}"
-X POST
API Keys are used to authenticate requests. Add your key to each request as a header with the name X-ApiKey
.
Keep your API key private as much as you do with passwords.
Rate Limits
Rate limits are calculated dynamically based on the load of the worker nodes.
If no resources are available, the API will respond with a 400
HTTP code and an error message.
It's generally recommended to wait for a response before sending a new one. To process batches of tags, submit
them one by one instead of all at the same time.
Error Handling
Example of an error
{ "error_type": "payload_error", "message": "There was an error." }
Conventional HTTP response codes are used to indicate if a request failed or was successful.
Codes in the 2xx
range indicate success.
Codes in the 4xx
range indicate that the request failed. In that case,
the JSON response will hold an error code and human-readable error message.
Error Types
authentication_error string, solvable |
The X-ApiKey header was not added or the key was incorrect. Contact support if you need help. |
license_error string, solvable |
Your license has not been approved or has expired. Contact support for more information. |
invalid_endpoint string, solvable |
An incorrect endpoint URL was used. Check for typos and make sure to use the endpoints from this documentation. |
payload_error string, solvable |
The payload contained missing parameters or had an incorrect format. See the error message for details. |
timeout string, solvable |
It took too long for the creative to load. Increase the default timeout manually if you wish to run the scan for a longer time. |
processing_error string, not solvable |
The worker nodes weren't able to process your request. Please drop us a note to see if we could troubleshoot. |
Change Log
Changes to the API are generally backwards compatible. If non-backwards compatible changes are introduced, the API version number in your endpoint URL will go up. Once you've reviewed the changelog and made the necessary changes at your side, you're invited to use the new API version by updating your endpoint URL accordingly.
HTML5 Zip Validator
Run a new scan
curl "https://{your_name}.api.creativeqa.net/v3.0/scan/zip"
-H "X-ApiKey: {api_key}"
-X POST
-d '{
"data": "WW91ciB6aXAgYmluYXJ5IGhlcmUuLi4="
}'
Example response
{ "3pas": "", "blocked_by_adblock": false, "click_tag_found": true, "console": { "errors": ["Error: ReferenceError: somefunction is not defined"], "warnings": [] }, "cookies": [{ "domain": ".creativeqa.io", "expires": 1646483649, "httpOnly": false, "name": "__gads", "path": "\/", "priority": "Medium", "secure": false, "session": false, "size": 92, "value": "ID=1a98edadd0995906-22cd64eb62ba0089:T=1612787649:S=ALNI_MYy4JVsyP7DbDydn73L6WR0-fHnKA" }, { "domain": ".doubleclick.net", "expires": 1646483650.085365, "httpOnly": true, "name": "IDE", "path": "\/", "priority": "Medium", "sameSite": "None", "secure": true, "session": false, "size": 70, "value": "AHWqTUlqh0OPFbGUeGXQqkXebE_Tf9xEs0i7fspXWBfoQHL0p3ooP5Iv-vx7JYmWKsA" }], "cpu_usage": 66, "creative_rendered": true, "dialogs": [], "dimensions": { "height": 90, "width": 728 }, "dom_content_loaded": 162, "file_structure": [{ "bytes": 3922, "name": "front_city.png", "type": "image" }, { "bytes": 11860, "name": "index.html", "type": "html" }, { "bytes": 6510, "name": "google_logo.png", "type": "image" }], "has_border": false, "has_external_assets": false, "has_video": false, "iframes": 1, "local_storage": [], "memory_usage": 2400256, "meta": { "api_version": "v3.0", "cpu": "AMD 16-Core EPYC 7302P", "creative_type": "zip", "device": "Desktop", "language": "en-US", "ram": "128GB", "scan_duration": "1.871964", "server_location": "ams", "timestamp": 1612789956, "ua": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/87.0.4280.88 Safari\/537.36" }, "meta_ad_size": false, "mobile_friendly": false, "network": { "load_size": { "host_initiated_subload": 0, "initial_load": 35690, "total": 35690 }, "responses": [{ "bytes": 11860, "headers": { "content-encoding": "br", "content-type": "text\/html", "date": "Mon, 08 Feb 2021 13:12:34 GMT", "last-modified": "Sat, 18 Apr 2020 18:08:16 GMT" }, "is_pixel": false, "method": "GET", "resource_type": "document", "server_ip": "127.0.0.1", "ssl": true, "ssl_info": { "protocol": "TLS 1.3", "validFrom": 1607455037, "validTo": 1922815037 }, "status": 200, "status_text": "", "timing": 169, "url": "https:\/\/www.creativeqa.io\/tmp\/7febf-e5693-1b71c-78616.zip\/index.html" }, { "bytes": 6510, "headers": { "accept-ranges": "bytes", "content-length": "6510", "content-type": "image\/png", "date": "Mon, 08 Feb 2021 13:12:34 GMT", "last-modified": "Sat, 18 Apr 2020 18:08:16 GMT" }, "is_pixel": false, "method": "GET", "resource_type": "image", "server_ip": "127.0.0.1", "ssl": true, "ssl_info": { "protocol": "TLS 1.3", "validFrom": 1607455037, "validTo": 1922815037 }, "status": 200, "status_text": "", "timing": 201, "url": "https:\/\/www.creativeqa.io\/tmp\/7febf-e5693-1b71c-78616.zip\/google_logo.png" },{ "..." }] }, "job_id": "7febf-e5693-1b71c-78616", "score": 93, "screenshot": { "highres": { "bytes": 132, "color": "#d8ecfe", "mime_type": "image\/png", "url": "https:\/\/try.cdn.creativeqa.net\/img\/qa-report-983243-29cbfuzn4mhk.png" }, "thumbnail": { "bytes": 538, "color": "#d8ecfe", "mime_type": "image\/jpg", "url": "https:\/\/try.cdn.creativeqa.net\/img\/qa-report-983243-xz5rs8mc3yuk.jpg" } }, "ssl": { "compliant": true, "insecure_urls": [] }, "tests": { "3pas": { "actual": "", "data_type": "string", "expected": "Any on list", "message": "No click tracking macro has been detected.", "name": "3PAS Vendor", "result": "ignored", "unit": "" }, "dimensions": { "actual": "728x90", "data_type": "string", "expected": "On acceptable list", "message": "This creative has dimensions 728 x 90, which is a standard size.", "name": "Ad Dimensions", "result": "passed", "unit": "" }, "adblock": { "actual": false, "data_type": "boolean", "expected": "false", "message": "This tag will likely not be blocked by ad blockers.", "name": "Blocked by AdBlock", "result": "passed", "unit": "" }, "cpu": { "actual": 66, "data_type": "int", "expected": "< 100 ms", "message": "CPU usage is acceptable at 66 ms.", "name": "CPU Usage", "result": "passed", "unit": "ms" }, "blocked_by_heavy_ad_intervention": { "actual": false, "data_type": "boolean", "expected": "< 15 seconds CPU and < 4 MB load size", "message": "This ad is not considered heavy, and probably will pass Chrome's Heavy Ad Intervention policy.", "name": "Chrome's Heavy Ad Intervention", "result": "passed", "unit": "" }, "click_tag_found": { "actual": true, "data_type": "boolean", "expected": "true", "message": "The clickTag for click tracking has been found in the main HTML document.", "name": "Click Tag", "result": "passed", "unit": "" }, "click_tracking_macro": { "actual": "", "data_type": "string", "expected": "Any on list", "message": "No click tracking macro has been detected.", "name": "Click Tracking Macro", "result": "ignored", "unit": "" }, "console_warnings": { "actual": 0, "data_type": "array", "expected": "0 warnings", "message": "No console warnings have been detected.", "name": "Console Warnings", "result": "passed", "unit": "" }, "cookies": { "actual": 0, "data_type": "array", "expected": "0 cookies", "message": "This ad doesn't seem to drop cookies.", "name": "Cookies Dropped", "result": "passed", "unit": "" }, "has_border": { "actual": false, "data_type": "boolean", "expected": "true", "message": "This creative doesn't have a high-contrasting border.", "name": "Creative Border", "result": "ignored", "unit": "" }, "creative_rendered": { "actual": true, "data_type": "boolean", "expected": "true", "message": "The creative was loaded successfully.", "name": "Creative Rendered", "result": "passed", "unit": "" }, "dialogs": { "actual": 0, "data_type": "boolean", "expected": "0 dialogs", "message": "No interruptive dialogs have been detected.", "name": "Dialogs & Modals", "result": "passed", "unit": "" }, "has_external_assets": { "actual": false, "data_type": "boolean", "expected": "false", "message": "This creative doesn't load assets from external domains.", "name": "External Assets", "result": "passed", "unit": "" }, "host_initiated_subload": { "actual": 0, "data_type": "int", "expected": "< 1048576 bytes", "message": "The host-initiated subload is acceptable at 0.00 KB.", "name": "Host-initiated Subload", "result": "passed", "unit": "bytes" }, "iframe_count": { "actual": 1, "data_type": "int", "expected": "<= 3 iframes", "message": "This creative uses 1 iframes.", "name": "Iframe Count", "result": "passed", "unit": "" }, "initial_load": { "actual": 35690, "data_type": "int", "expected": "< 1048576 bytes", "message": "The initial load size is acceptable at 34.9 KB.", "name": "Initial Load", "result": "passed", "unit": "bytes" }, "js_errors": { "actual": 0, "data_type": "array", "expected": "0 errors", "message": "No JavaScript errors have been detected.", "name": "JavaScript Errors", "result": "passed", "unit": "" }, "load_size": { "actual": 35690, "data_type": "int", "expected": "< 1048576 bytes", "message": "The load size is acceptable at 34.9 KB.", "name": "Load Size (Total)", "result": "passed", "unit": "bytes" }, "dom_content_loaded": { "actual": 162, "data_type": "int", "expected": "< 1000 ms", "message": "The DOMContentLoaded event fired after 162 ms.", "name": "Load Speed", "result": "passed", "unit": "ms" }, "local_storage": { "actual": 0, "data_type": "int", "expected": "0 localStorage objects", "message": "This ad doesn't seem to use HTML5 localStorage.", "name": "Local Storage", "result": "passed", "unit": "" }, "memory": { "actual": 2400256, "data_type": "int", "expected": "< 5242880 bytes", "message": "Memory usage is acceptable at 2 MB.", "name": "Memory Usage", "result": "passed", "unit": "bytes" }, "meta_ad_size": { "actual": false, "data_type": "boolean", "expected": "true", "message": "The meta tag 'ad.size' is not found in the HEAD. See the IAB guidelines.", "name": "Meta tag 'ad.size'", "result": "failed", "unit": "" }, "missing_assets": { "actual": 0, "data_type": "boolean", "expected": "No 40x HTTP status codes", "message": "All HTTP requests were valid.", "name": "Missing Assets", "result": "passed", "unit": "" }, "mobile_friendly": { "actual": false, "data_type": "boolean", "expected": "true", "message": "This 728 x 90 creative is not responsive on mobile devices.", "name": "Mobile Friendly", "result": "failed", "unit": "" }, "network_requests": { "actual": 8, "data_type": "int", "expected": "<= 15 requests", "message": "A total of 8 HTTP requests were made (including pixels).", "name": "Network Requests", "result": "passed", "unit": "" }, "pixels_fired": { "actual": 0, "data_type": "int", "expected": "< 5 pixels", "message": "This creative fires 0 pixels.", "name": "Pixels Fired", "result": "passed", "unit": "" }, "has_video": { "actual": false, "data_type": "boolean", "expected": "true or false", "message": "This ad doesn't seem to play videos.", "name": "Plays Video", "result": "passed", "unit": "" }, "ssl_compliant": { "actual": true, "data_type": "boolean", "expected": "true", "message": "All requests are loaded over https, including pixels and images.", "name": "SSL-Compliant", "result": "passed", "unit": "" }, "document_write": { "actual": false, "data_type": "boolean", "expected": "false", "message": "This creative doesn't use document.write().", "name": "Uses document.write()", "result": "passed", "unit": "" }, "visual_artifacts": { "actual": false, "data_type": "boolean", "expected": "false", "message": "No dimension discrepancies have been detected.", "name": "Visual Artifacts", "result": "passed", "unit": "" } }, "uses_document_write": false, "visual_artifacts": false, "json": { "url": "https:\/\/try.cdn.creativeqa.net\/img\/qa-report-983243-4n9vhsar26uk.json" } }
Use this scan to validate HTML5 ads in Zip format. Add the binary Zip file as a base64-encoded string to your API request.
Endpoint
POST https://{your_name}.api.creativeqa.net/v3.0/scan/zip
Arguments
data string, required |
The binary Zip file in base64-encoded format. The maximum size for this string is 10MB. |
server_location string |
The location of the server used to scan the creative:
|
timeout int |
Timeout in seconds after which the scan will be canceled. Range: 10 - 120. Defaults to 60 seconds. |
Returns
3pas string |
The name of the third-party ad server, if detected successfully. Remains blank otherwise. |
blocked_by_adblock boolean |
Whether or not the tag will likely be blocked by ad blockers. |
click_tag_found boolean |
Whether or not a click tag was found in the index.html file. |
console array |
All errors and warnings generated while loading the creative. |
cookies array |
All cookies that were dropped by the creative, either set via JavaScript or via an HTTP header. |
cpu_usage int |
The CPU usage, in milliseconds. |
creative_rendered boolean |
Equals true in case something was painted on the screen, false otherwise.
|
dialogs array |
Any dialog message the creative shows as a pop-up. Generally created by alert() and confirm(). |
dimensions array |
The detected width and height of the creative. |
dom_content_loaded int |
The time it took for the DOMContentLoaded event to fire, in milliseconds. |
file_structure array |
Contains the file structure of the Zip, including the name, type and file size. |
has_border boolean |
Whether or not the creative has a contrasting border. |
has_external_assets boolean |
Whether or not the creative loads assets from outside the Zip. Keep this at a minimum to reduce additional DNS lookups, connections, etc. |
has_video boolean |
Whether or not the creative plays video content. |
iframes int |
The number of iframes added to the DOM. This should be kept at a minimum to reduce memory usage. |
local_storage array |
All key/value pairs stored in window.localStorage. |
memory_usage int |
The amount of RAM memory used, in bytes. |
meta array |
Meta-data about the scan, like the CPU used, the time it took to complete the scan, the server location, etc. |
meta_ad_size boolean |
Whether or not the creative has a <meta name="ad.size" content="width=X,height=X"> tag, as per IAB standards.
|
mobile_friendly boolean |
Whether or not the creative will display fine on a mobile device. Equals true if the creative is responsive or < 300 pixels wide.
|
network array |
All network requests and their responses, including a full echo of the HTTP headers. Provides SSL certificate information too. |
job_id string |
A unique ID assigned to the scan. Store this ID on your own backend to re-fetch result data at a later moment. |
score int |
The score, calculated based on the number of failed/passed tests. |
screenshot array |
A screenshot of the creative. The url points to a PNG image.
The background_color is in hex-format. It generally goes well with the main colors of the screenshot.
|
ssl boolean |
Whether or not the creative is SSL-compliant. If the creative tries to load assets over http, it will equal false .
|
tests array |
The most important part of the JSON response: an array of all tests conducted and their results. You can use this array to create your own report. |
uses_document_write boolean |
Whether or not the creative uses the JS document.write() function. Synchronous code should be avoided. |
visual_artifacts boolean |
If visual artificats have been detected. For example, a 300x250 creative that is actualy 301x251 in size. |
json array |
The url contains a link to the JSON result of the scan. Great for manual downloads and inspection.
|
Retrieve a scan
curl "https://{your_name}.api.creativeqa.net/v3.0/jobs/{job_id}"
-H "X-ApiKey: {api_key}"
-X GET
Example response
{ "3pas": "", "blocked_by_adblock": false, "click_tag_found": true, "..." }
To retrieve a cached JSON response of a creative you've previously scanned, use the following endpoint.
Make sure to use GET as a method. The job_id
can be found in the response from a new scan.
Endpoint
GET https://{your_name}.api.creativeqa.net/v3.0/jobs/{job_id}
Returns
response object |
The full JSON response from the original scan. |
Ad Tag Validator
Run a new scan
curl "https://{your_name}.api.creativeqa.net/v3.0/scan/tag"
-H "X-ApiKey: {api_key}"
-X POST
-d '{
"data": "WW91ciBhZCB0YWcgaGVyZS4uLg=="
}'
Example response
{ "3pas": "Google Ad Manager (GAM)", "blocked_by_adblock": true, "console": { "errors": ["Error: ReferenceError: somefunction is not defined"], "warnings": [] }, "cookies": [{ "domain": ".creativeqa.io", "expires": 1646483649, "httpOnly": false, "name": "__gads", "path": "\/", "priority": "Medium", "secure": false, "session": false, "size": 92, "value": "ID=1a98edadd0995906-22cd64eb62ba0089:T=1612787649:S=ALNI_MYy4JVsyP7DbDydn73L6WR0-fHnKA" }, { "domain": ".doubleclick.net", "expires": 1646483650.085365, "httpOnly": true, "name": "IDE", "path": "\/", "priority": "Medium", "sameSite": "None", "secure": true, "session": false, "size": 70, "value": "AHWqTUlqh0OPFbGUeGXQqkXebE_Tf9xEs0i7fspXWBfoQHL0p3ooP5Iv-vx7JYmWKsA" }], "cpu_usage": 634, "creative_rendered": true, "dialogs": [], "dimensions": { "height": 250, "width": 300 }, "dom_content_loaded": 166, "has_border": true, "has_video": false, "iframes": 2, "local_storage": [], "memory_usage": "11313152", "meta": { "api_version": "v3.0", "cpu": "AMD 16-Core EPYC 7302P", "creative_type": "ad_tag", "device": "Desktop", "language": "en-US", "ram": "128GB", "scan_duration": "2.809499", "server_location": "ams", "timestamp": 1612787651, "ua": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/87.0.4280.88 Safari\/537.36" }, "mobile_friendly": true, "network": { "load_size": { "host_initiated_subload": 0, "initial_load": 263515, "total": 263515 }, "responses": [{ "bytes": 19175, "headers": { "cache-control": "private, max-age=900, stale-while-revalidate=3600", "content-encoding": "gzip", "content-length": "19175", "content-type": "text\/javascript", "date": "Mon, 08 Feb 2021 12:34:09 GMT", "etag": "\"777 \/ 11 of 1000 \/ last-modified: 1612786878\"", "expires": "Mon, 08 Feb 2021 12:34:09 GMT", "server": "sffe", "timing-allow-origin": "*", "vary": "Accept-Encoding", }, "is_pixel": false, "method": "GET", "resource_type": "script", "server_ip": "142.250.179.194", "ssl": true, "ssl_info": { "protocol": "TLS 1.3", "validFrom": 1611043025, "validTo": 1618300624 }, "status": 200, "status_text": "", "timing": 172, "url": "https:\/\/securepubads.g.doubleclick.net\/tag\/js\/gpt.js" }, { "bytes": 103509, "headers": { "accept-ranges": "bytes", "cache-control": "private, immutable, max-age=31536000", "content-encoding": "gzip", "content-length": "103509", "content-type": "text\/javascript", "cross-origin-resource-policy": "cross-origin", "date": "Mon, 08 Feb 2021 12:34:09 GMT", "expires": "Mon, 08 Feb 2021 12:34:09 GMT", "last-modified": "Tue, 02 Feb 2021 09:38:25 GMT", "server": "sffe", "timing-allow-origin": "*", "vary": "Accept-Encoding", }, "is_pixel": false, "method": "GET", "resource_type": "script", "server_ip": "142.250.179.194", "ssl": true, "ssl_info": { "protocol": "TLS 1.3", "validFrom": 1611043025, "validTo": 1618300624 }, "status": 200, "status_text": "", "timing": 224, "url": "https:\/\/securepubads.g.doubleclick.net\/gpt\/pubads_impl_2021020201.js" },{ "..." }] }, "job_id": "2af21-de8d9-7cb57-8f014", "score": 77, "screenshot": { "highres": { "bytes": 37715, "color": "#77b2c1", "mime_type": "image\/png", "url": "https:\/\/try.cdn.creativeqa.net\/img\/qa-report-983243-aue7bczw9t3v.png" }, "thumbnail": { "bytes": 3460, "color": "#77b2c1", "mime_type": "image\/jpg", "url": "https:\/\/try.cdn.creativeqa.net\/img\/qa-report-983243-6gn25mbhxwu9.jpg" } }, "ssl": { "compliant": true, "insecure_urls": [] }, "tests": { "3pas": { "actual": "Google Ad Manager (GAM)", "data_type": "string", "expected": "Any on list", "message": "This is a third-party tag from Google Ad Manager (GAM).", "name": "3PAS Vendor", "result": "ignored", "unit": "" }, "dimensions": { "actual": "300x250", "data_type": "string", "expected": "On acceptable list", "message": "This creative has dimensions 300 x 250, which is a standard size.", "name": "Ad Dimensions", "result": "passed", "unit": "" }, "adblock": { "actual": true, "data_type": "boolean", "expected": "false", "message": "This tag will likely be blocked by ad blockers. Expect discrepancies when comparing third-party metrics with yours.", "name": "Blocked by AdBlock", "result": "failed", "unit": "" }, "cpu": { "actual": 634, "data_type": "int", "expected": "< 100 ms", "message": "This creative uses the CPU for 634 ms. That's quite a lot.", "name": "CPU Usage", "result": "failed", "unit": "ms" }, "blocked_by_heavy_ad_intervention": { "actual": false, "data_type": "boolean", "expected": "< 15 seconds CPU and < 4 MB load size", "message": "This ad is not considered heavy, and probably will pass Chrome's Heavy Ad Intervention policy.", "name": "Chrome's Heavy Ad Intervention", "result": "passed", "unit": "" }, "click_tracking_macro": { "actual": "", "data_type": "string", "expected": "Any on list", "message": "No click tracking macro has been detected.", "name": "Click Tracking Macro", "result": "ignored", "unit": "" }, "console_warnings": { "actual": 0, "data_type": "array", "expected": "0 warnings", "message": "No console warnings have been detected.", "name": "Console Warnings", "result": "passed", "unit": "" }, "cookies": { "actual": 2, "data_type": "array", "expected": "0 cookies", "message": "A total of 2 cookies were dropped while loading this ad. Due to global privacy laws, make sure you have user-consent.", "name": "Cookies Dropped", "result": "failed", "unit": "" }, "has_border": { "actual": true, "data_type": "boolean", "expected": "true", "message": "This creative has a high-contrasting border.", "name": "Creative Border", "result": "ignored", "unit": "" }, "creative_rendered": { "actual": true, "data_type": "boolean", "expected": "true", "message": "The creative was loaded successfully.", "name": "Creative Rendered", "result": "passed", "unit": "" }, "dialogs": { "actual": 0, "data_type": "boolean", "expected": "0 dialogs", "message": "No interruptive dialogs have been detected.", "name": "Dialogs & Modals", "result": "passed", "unit": "" }, "host_initiated_subload": { "actual": 0, "data_type": "int", "expected": "< 1048576 bytes", "message": "The host-initiated subload is acceptable at 0.00 KB.", "name": "Host-initiated Subload", "result": "passed", "unit": "bytes" }, "iframe_count": { "actual": 2, "data_type": "int", "expected": "<= 3 iframes", "message": "This creative uses 2 iframes.", "name": "Iframe Count", "result": "passed", "unit": "" }, "initial_load": { "actual": 263515, "data_type": "int", "expected": "< 1048576 bytes", "message": "The initial load size is acceptable at 257.3 KB.", "name": "Initial Load", "result": "passed", "unit": "bytes" }, "js_errors": { "actual": 0, "data_type": "array", "expected": "0 errors", "message": "No JavaScript errors have been detected.", "name": "JavaScript Errors", "result": "passed", "unit": "" }, "load_size": { "actual": 263515, "data_type": "int", "expected": "< 1048576 bytes", "message": "The load size is acceptable at 257.3 KB.", "name": "Load Size (Total)", "result": "passed", "unit": "bytes" }, "dom_content_loaded": { "actual": 166, "data_type": "int", "expected": "< 1000 ms", "message": "The DOMContentLoaded event fired after 166 ms.", "name": "Load Speed", "result": "passed", "unit": "ms" }, "local_storage": { "actual": 0, "data_type": "int", "expected": "0 localStorage objects", "message": "This ad doesn't seem to use HTML5 localStorage.", "name": "Local Storage", "result": "passed", "unit": "" }, "memory": { "actual": "11313152.0", "data_type": "int", "expected": "< 5242880 bytes", "message": "This creative uses 11 MB of memory. That's quite a lot.", "name": "Memory Usage", "result": "failed", "unit": "bytes" }, "missing_assets": { "actual": 0, "data_type": "boolean", "expected": "No 40x HTTP status codes", "message": "All HTTP requests were valid.", "name": "Missing Assets", "result": "passed", "unit": "" }, "mobile_friendly": { "actual": true, "data_type": "boolean", "expected": "true", "message": "The creative seems to be responsive on mobile devices.", "name": "Mobile Friendly", "result": "passed", "unit": "" }, "network_requests": { "actual": 20, "data_type": "int", "expected": "<= 15 requests", "message": "A total of 20 HTTP requests were made. This has a significant impact on the performance of the creative and the page itself. The IAB suggests a limit of 15 HTTP requests per creative.", "name": "Network Requests", "result": "failed", "unit": "" }, "pixels_fired": { "actual": 6, "data_type": "int", "expected": "< 5 pixels", "message": "This creative fires 6 pixels. Keep the amount of pixels at a minimum to improve network performance.", "name": "Pixels Fired", "result": "failed", "unit": "" }, "has_video": { "actual": false, "data_type": "boolean", "expected": "true or false", "message": "This ad doesn't seem to play videos.", "name": "Plays Video", "result": "passed", "unit": "" }, "ssl_compliant": { "actual": true, "data_type": "boolean", "expected": "true", "message": "All requests are loaded over https, including pixels and images.", "name": "SSL-Compliant", "result": "passed", "unit": "" }, "document_write": { "actual": false, "data_type": "boolean", "expected": "false", "message": "This creative doesn't use document.write().", "name": "Uses document.write()", "result": "passed", "unit": "" }, "visual_artifacts": { "actual": false, "data_type": "boolean", "expected": "false", "message": "No dimension discrepancies have been detected.", "name": "Visual Artifacts", "result": "passed", "unit": "" } }, "uses_document_write": false, "visual_artifacts": false, "json": { "url": "https:\/\/try.cdn.creativeqa.net\/img\/qa-report-983243-txkf9dmzawu7.json" } }
Use this scan to validate ad tags in HTML and/or JavaScript. Add the ad tag as a base64-encoded string to your API request.
Endpoint
POST https://{your_name}.api.creativeqa.net/v3.0/scan/tag
Arguments
data string, required |
The ad tag in base64-encoded format. |
server_location string |
The location of the server used to scan the creative:
|
timeout int |
Timeout in seconds after which the scan will be canceled. Range: 10 - 120. Defaults to 60 seconds. |
Returns
3pas string |
The name of the third-party ad server, if detected successfully. Remains blank otherwise. |
blocked_by_adblock boolean |
Whether or not the tag will likely be blocked by ad blockers. |
console array |
All errors and warnings generated while loading the creative. |
cookies array |
All cookies that were dropped by the creative, either set via JavaScript or via an HTTP header. |
cpu_usage int |
The CPU usage, in milliseconds. |
creative_rendered boolean |
Equals true in case something was painted on the screen, false otherwise.
|
dialogs array |
Any dialog message the creative shows as a pop-up. Generally created by alert() and confirm(). |
dimensions array |
The detected width and height of the creative. |
dom_content_loaded int |
The time it took for the DOMContentLoaded event to fire, in milliseconds. |
has_border boolean |
Whether or not the creative has a contrasting border. |
has_video boolean |
Whether or not the creative plays video content. |
iframes int |
The number of iframes added to the DOM. This should be kept at a minimum to reduce memory usage. |
local_storage array |
All key/value pairs stored in window.localStorage. |
memory_usage int |
The amount of RAM memory used, in bytes. |
meta array |
Meta-data about the scan, like the CPU used, the time it took to complete the scan, the server location, etc. |
mobile_friendly boolean |
Whether or not the creative will display fine on a mobile device. Equals true if the creative is responsive or < 300 pixels wide.
|
network array |
All network requests and their responses, including a full echo of the HTTP headers. Provides SSL certificate information too. |
job_id string |
A unique ID assigned to the scan. Store this ID on your own backend to re-fetch result data at a later moment. |
score int |
The score, calculated based on the number of failed/passed tests. |
screenshot array |
A screenshot of the creative. The url points to a PNG image.
The background_color is in hex-format. It generally goes well with the main colors of the screenshot.
|
ssl boolean |
Whether or not the creative is SSL-compliant. If the creative tries to load assets over http, it will equal false .
|
tests array |
The most important part of the JSON response: an array of all tests conducted and their results. You can use this array to create your own report. |
uses_document_write boolean |
Whether or not the creative uses the JS document.write() function. Synchronous code should be avoided. |
visual_artifacts boolean |
If visual artificats have been detected. For example, a 300x250 creative that is actualy 301x251 in size. |
json array |
The url contains a link to the JSON result of the scan. Great for manual downloads and inspection.
|
Retrieve a scan
curl "https://{your_name}.api.creativeqa.net/v3.0/jobs/{job_id}"
-H "X-ApiKey: {api_key}"
-X GET
Example response
{ "3pas": "", "blocked_by_adblock": false, "..." }
To retrieve a cached JSON response of a creative you've previously scanned, use the following endpoint.
Make sure to use GET as a method. The job_id
can be found in the response from a new scan.
Endpoint
GET https://{your_name}.api.creativeqa.net/v3.0/jobs/{job_id}
Returns
response object |
The full JSON response from the original scan. |