× Cookies are disabled! This site requires cookies to be enabled to work properly

Important! The VirusTotal Public API v1.0 is deprecated and may be fully removed in the future. Therefore, we encourage you to move to the newest version of the public API. You may also want to consider the private API alternative with higher request rates, strict SLA, detailed information regarding scans and legacy support.

VirusTotal's Public API lets you upload and scan files, submit and scan URLs, access finished scan reports and make automatic comments on URLs or samples without the need of using the HTML website interface. In other words, it allows you to build simple scripts to access the information generated by VirusTotal.

The chosen format for the API is HTTP POST requests with JSON object responses and it is limited to at most 20 requests of any nature in any given 5 minutes time frame. If you run a honeyclient, honeypot or any other automation that is going to provide resources to VirusTotal and not only retrieve reports you are entitled to a higher request rate quota, ask for it at . Note that you will only have a higher request rate quota when asking for files or URLs that you previously sent to VirusTotal.

The public API is a free service, available for any web site or application that is free to consumers. The API must not be used in commercial products or services, it can not be used as a substitute for antivirus products and it can not be integrated in any project that may harm the antivirus industry directly or indirectly. Noncompliance of these terms will result in inmediate permanent ban of the infractor individual or organization. Please see VirusTotal's terms of service for more information.

Contents

Audience
Getting started
Response basics
Sending and scanning files
Retrieving file scan reports
Sending and scanning URLs
Retrieving URL scan reports
Making comments on files and URLs
Scripts for using the API

Audience

This document is intended for programmers who want to write client applications that can interact with VirusTotal using JSON and HTTP.

This document assumes that you understand general networking and programming ideas. Even though code examples are built using python, any programming language of your choice can be used to interact with this API as you can notice in the scripts for using the API section.

Getting started

The process could not be easier. Sign up to VirusTotal Community. Once you have a valid VirusTotal Community account, you will find your personal API key in your Community profile. This key is all you need to use VirusTotal's API.

You will also need a programming language capable of performing HTTP requests and a library or implementation for parsing JSON data.

Response basics

The API response format is a JSON object containing at least a result property. If the item you searched for was not present this result will be 0, if you exceeded the public API request rate it will be -2, if the API key provided is incorrect it will be -1, any other case is detailed in the following sections.

Sending and scanning files

The VirusTotal API also allows you to send files. Before performing your submissions we encourage you to retrieve the latest report on the files, if it is recent enough you might want to save time and bandwidth by making use of it.

In order to send a file you must perform an HTTP POST request to the following URL (https is also allowed):

http://www.virustotal.com/api/scan_file.json

This API call expects multipart/form-data parameters, the string part of the the call should have the following parameter:

  • key: your API key.

The file part of the call should contain the name of the submitted file and the file itself. We strongly encourage you to send the file with the name with which it was found in the wild since this is very rich metadata for the VirusTotal database. Summing up, The API acts like a form with a file input field named file.

Some python code will hopefully illustrate better how this is done. Since urllib2 cannot (at least up to python 2.5) send files using POST and multipart/form-data encoding we will use this snippet to help us, let us call it postfile.py.

>>> import postfile
>>> host = "www.virustotal.com"
>>> selector = "http://www.virustotal.com/api/scan_file.json"
>>> fields = [("key", "-- YOUR API KEY --")]
>>> file_to_send = open("test.txt", "rb").read()
>>> files = [("file", "test.txt", file_to_send)]
>>> json = postfile.post_multipart(host, selector, fields, files)
>>> print json
{"scan_id": "cd1384c10baa2d5b96f397b986e2a1fc9535d2ef0e185a113fc610eca1c6fb0e-1271623480",
 "result": 1}

The scan_id field of the JSON object lets us query the report later making use of the file report retrieving API. Keep in mind that files sent using the API have the lowest scanning priority, depending on VirusTotal's load, it may take several hours before the file is scanned, so query the report at regular intervals until the result shows up and do not keep sending the file once and over again.

Having said this, you might prefer to use Bryce Boe's (@bboe) python snippet for uploading samples to VirusTotal, the script can be found in his blog.

Retrieving file scan reports

In order to retrieve a scan report on a given file you must perform an HTTP POST request to the following URL (https is also allowed):

http://www.virustotal.com/api/get_file_report.json

With the following two HTTP POST parameters:

  • resource: a md5/sha1/sha256 hash will retrieve the most recent report on a given sample. You may also specify a scan_id (sha256-timestamp as returned by the file upload API) to access a specific report.
  • key: your API key.

Some python code will hopefully illustrate better how this is done:

>>> import simplejson
>>> import urllib
>>> import urllib2
>>> url = "http://www.virustotal.com/api/get_file_report.json"
>>> parameters = {"resource": "99017f6eebbac24f351415dd410d522d",
...               "key": "-- YOUR API KEY --"}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
>>> response = urllib2.urlopen(req)
>>> json = response.read()
>>> print json
{"report": ["2010-04-13 23:28:27", {"nProtect": "",
                                    "CAT-QuickHeal": "",
                                    "McAfee": "Generic.dx!rkx",
                                    "TheHacker": "Trojan/VB.gen",
                                    "VirusBuster": "",
                                    "NOD32": "a variant of Win32/Qhost.NTY",
                                    "F-Prot": "", "Symantec": "",
                                    "Norman": "",
                                    "a-squared": "Trojan.Win32.VB!IK", ...}],
 "permalink": "http://www.virustotal.com/file-scan/report.html?id=a8...",
 "result": 1}
>>> response_dict = simplejson.loads(json)
>>> response_dict.get("report")
['2010-04-13 23:28:27', {'nProtect': '', 'CAT-QuickHeal': '',
'McAfee': 'Generic.dx!rkx', 'TheHacker': 'Trojan/VB.gen',
'VirusBuster': '', 'NOD32': 'a variant of Win32/Qhost.NTY',
'F-Prot': '', 'Symantec': '', 'Norman': '', 'Avast': 'Win32:Malware-gen',
'eSafe': 'Win32.TRVB.Acgy', 'ClamAV': '', 'Kaspersky': 'Trojan.Win32.VB.acgy',
'BitDefender': 'Trojan.Generic.3611249', 'Comodo': 'Heur.Suspicious',
'F-Secure': 'Trojan.Generic.3611249', 'DrWeb': 'Trojan.Hosts.37',
'AntiVir': 'TR/VB.acgy.1', 'TrendMicro': '', 'McAfee-GW-Edition': 'Trojan.VB.acgy.1',
'Sophos': '', 'eTrust-Vet': '', 'Authentium': '', 'Jiangmin': '',
'Antiy-AVL': 'Trojan/Win32.VB', 'a-squared': 'Trojan.Win32.VB!IK',
'Microsoft': '', 'ViRobot': '', 'Prevx': 'Medium Risk Malware',
'GData': 'Trojan.Generic.3611249', 'AhnLab-V3': '', 'VBA32': '',
'Sunbelt': 'Trojan.Win32.Generic!BT', 'PCTools': '', 'Rising': '',
'Ikarus': 'Trojan.Win32.VB', 'Fortinet': '', 'AVG': 'Generic17.ASTJ',
'Panda': 'Adware/AccesMembre', 'Avast5': 'Win32:Malware-gen'}]

As you can see, the report field of the response is a list with the date of the file scan as its first member and a dictionary of antivirus:result key:value pairs. Whenever a file is not detected by a given antivirus the result is an empty string.

Sending and scanning URLs

URLs can also be submitted for scanning. Once again, before performing your submission we encourage you to retrieve the latest report on the URL, if it is recent enough you might want to save time and bandwidth by making use of it.

To submit a URL you must perform an HTTP POST request to the following URL:

http://www.virustotal.com/api/scan_url.json

This API call expects the following HTTP POST parameters:

  • url: The URL that should be scanned.
  • key: your API key.

Some python code will hopefully illustrate better how this is done:

>>> import simplejson
>>> import urllib
>>> import urllib2
>>> url = "http://www.virustotal.com/api/scan_url.json"
>>> parameters = {"url": "http://www.virustotal.com",
...               "key": "-- YOUR API KEY --"}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
>>> response = urllib2.urlopen(req)
>>> json = response.read()
>>> print json
{"scan_id": "7f911bbcf618f052ac6b9928600d2820-1271621154", "result": 1}

The scan_id parameter of the JSON object can then be used to query for the scan report making use of the URL scan report retrieval API described in the next section. Keep in mind that URLs sent using the API have the lowest scanning priority, depending on VirusTotal's load, it may take several hours before the URL is scanned, so query the report at regular intervals until the result shows up and do not keep submitting the URL once and over again.

Retrieving URL scan reports

In order to retrieve a scan report on a given URL you must perform an HTTP POST request to the following URL:

http://www.virustotal.com/api/get_url_report.json

With the following HTTP POST parameters:

  • resource: a URL will retrieve the most recent report on the given URL. You may also specify a scan_id (md5-timestamp as returned by the URL submission API) to access a specific report.
  • scan (optional): this is an optional parameter that when set to "1" will automatically submit the URL for analysis if no report is found for it in VirusTotal's database. In this case the result will contain a scan_id field that can be used to query the analysis report later on.
  • key: your API key.

Some python code will hopefully illustrate better how this is done:

>>> import simplejson
>>> import urllib
>>> import urllib2
>>> url = "http://www.virustotal.com/api/get_url_report.json"
>>> parameters = {"resource": "http://www.google.com",
...               "key": "-- YOUR API KEY --"}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
>>> response = urllib2.urlopen(req)
>>> json = response.read()
>>> print json
{"report": ["2010-04-17 19:13:22", {"Firefox": "Clean site",
                                    "Opera": "Clean site",
                                    "Google Safebrowsing": "Clean site",
                                    "Phishtank": "Clean site",
                                    "TRUSTe": "Clean site",
                                    "Smartscreen": "Clean site"}],
 "result": 1,
"file-report":"9920da8178df4c521f8cd8754c2fc67fd41fd0b098b2c8a41b290179a158b713-1271611297"}
>>> response_dict = simplejson.loads(json)
>>> response_dict.get("report")[1].get("Firefox")
'Clean site'
>>> parameters = {"resource": "http://www.google.com",
...               "key": "-- YOUR API KEY --",
                  "scan": 1}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
>>> response = urllib2.urlopen(req)
>>> json = response.read()
>>> print json
{"scan_id": "4fb49478f1857a41ec1708a397f71206-1288247724", "result": 0}

As you can see, the report field of the response is a list with the date of the URL scan as its first member and a dictionary of scantool:result key:value pairs. The URL is downloaded and sent to the antivirus scanning engine of VirusTotal, the report id of the file scan is presented in the file-report key of the JSON object.

Make comments on files and URLs

The initial idea of VirusTotal Community was that users should be able to make comments on files and URLs, the comments may be malware analyses, false positive flags, disinfection instructions, etc.

Imagine you have some automatic setup that can produce interesting results related to a given sample or URL that you submit to VirusTotal for antivirus characterization, you might want to give visibility to your setup by automatically reviewing samples and URLs with the output of your automation.

In order to do so you can make use of VirusTotal's API by performing an HTTP POST request to the following URL:

http://www.virustotal.com/api/make_comment.json

You must provide the following HTTP POST parameters to the call:

  • file or url: either a md5/sha1/sha256 hash of the file you want to review or the URL itself that you want to comment on.
  • comment: the actual review, you can tag it using the "#" twitter-like syntax (e.g. #disinfection #zbot) and reference users using the "@" syntax (e.g. @EmilianoMartinez).
  • tags (optional): this parameter is optional. It should be a semi-colon separated list of standard file or URL tags. The standard file tags are: goodware, malware, spamattachmentorlink, p2pdownload, impropagating, networkworm, drivebydownload. The standard URL tags are: malicious, benign, malwaredownload, phishingsite, browserexploit, spamlink.
  • key: your API key.

Some python code will hopefully illustrate better how this is done:

>>> import simplejson
>>> import urllib
>>> import urllib2
>>> url = "http://www.virustotal.com/api/make_comment.json"
>>> parameters = {"file": "99017f6eebbac24f351415dd410d522d",
...               "comment": "How to disinfect you from this file... #disinfect #zbot",
...               "tags": "malware;drivebydownload",
...               "key": "-- YOUR API KEY --"}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
>>> response = urllib2.urlopen(req)
>>> json = response.read()
>>> print json
{"result": 1}

If the comment was successfully posted the result will be 1.

Scripts for using the API

Several VT Community users have made scripts for using the API in different languages, VirusTotal is not responsible for these code snippets, having said this, many of you may find them useful. If you want to see your snippet in this list just ping VirusTotalTeam.