VirusTotal Developer Hub

Welcome to the VirusTotal developer hub. Here you'll find comprehensive guides and documentation to help you start working with VirusTotal's API as quickly as possible. Let's jump right in!

Search results for "{{ search.query }}"

No results found for "{{search.query}}". 
View All Results

Getting started

 

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

In order to use the API you must sign up to VirusTotal Community. Once you have a valid VirusTotal Community account you will find your personal API key in your personal settings section. This key is all you need to use the VirusTotal API.

Important

The VirusTotal 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 immediate permanent ban of the infractor individual or organization.

Under all circumstances VirusTotal's Terms of Service and Best Practices must be respected.

By default any VirusTotal Community registered user is entitled to an API key that allows them to interact with a basic set of endpoints. Advanced research calls are available via the private API, which requires special privileges. Contact us if you would like to learn more about how to obtain access.

Note that all endpoints referenced in this guide share a common URL prefix: www.virustotal.com/vtapi/v2/.

Public vs Private API

 

While many of the endpoints and features provided by the VirusTotal API are freely accessible to all registered users, some of them are restricted to our premium customers only. Those endpoints and features constitute the VirusTotal Private API and they will be appropriately identified in this section. If you are interested in using our Private API please contact us.

The Public API, on the other hand, is a set of endpoints available for everyone to use at no cost. The only thing you need in order to use the Public API is to sign up in VirusTotal Community and obtain your API key as described in Getting started.

Notice

The Public API is limited to 4 requests per minute.
The Private API returns more threat data and exposes more endpoints.
The Private API is governed by an SLA that guarantees readiness of data.

The Private API has the following advantages over the Public API:

  • Allows you to choose a request rate and daily quota allowance that best suits your needs.
  • Will return further details about the resources scanned by VirusTotal, for instance: VBA code stream warnings for documents, source metadata, ExifTool output, IDS output for recorded network traces, etc.
  • Includes metadata generated exclusively by VirusTotal: first submission date of a given file, list of file names with which a file was submitted to VirusTotal, submission countries, prevalence, etc.
  • Will give you access to behavior information about files, produced by executing Windows PEs, DMGs, Mach-Os and APKs in a virtualized sandbox environment.
  • Exposes whitelisting and trusted source information.
  • Allows you to perform property to sample queries: reverse searches such as give me all samples that are detected with the following signature, give me all samples that are detected by more than 10 engines, give me all samples that contain a given PE section with the following hash, etc. these search modifiers can be combined to build complex requests.
  • Exposes file clustering and file similarity search calls.
  • Enables you to download submitted samples for further research, along with the network traffic captures they generate upon execution and their detailed execution reports.
  • Has a strict Service License Agreement (SLA) that guarantees availability and readiness of data.

API responses

 

When interacting with the API, if the request was correctly handled by the server and no errors were produced, a 200 HTTP status code will be returned. The body of the response will usually be a JSON object (except for file downloads) that will contain at least the following two properties:

  • response_code: if the item you searched for was not present in VirusTotal's dataset this result will be 0. If the requested item is still queued for analysis it will be -2. If the item was indeed present and it could be retrieved it will be 1. Any other case is detailed in the full reference.
  • verbose_msg: provides verbose information regarding the response_code property.

In case of error you can get any of the following status codes:

Code
Description

204

Request rate limit exceeded. You are making more requests than allowed.

400

Bad request. Your request was somehow incorrect. This can be caused by missing arguments or arguments with wrong values.

403

Forbidden. You don't have enough privileges to make the request. You may be doing a request without providing an API key or you may be making a request to a Private API without having the appropriate privileges.

/file/report

Retrieve file scan reports

 
gethttps://www.virustotal.com/vtapi/v2/file/report
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/file/report?apikey=<apikey>&resource=<resource>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/report'

params = {'apikey': '<apikey>', 'resource': '<resource>'}

response = requests.get(url, params=params)

print(response.json())
<?php
$post = array('apikey' => 'YOUR_API_KEY','resource'=>'99017f6eebbac24f351415dd410d522d');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.virustotal.com/vtapi/v2/file/report');
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_VERBOSE, 1); // remove this if your not debugging
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); // please compress data
curl_setopt($ch, CURLOPT_USERAGENT, "gzip, My php curl client");
curl_setopt($ch, CURLOPT_RETURNTRANSFER ,true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

$result=curl_exec ($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print("status = $status_code\n");
if ($status_code == 200) { // OK
  $js = json_decode($result, true);
  print_r($js);
} else {  // Error occured
  print($result);
}
curl_close ($ch);
?>
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

resource
string
required

Resource(s) to be retrieved

allinfo
boolean

Return additional information about the file

 

The resource argument can be the MD5, SHA-1 or SHA-256 of a file for which you want to retrieve the most recent antivirus report. You may also specify a scan_id returned by the /file/scan endpoint.

If the allinfo argument is set to true additional information other than the antivirus results is returned. This additional information includes the output of several tools acting on the file (PDFiD, ExifTool, sigcheck, TrID, etc.), the output of behavioral sandboxes, metadata regarding VirusTotal submissions (number of unique sources that have sent the file in the past, first seen date, last seen date, etc.) and the output of other in-house technologies.

Private API

The allinfo argument is available in the Private API only.

{
 'response_code': 1,
 'verbose_msg': 'Scan finished, scan information embedded in this object',
 'resource': '99017f6eebbac24f351415dd410d522d',
 'scan_id': '52d3df0ed60c46f336c131bf2ca454f73bafdc4b04dfa2aea80746f5ba9e6d1c-1273894724',
 'md5': '99017f6eebbac24f351415dd410d522d',
 'sha1': '4d1740485713a2ab3a4f5822a01f645fe8387f92',
 'sha256': '52d3df0ed60c46f336c131bf2ca454f73bafdc4b04dfa2aea80746f5ba9e6d1c',
 'scan_date': '2010-05-15 03:38:44',
 'permalink': 'https://www.virustotal.com/file/52d3df0ed60c46f336c131bf2ca454f73bafdc4b04dfa2aea80746f5ba9e6d1c/analysis/1273894724/',
 'positives': 40,
 'total': 40,
 'scans': {
   'nProtect': {
     'detected': true, 
     'version': '2010-05-14.01', 
     'result': 'Trojan.Generic.3611249', 
     'update': '20100514'
   },
   'CAT-QuickHeal': {
     'detected': true, 
     'version': '10.00', 
     'result': 'Trojan.VB.acgy', 
     'update': '20100514'
   },
   'McAfee': {
     'detected': true, 
     'version': '5.400.0.1158', 
     'result': 'Generic.dx!rkx', 
     'update': '20100515'
   },
   'TheHacker': {
     'detected': true, 
     'version': '6.5.2.0.280', 
     'result': 'Trojan/VB.gen', 
     'update': '20100514'
   },   
   'VirusBuster': {
    'detected': true,
     'version': '5.0.27.0',
     'result': 'Trojan.VB.JFDE',
     'update': '20100514'
   }
 }
}

/file/scan

Upload and scan a file

 
posthttps://www.virustotal.com/vtapi/v2/file/scan
curl --request POST \ 
  --url 'https://www.virustotal.com/vtapi/v2/file/scan' \
  --form 'apikey=<apikey>' \
  --form 'file=@/path/to/file'
  
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/scan'

params = {'apikey': '<apikey>'}

files = {'file': ('myfile.exe', open('myfile.exe', 'rb'))}

response = requests.post(url, files=files, params=params)

print(response.json())
<?php
$file_name_with_full_path = realpath('/bin/cp');
$api_key = getenv('VT_API_KEY') ? getenv('VT_API_KEY') :'YOUR_API_KEY';
$cfile = curl_file_create($file_name_with_full_path);

$post = array('apikey' => $api_key,'file'=> $cfile);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.virustotal.com/vtapi/v2/file/scan');
curl_setopt($ch, CURLOPT_POST, True);
curl_setopt($ch, CURLOPT_VERBOSE, 1); // remove this if your not debugging
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); // please compress data
curl_setopt($ch, CURLOPT_USERAGENT, "gzip, My php curl client");
curl_setopt($ch, CURLOPT_RETURNTRANSFER ,True);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

$result=curl_exec ($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print("status = $status_code\n");
if ($status_code == 200) { // OK
  $js = json_decode($result, true);
  print_r($js);
} else {  // Error occured
  print($result);
}
curl_close ($ch);
?>
A binary file was returned

You couldn't be authenticated

Try the API to see results

Form Data

apikey
string
required

Your API key

file
file
required

File to be scanned

 

This endpoint allows you to send a file for scanning with VirusTotal. Before performing your submissions we encourage you to retrieve the latest report on the file, if it is recent enough you might want to save time and bandwidth by making use of it. File size limit is 32MB, in order to submit files up to 200MB in size you must request a special upload URL using the /file/scan/upload_url endpoint.

{
 'permalink': 'https://www.virustotal.com/file/d140c...244ef892e5/analysis/1359112395/',
 'resource': 'd140c244ef892e59c7f68bd0c6f74bb711032563e2a12fa9dda5b760daecd556',
 'response_code': 1,
 'scan_id': 'd140c244ef892e59c7f68bd0c6f74bb711032563e2a12fa9dda5b760daecd556-1359112395',
 'verbose_msg': 'Scan request successfully queued, come back later for the report',
 'sha256': 'd140c244ef892e59c7f68bd0c6f74bb711032563e2a12fa9dda5b760daecd556'
}

/file/scan/upload_url

Get a URL for uploading files larger than 32MB

 
gethttps://www.virustotal.com/vtapi/v2/file/scan/upload_url
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/file/scan/upload_url?apikey=<apikey>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/scan/upload_url'

params = {'apikey':'<apikey>'}

response = requests.get(url, params=params)

print(response.json())
upload_url_json = response.json()
upload_url = upload_url_json['upload_url']

file_to_scan="sample.exe"
files = {'file': (file_to_scan, open(file_to_scan, 'rb'))}
response = requests.post(upload_url, files=files)
print response.text
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

 

Restricted API

This API requires additional privileges. Please contact us if you need to upload files bigger than 32MB in size.

In order to submit files bigger than 32MB you need to obtain a special upload URL to which you can POST files up to 200MB in size. This API generates such a URL.

{
  'upload_url': 'https://www.virustotal.com/_ah/upload/?apikey=>apikey</AMmfu6aOazgAdakralarFKHjJvxHdDiN5umGU9j5RzEfWPU8jQwtRgAM_LkxJlR24R0SCJ7MsIkWLD-C9nSraPSBwK7ujv84k3QNhzkSwX-GqcerFjSOZS25eHTQP6QBDyCXWAU4vEzIHcX1iigpcTbLrS9O9LnXQUs3Jn_kocDc61aDki2-Cm6ARN99JbAK82H8lWG3cBN1c4_WJbaeCDTNNnkky8Bfz8Qhxf327o_6GPAWVeeIt39TYTYL1e45-zwxFrqFHIWl/ALBNUaYAAAAAUQKBI1y6AfbKZLSO5QBdb2zDB0EYysh6/'
}

/file/rescan

Re-scan a file

 
posthttps://www.virustotal.com/vtapi/v2/file/rescan
curl --request POST \
  --url 'https://www.virustotal.com/vtapi/v2/file/rescan' \
  --data 'apikey=<apikey>' \
  --data 'resource=<resource>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/rescan'

params = {'apikey': '<apikey>', 'resource': '<resource>'}

response = requests.post(url, params=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Form Data

apikey
string
required

Your API key

resource
string
required

Resource(s) to be re-scanned

 

Caution

This API has the potential to produce a denial of service on the scanning infrastructure if abused. Please contact us if you are going to be rescanning more than 50K files per day.

The resource argument can be the MD5, SHA-1 or SHA-256 of the file you want to re-scan.

{
  'response_code': 1,
  'scan_id': '54bc950d46a0d1aa72048a17c8275743209e6c17bdacfc4cb9601c9ce3ec9a71-1390472785',
  'permalink': 'https://www.virustotal.com/file/__sha256hash__/analysis/1390472785/',
  'sha256': '54bc950d46a0d1aa72048a17c8275743209e6c17bdacfc4cb9601c9ce3ec9a71',
  'resource': '7657fcb7d772448a6d8504e4b20168b8'
}

/file/download

Download a file

 
gethttps://www.virustotal.com/vtapi/v2/file/download
curl -v --location --output sample.bin \
  --url 'https://www.virustotal.com/vtapi/v2/file/download?apikey=<apikey>&hash=<hash>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/download'

params = {'apikey': '<apikey>', 'hash': '<hash>'}

response = requests.get(url, params=params)

downloaded_file = response.content
A binary file was returned

You couldn't be authenticated

Raw binary downloaded

Query Params

apikey
string
required

Your API key

hash
string
required

The md5/sha1/sha256 hash of the file you want to download

 

Private API

This endpoint is available in the Private API only.

/file/behaviour

Retrieve behaviour report

 
gethttps://www.virustotal.com/vtapi/v2/file/behaviour
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/file/behaviour?apikey=<apikey>&hash=<hash>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/behaviour'

params = {'apikey':'<apikey>','hash':'<hash>'}

response = requests.get(url, params=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

hash
string
required

The md5/sha1/sha256 hash of the file whose dynamic behavioural report you want to retrieve.

 

Private API

This endpoint is available in the Private API only.

VirusTotal runs a distributed setup of Cuckoo sandbox machines that execute the files we receive. Execution is attempted only once, upon first submission to VirusTotal, and only Portable Executables under 10MB in size are ran. The execution of files is a best effort process, hence, there are no guarantees about a report being generated for a given file in our dataset.

If a file did indeed produce a behavioral report, a summary of it can be obtained by using the /file/report endpoint providing the additional parameter allinfo=true. The summary will appear under the behaviour-v1 property of the additional_info field in the JSON report.

This API allows you to retrieve the full JSON report of the file's execution as returned by the Cuckoo JSON report encoder.

/file/network-traffic

Retrieve network traffic report

 
gethttps://www.virustotal.com/vtapi/v2/file/network-traffic
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/file/network-traffic?apikey=<apikey>&hash=<hash>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/network-traffic'

params = {'apikey':'<apikey>','hash':'<hash>'}

response = requests.get(url, params=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

hash
string
required

The md5/sha1/sha256 hash of the file whose network traffic dump you want to retrieve

 

Private API

This endpoint is available in the Private API only.

/file/feed

Retrieve live feed of all files submitted to VirusTotal

 
gethttps://www.virustotal.com/vtapi/v2/file/feed
curl --location --output package.tar.bz2 --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/file/feed?apikey=<apikey>&package=<package>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/feed'

params = {'apikey': '<apikey>', 'package': '<package>'}

response = requests.get(url, params=params, stream=True, allow_redirects=True)

with open('package.tar.bz2', 'wb') as fd:
  for chunk in response.iter_content(chunk_size=65536):
    fd.write(chunk)
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

package
string
required

Indicates a time window to pull reports on all items received during such window. Timestamp less than 24 hours ago, UTC.

 

Private API

This endpoint is available in the Private API only.

This endpoint allows you to retrieve a live feed of absolutely all uploaded files to VirusTotal, and download them for further scrutiny, along with their full reports. It requires you to stay relatively synced with the live submissions as only a backlog of 24 hours is provided at any given point in time.

The package argument indicates a time window to pull reports on all items received during such window. Only per-minute and hourly windows are allowed, the format is %Y%m%dT%H%M (e.g. 20160304T0900) or %Y%m%dT%H (e.g. 20160304T09). Time is expressed in UTC.

The response is a bzip2 compressed tarball. For per-minute packages the compressed package contains a unique file, the file contains a JSON per line, this JSON is a full report on a given file processed by VirusTotal during the given time window. The file report follows the exact same format as the response of the /file/report endpoint when allinfo=true is provided. For hourly packages, the tarball contains 60 files, one per each one-minute window.

To download a given file you would then perform an HTTP GET request to the URL provided in the link property of an individual report. Do not use the /file/download endpoint to retrieve the corresponding file, please use the link embedded in this response, it is far more efficient.

/file/clusters

Retrieve file clusters

 
gethttps://www.virustotal.com/vtapi/v2/file/clusters
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/file/clusters?apikey=<apikey>&date=<date>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/clusters'

params = {'apikey': '<apikey>', 'date': '<date>'}

response = requests.get(url, params=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

date
date
required

A date for which we want to access the clustering details in YYYY-MM-DD format.

 

Private API

This endpoint is available in the Private API only.

VirusTotal has built its own in-house file similarity clustering functionality. At present, this clustering works only on PE, PDF, DOC and RTF files and is based on a very simple structural feature hash. This hash can very often be confused by certain compression and packing strategies, in other words, this clustering logic is no holly grail, yet it has proven itself very useful in the past.

All of the API responses are JSON objects, if no clusters were identified for the given time frame, this JSON will have a response_code property equal to 0, if there was some sort of error with your query this code will be set to -1, if your query succeeded and file similarity clusters were found it will have a value of 1 and the rest of the JSON properties will contain the clustering information.

{
 'response_code': 1,
 'verbose_msg': 'Clustering information enclosed',
 'num_candidates': 184701,
 'num_clusters': 44269,
 'size_top200': 85160,
 'clusters': [
  {
   'label': 'vilsel [0001]',
   'avg_positives': 43, 
   'id': 'vhash 0740361d051)z1e3z 2013-09-10', 
   'size': 5712
  },
  {
    'label': 'installer [0032]',
    'avg_positives': 7, 
    'id': 'vhash 02503e0f7d5019z6hz13z1fz 2013-09-10', 
    'size': 4710
  },
  {
    'label': 'megasearch [0000]', 
    'avg_positives': 12, 
    'id': 'vhash 075056651d1d155az639z25z12z14fz 2013-09-10', 
    'size': 3651
  }
 ]
}

The JSON object returned by this endpoint contains several properties, some of them may not be clear, the following table provides some further insight:

num_candidates

Total number of files submitted during the given time frame for which a feature hash could be calculated.

num_clusters

Total number of clusters generated for the given time period under consideration, a cluster can be as small as an individual file, meaning that no other feature-wise similar file was found.

size_top200

The sum of the number of files in the 200 largest clusters identified.

clusters

List of JSON objects that contain details about the 200 largest clusters identified. These objects contain 4 properties: id, label, size and avg_positives.. The id field can be used to then query the search API call for files contained in the given cluster. The label property is a verbose human-intelligible name for the cluster. The size field is the number of files that make up the cluster. Finally, avg_positives represents the average number of antivirus detections that the files in the cluster exhibit.

/file/false-positives

Retrieve false positives

 
gethttps://www.virustotal.com/vtapi/v2/file/false-positives
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/file/false-positives?apikey=<apikey>' \
  --header 'accept-encoding: gzip' \
  --header 'user-agent: gzip'
import requests

url = 'https://www.virustotal.com/vtapi/v2/file/false-positives'

params = {'apikey':'apikey'}

headers = {
  'accept-encoding': 'gzip',
  'user-agent': 'gzip'}

response = requests.get(url, headers=headers, params=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

limit
string

The number of false positive notification to consume, if available. The maximum value for this parameter is 1000.

Headers

Accept-Encoding
string
required
User-Agent
string
required
 

Restricted API

This API is only available to antivirus vendors participating in VirusTotal. If you are one such vendor contact us to set up your access.

Required Headers

All calls to this endpoint should set two HTTP request headers: Accept-Encoding: gzip and User-Agent: gzip, otherwise you will receive 400 Bad Request Errors.

This endpoint allows vendors to consume false positive notifications for files that they mistakenly detect.

VirusTotal has partnered up with certain large trusted software developers of legit applications in order to mark files that unambiguously belong to these companies. Whenever one such file is detected by a given antivirus vendor its details and download link are published in the vendor's false positive notification pipe. The aim of this is to provide early remediation to false positives, which are a business hazard for developers and reputation/press chaos for antivirus solutions.

/url/report

Retrieve URL scan reports

 
gethttps://www.virustotal.com/vtapi/v2/url/report
curl --request GET \
    --url 'https://www.virustotal.com/vtapi/v2/url/report?apikey=<apikey>&resource=<resource>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/url/report'

params = {'apikey': '<apikey>', 'resource':'<resource>'}

response = requests.get(url, params=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

resource
string
required

Resource(s) to be retrieved

allinfo
boolean

Return additional information about the file

 

The resource argument must be the URL for which you want to retrieve the most recent report. You may also specify a scan_id returned by the /url/scan endpoint to access a specific report.

If the allinfo argument is set to true additional information other than the URL scanning engines results is returned. VirusTotal related metadata (first seen date, last seen date, files downloaded from the given URL, etc.) and the output of other tools and datasets when fed with the URL.

{
 'response_code': 1,
 'verbose_msg': 'Scan finished, scan information embedded in this object',
 'scan_id': '1db0ad7dbcec0676710ea0eaacd35d5e471d3e11944d53bcbd31f0cbd11bce31-1390467782',
 'permalink': 'https://www.virustotal.com/url/__urlsha256__/analysis/1390467782/',
 'url': 'http://www.virustotal.com/',
 'scan_date': '2014-01-23 09:03:02',
 'filescan_id': null,
 'positives': 0,
 'total': 51,
 'scans': {
    'CLEAN MX': {
      'detected': false, 
      'result': 'clean site'
    },
    'MalwarePatrol': {
      'detected': false, 
      'result': 'clean site'
    }
  }
}

/url/scan

Scan an URL

 
posthttps://www.virustotal.com/vtapi/v2/url/scan
curl --request POST \
  --url 'https://www.virustotal.com/vtapi/v2/url/scan' \
  --data 'apikey=<apikey>' \
  --data 'url=<url>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/url/scan'

params = {'apikey': '<apikey>', 'url':'<url>'}

response = requests.post(url, data=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Form Data

apikey
string
required

Your API key

url
string
required

The URL that should be scanned

 
{
 'response_code': 1,
 'verbose_msg': 'Scan request successfully queued, come back later for the report',
 'scan_id': '1db0ad7dbcec0676710ea0eaacd35d5e471d3e11944d53bcbd31f0cbd11bce31-1320752364',
 'scan_date': '2011-11-08 11:39:24',
 'url': 'http://www.virustotal.com/',
 'permalink': 'http://www.virustotal.com/url/1db0ad7dbcec0676710ea0eaacd35d5e471d3e11944d53bcbd31f0cbd11bce31/analysis/1320752364/'
}

/url/feed

Retrieve live feed of all URLs submitted to VirusTotal

 
gethttps://www.virustotal.com/vtapi/v2/url/feed
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/url/feed?apikey=apikey&package=package'
var request = require("request");

var options = { method: 'GET',
  url: 'https://www.virustotal.com/vtapi/v2/url/feed',
  qs: 
   { apikey: 'apikey',
     package: 'package' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://www.virustotal.com/vtapi/v2/url/feed?apikey=apikey&package=package")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://www.virustotal.com/vtapi/v2/url/feed?apikey=apikey&package=package");

xhr.send(data);
import requests

url = "https://www.virustotal.com/vtapi/v2/url/feed"

querystring = {"apikey":"apikey","package":"package"}

response = requests.request("GET", url, params=querystring)

print(response.text)
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

package
string
required

Indicates a time window to pull reports on all items received during such window

 

Private API

This endpoint is available in the Private API only.

This endpoint allows you to retrieve a live feed of reports on absolutely all URLs scanned by VirusTotal. It requires you to stay relatively synced with the live submissions as only a backlog of 24 hours is provided at any given point in time.

The package argument indicates a time window to pull reports on all items received during such window. Only per-minute and hourly windows are allowed, the format is %Y%m%dT%H%M (e.g. 20160304T0900) or %Y%m%dT%H (e.g. 20160304T09). Time is expressed in UTC.

The response is a bzip2 compressed tarball. For per-minute packages the compressed package contains a unique file, the file contains a JSON per line, this JSON is a full report on a given URL processed by VirusTotal during the given time window. The URL report follows the exact same format as the response of the /url/report endpoint when allinfo=true is provided. For hourly packages, the tarball contains 60 files, one per each one-minute window.

/domain/report

Retrieves a domain report

 
gethttps://www.virustotal.com/vtapi/v2/domain/report
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/domain/report?apikey=<apikey>&domain=<domain>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/domain/report'

params = {'apikey':'<apikey>','domain':'<domain>'}

response = requests.get(url, params=params)

print(response.json())
<?php

//get API KEY from environment, or set your API key here
$api_key = getenv('VT_API_KEY') ? getenv('VT_API_KEY') :'YOUR_API_KEY';
$domain = 'drive.google.com';


$data = array('apikey' => $api_key,'domain'=> $domain);
$ch = curl_init();
$url = 'https://www.virustotal.com/vtapi/v2/domain/report?';
$url .= http_build_query($data); // append query params
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, 1); // remove this if your not debugging
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); // please compress data
curl_setopt($ch, CURLOPT_USERAGENT, "gzip, My php curl client");
curl_setopt($ch, CURLOPT_RETURNTRANSFER ,True);

$result=curl_exec ($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
print("status = $status_code\n");
if ($status_code == 200) { // OK
  $js = json_decode($result, true);
  print_r($js);
} else {  // Error occured
  print($result);
}
curl_close ($ch);
?>
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string

Your API key

domain
string

A domain name

 
{
 'response_code': 1,
 'verbose_msg': 'Domain found in dataset',
 'resolutions': [
   { 
  	'last_resolved': '2013-04-05 00:00:00', 
  	'ip_address': '90.156.201.11'
   },
   {
    'last_resolved': '2013-04-07 00:00:00', 
    'ip_address': '90.156.201.14'
   },
   {
    'last_resolved': '2013-04-08 00:00:00', 
    'ip_address': '90.156.201.27'
   },
   {
     'last_resolved': '2013-04-07 00:00:00', 
     'ip_address': '90.156.201.71'
   }
 ],
 'detected_urls': [
   {
     'url': 'http://027.ru/', 
     'positives': 2, 
     'total': 37, 
     'scan_date': '2013-04-07 07:18:09'
   }
  ]
}

/ip-address/report

Retrieve an IP address report

 
gethttps://www.virustotal.com/vtapi/v2/ip-address/report
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/ip-address/report?apikey=<apikey>&ip=<ip>'
import requests

url = 'https://www.virustotal.com/vtapi/v2/ip-address/report'

params = {'apikey':'<apikey>','ip':'<ip>'}

response = requests.get(url, params=params)

print(response.json())
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

ip
string
required

An IP address

 
{
 'response_code': 1,
 'verbose_msg': 'IP address found in dataset',
 'resolutions': [
  {
    'last_resolved': '2013-04-08 00:00:00', 
    'hostname': '027.ru'
  },
  {
    'last_resolved': '2013-04-08 00:00:00', 
    'hostname': 'auto.rema-tiptop.ru'
  },
  {
    'last_resolved': '2013-04-08 00:00:00', 
    'hostname': 'catalog24de.ru'
  },
  {
    'last_resolved': '2013-04-08 00:00:00', 
    'hostname': 'club.velhod.ru'
  },
  {
    'last_resolved': '2013-04-08 00:00:00', 
    'hostname': 'danilova.pro'
  }
 ],
 'detected_urls': [
  {
    'url': 'http://027.ru/', 
    'positives': 2, 
    'total': 37, 
    'scan_date': '2013-04-07 07:18:09'
  }
 ]
}

/comments/get

Get comments for a file or URL

 
gethttps://www.virustotal.com/vtapi/v2/comments/get
curl --request GET \
  --url 'https://www.virustotal.com/vtapi/v2/comments/get?apikey=apikey&resource=resource'
var request = require("request");

var options = { method: 'GET',
  url: 'https://www.virustotal.com/vtapi/v2/comments/get',
  qs: 
   { apikey: 'apikey',
     resource: 'resource' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://www.virustotal.com/vtapi/v2/comments/get?apikey=apikey&resource=resource")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://www.virustotal.com/vtapi/v2/comments/get?apikey=apikey&resource=resource");

xhr.send(data);
import requests

url = "https://www.virustotal.com/vtapi/v2/comments/get"

querystring = {"apikey":"apikey","resource":"resource"}

response = requests.request("GET", url, params=querystring)

print(response.text)
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

apikey
string
required

Your API key

resource
string
required

Either an md5/sha1/sha256 hash of the file or the URL itself you want to retrieve.

before
date-time

A datetime token that allows you to iterate over all comments on a specific item whenever it has been commented on more than 25 times.

 
{
 'response_code': 1,
 'verbose_msg': 'Resource found, comments, if any, returned here',
 'resource': '13166fc9de263ee2c676430ae88e65040e10761c90e79347a2684476bc60e622',
 'comments': [
   {
    'date': '20120404132340',
    'comment': '[b]Bot Communication Details:[\/b]\nServer DNS Name: 67.230.163.30
                   Service Port: 80\nDirection Command User-Agent Host Connection
                   Pragma\nGET \/?0b72ab=huTK4N7k6G9718ze0NLa5%2BnM1NaHx9fXtqfeyr
                   FjiKSbxZ%2BmmqOjpqeXZqPPnpOhnda\nrpJ2bkpfLyZdk0MqokZNplofO5aKh
                   [... continues ...]'
   },
   {
    'date': '20120404132122',
    'comment': '#fakeAV'
   },
   {
    'date': '20120404131639',
    'comment': 'GET \/ury1007_8085.php?il41225lo=jeWqkqWocs3h1NDHi6Lcx56mlaqol
                   tnVmG5lWJbO0eWeuqZ6w4nN4aKjo6CgkqOkb6mrxL%2BZw8%2FJatXCqrOdmO3
                   S16mjl5eUnNbemcTJooLGicreoqOpp5eeZ2pgY26aoaOUjNih1NfW4aKjmefS0
                   HFiYmRrkuPnzaPGXtSYx6KepaWkopKopG9jaJ%2BiqJWamWWjicXd0tPc3qbjq
                   6hlYKXR4ebQ1MaZoNDC4dnX5eLUmpiVoKVj1d3Z0IzPpNnXnuPb6d%2Fm0ZKnp
                   pR1otCs5sbUyXPcz8aS HTTP\/1.1\nAccept: image\/gif, image\/jpeg
                   , image\/pjpeg, image\/pjpeg, application\/x-shockwave-flash,
                   application\/vnd.ms-excel, application\/vnd.ms-powerpoint,
                   [... continues ...]'
   }
  ]
}

The server answers with the comments sorted in descending order according to their date. Please note that it will only answer back with at most 25 comments. If the answer contains less than 25 comments it means that there are no more comments for that item. On the other hand, if 25 comments were returned you can keep issuing further calls making use of the optional before parameter, this parameter should be fixed to the oldest (last in the list) comment's date token, exactly in the same format that was returned by your previous API call (e.g. 20120404132340).

If there were any comments the response code will be 1, and 0 if otherwise. Please note that comments may have bbcode formatting tags in them.

/comments/put

Post comment for a file or URL

 
posthttps://www.virustotal.com/vtapi/v2/comments/put
import requests
params = {
  'apikey': '-YOUR API KEY HERE-',
  'resource':'99017f6eebbac24f351415dd410d522d',
  'comment': 'How to disinfect you from this file... #disinfect #zbot'
}
response = requests.post('https://www.virustotal.com/vtapi/v2/comments/put', params=params)
response_json = response.json()
curl -v --request POST \
  --url 'https://www.virustotal.com/vtapi/v2/comments/put' \
  -d apikey=${VT_API_KEY} \
  -d 'comment=#malware' \
  -d resource=8ebc97e05c8e1073bda2efb6f4d00ad7e789260afa2c276f0c72740b838a0a93
A binary file was returned

You couldn't be authenticated

{
    "response_code": 1,
    "verbose_msg": "Your comment was successfully posted"
}

Form Data

apikey
string
required

Your API key

resource
string
required

Either an md5/sha1/sha256 hash of the file you want to review or the URL itself that you want to comment on

comment
string
required

The comment's text

 

Tag the comments

See the community documentation on using hash tags.