You have probably used the virustotal.com site more than once to check if the binaries contain malicious functions, or to test your own developments. This service has a free API, the work with which we will analyze in Python in this article.
To use the VirusTotal APIs without restrictions, you need to get a key, which costs a serious amount - prices start at 700 euros per month. Moreover, a private person, even if they are willing to pay, will not be given a key.
However, you should not despair, since the service provides the main functions for free and limits us only by the number of requests - no more than two per minute. Well, you'll have to put up with it.
Getting the API Key
So, first of all, we need to register on the site. There are no problems - I'm sure you can handle it. After registration, we take the access key by going to the API key menu item.
Here is the access key to the VirusTotal API API
Versions
The current API version is number 2 . But at the same time, there is already a new option - number 3 . This version of the API is still in beta, but it is already quite usable, especially since the possibilities that it provides are much wider.
So far, the developers recommend using the third version only for experiments or for non-critical projects. We will analyze both versions. The access key for them is the same.
VirusTotal API. Version 2
As with other popular web services, working with an API is about sending requests over HTTP and receiving responses.
The second version of the API allows:
Errors
If the request was processed correctly and no errors occurred, a 200 (OK) code will be returned.
If an error occurs, then there may be such options:
Sending a file to the server for scanning
To send a file for scanning, you need to generate a POST request to the address https://www.virustotal.com/vtapi/v2 , while in the request you need to specify the API access key and transfer the file itself (there is a restriction here file size - no more than 32 MB). It might look like this (using Python):
Here, instead of the <access key> line, you need to insert your API access key, and instead of <file path> - the path to the file that you will send to VirusTotal. If you don't have the requests library, then install it with the pip install requests command.
In response, if everything went well and the HTTP status code is 200, we will get something like this:
Here we see the response_code and verbose_msg values, as well as the SHA-256, SHA-1 and MD5 hashes of the file, a link to the permalink site scan results of the file, and the file's scan_id.
Keep in mind that when opening a file or sending requests to the server, exceptions can occur: FileNotFoundError if the file does not exist, requests.ConnectionError, requests.Timeout for connection errors, and so on.
Getting a report on the last scan of a file
Using any of the hashes or the scan_id value from the response, you can get a report on the last scan of a file (if the file has already been uploaded to VirusTotal). To do this, you need to generate a GET request and specify the access key and file identifier in the request. For example, if we have the scan_id from the previous example, then the request would look like this:
If successful, we will see the following in response:
Here, as in the first example, we get the hash values of the file, scan_id, permalink, response_code and verbose_msg values. We also see the results of scanning the file with antiviruses and the overall results of the total assessment - how many antivirus engines were involved in the scan and positives - how many antiviruses gave a positive verdict.
To display the scan results of all antiviruses in a digestible form, you can, for example, write something like this:
Displaying information about the results of scanning a file on VirusTotal using different anti-virus engines
Sending a URL to the server for scanning
To send a URL for scanning, we need to generate and send a POST request containing an access key and the URL itself:
In response, we will receive approximately the same as when sending a file, except for the hash values. The contents of the scan_id field can be used to get a report on the crawl of a given URL.
Obtaining a report on the results of scanning a URL
Let's form a GET request with an access key and specify either the URL itself as a string, or the scan_id value obtained using the previous function. It will look like this:
In addition to the access key and the string with the URL, there is an optional scan parameter - by default it is zero. If its value is equal to one, then when there is no information about the requested URL in the VirusTotal database (the URL has not been checked before), this URL will be automatically sent to the server for verification, after which we will receive in response the same information as when sending the URL to the server. If this parameter is zero (or was not set), we will receive a report about this URL or (if information about it is not in the VirusTotal database) a response like this:
Obtaining information about IP addresses and domains
To check IP addresses and domains, you need to generate and send a GET request with a key, the name of the domain to be checked, or IP as a string. To check a domain, it looks like this:
To check the IP address:
The answers to such queries are voluminous and contain a lot of information. For example, for IP 178.248.232.27 (this is the "Hacker" IP), the beginning of the report received from the VirusTotal server looks like this:
VirusTotal API. Version 3
API version 3 has a lot more features than version 2, even with a free key. Moreover, when experimenting with the third version, I did not notice that the number of uploaded objects (files or addresses) to the server was limited within a minute. Looks like the beta restrictions don't work at all yet.
The functions of the third version of the API are designed using REST principles and are easy to understand. The access key is passed in the request header here.
Errors
In the third version of the API, the list of errors (and, accordingly, HTTP status codes) has expanded. Were added:
The JSON format for the error is as follows:
Functions for working with files
The third version of the API allows you to:
In response, we will receive the following:
Here we see the id value, which serves as the id of the file. This identifier should be used to get information about the analysis of the file in GET requests like /analyses (we'll talk about this a little later).
To get a URL to download a large file (more than 32 MB), you need to send a GET request, which specifies https://www.virustotal.com/api/v3/files/upload_url. Insert the access key into the header:
In response, we will receive JSON with the address where the file should be downloaded for analysis. The resulting URL can only be used once.
To get information about a file that the service has already parsed, you need to make a GET request with the file identifier in the URL (it can be a SHA-256, SHA-1 or MD5 hash). As in the previous cases, we specify the access key in the header:
In response, we will receive a file scan report, where, in addition to the results of scanning by all VirusTotal antiviruses, there will be a lot of additional information, the composition of which depends on the type of file scanned. For example, for executable files, you can see information about the following attributes:
Or, for example, information about the sections of the executable file:
If the file has not been uploaded to the server before and has not yet been parsed, then in response we will receive a Not Found Error type error with an HTTP status code of 404:
To re-parse the file, you also need to send a GET request to the server, in which we put the file identifier in the URL, and add /analyse:
The response will include the same file descriptor as in the first case - when uploading the file to the server. And just like in the first case, the identifier from the descriptor can be used to obtain information about the analysis of the file via a GET request like /analyses.
You can view the comments of users of the service, as well as the results of voting on a file, by sending an appropriate GET request to the server. For comments:
To get voting results:
In both cases, you can use an optional limit parameter that specifies the maximum number of comments or votes in a response to a request. You can use this option, for example, like this:
To post your comment or vote on a file, we create a POST request, and pass the comment or vote as a JSON object:
To get more information about a file, you can query details about the objects associated with it. In this case, the objects can characterize, for example, the behavior of a file (behaviors object) or URL, IP addresses, domain names (contacted_urls, contacted_ips, contacted_domains objects). The
most interesting object behavioursFor example, for executable files, it will include information about loadable modules, processes created and launched, file system and registry operations, and network operations.
To get this information, we send a GET request:
The response will contain a JSON object with information about the behavior of the file:
Functions for working with URLs
The list of possible operations with URLs includes:
To send a URL for analysis, you need to use a POST request:
In response, we will see a URL descriptor (similar to a file descriptor):
We use the id identifier from this descriptor to obtain information about the analysis of the file via a GET request like /analyses (more on this request at the end of the article).
You can get information about domains or IP addresses associated with a URL by using a GET request like /network_locationthis (here we use the Base64 or SHA-256 identifier of the URL):
Other operations with URLs are performed in the same way as similar operations with files.
Domain and IP Address
Features This list of features includes:
For example, you can get information about the www.xakep.ru domain in the following way:
And, for example, look at the comments at the IP address 178.248.232.27 - like this:
GET request of type /analyses
This request allows you to get information about the results of the analysis of files or URLs after they have been uploaded to the server or after re-analysis. This must use the identifier contained in the id field of the file descriptor, or the URL obtained as a result of sending requests to download the file or URL to the server, or as a result of reparsing the file or URL.
For example, you can create a similar request for a file like this:
And a variant for the URL:
Conclusion
We have gone through all the main functions of the VirusTotal API. You can borrow the given code for your projects. If you use the second version, you will need to make sure that you do not send requests too often, but in the third version there is no such restriction yet. I recommend choosing it, because the possibilities here are also much wider. In addition, sooner or later it will become the main one.
www

To use the VirusTotal APIs without restrictions, you need to get a key, which costs a serious amount - prices start at 700 euros per month. Moreover, a private person, even if they are willing to pay, will not be given a key.
However, you should not despair, since the service provides the main functions for free and limits us only by the number of requests - no more than two per minute. Well, you'll have to put up with it.
Getting the API Key
So, first of all, we need to register on the site. There are no problems - I'm sure you can handle it. After registration, we take the access key by going to the API key menu item.

Here is the access key to the VirusTotal API API
Versions
The current API version is number 2 . But at the same time, there is already a new option - number 3 . This version of the API is still in beta, but it is already quite usable, especially since the possibilities that it provides are much wider.
So far, the developers recommend using the third version only for experiments or for non-critical projects. We will analyze both versions. The access key for them is the same.
VirusTotal API. Version 2
As with other popular web services, working with an API is about sending requests over HTTP and receiving responses.
The second version of the API allows:
- send files for review;
- receive a report on previously scanned files using the file identifier (SHA-256, SHA-1 or MD5 hash of the file, or the scan_id value from the response received after sending the file);
- send URL for scanning to the server;
- receive a report on previously checked addresses using either the URL itself or the scan_id value from the response received after sending the URL to the server;
- receive a report by IP address;
- receive a report on a domain name.
Errors
If the request was processed correctly and no errors occurred, a 200 (OK) code will be returned.
If an error occurs, then there may be such options:
- 204 - Request rate limit exceeded error. Occurs when the quota of the allowed number of requests has been exceeded (for a free key, the quota is four requests per minute);
- 400 - Bad request type error. Occurs when the request is incorrectly formed, for example, if there are no necessary arguments or they have invalid values;
- 403 is a Forbidden error. Occurs when trying to use API functions that are available only with a paid key when it is not there.
- response_code - if the requested object (file, URL, IP address or domain name) is in the VirusTotal database (that is, it was checked before) and information about this object can be obtained, then the value of this field will be equal to one; if the requested object is in the parsing queue, the field value will be -2; if the requested object is not in the VirusTotal database, it is equal to zero;
- verbose_msg provides a more detailed description of the response_code value (for example, Scan finished, information embedded after the file is submitted for scanning).
Sending a file to the server for scanning
To send a file for scanning, you need to generate a POST request to the address https://www.virustotal.com/vtapi/v2 , while in the request you need to specify the API access key and transfer the file itself (there is a restriction here file size - no more than 32 MB). It might look like this (using Python):
You must reply before you can see the hidden data contained here.
In response, if everything went well and the HTTP status code is 200, we will get something like this:
You must reply before you can see the hidden data contained here.
Keep in mind that when opening a file or sending requests to the server, exceptions can occur: FileNotFoundError if the file does not exist, requests.ConnectionError, requests.Timeout for connection errors, and so on.
Getting a report on the last scan of a file
Using any of the hashes or the scan_id value from the response, you can get a report on the last scan of a file (if the file has already been uploaded to VirusTotal). To do this, you need to generate a GET request and specify the access key and file identifier in the request. For example, if we have the scan_id from the previous example, then the request would look like this:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
To display the scan results of all antiviruses in a digestible form, you can, for example, write something like this:
You must reply before you can see the hidden data contained here.

Displaying information about the results of scanning a file on VirusTotal using different anti-virus engines
Sending a URL to the server for scanning
To send a URL for scanning, we need to generate and send a POST request containing an access key and the URL itself:
You must reply before you can see the hidden data contained here.
Obtaining a report on the results of scanning a URL
Let's form a GET request with an access key and specify either the URL itself as a string, or the scan_id value obtained using the previous function. It will look like this:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
To check IP addresses and domains, you need to generate and send a GET request with a key, the name of the domain to be checked, or IP as a string. To check a domain, it looks like this:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
API version 3 has a lot more features than version 2, even with a free key. Moreover, when experimenting with the third version, I did not notice that the number of uploaded objects (files or addresses) to the server was limited within a minute. Looks like the beta restrictions don't work at all yet.
The functions of the third version of the API are designed using REST principles and are easy to understand. The access key is passed in the request header here.
Errors
In the third version of the API, the list of errors (and, accordingly, HTTP status codes) has expanded. Were added:
- 401 is an error of type User Not Active Error, it occurs when the user account is inactive;
- 401 - an error of type Wrong Credentials Error, occurs if an invalid access key is used in the request;
- 404 Not Found Error occurs when the requested parse object is not found;
- 409 - Already Exists Error occurs when the resource already exists.
- 429 - An error of the type Quota Exceeded Error, occurs when one of the quotas for the number of requests (minute, daily or monthly) is exceeded. As I said, during my experiments, no restrictions on the number of requests per minute were observed, although I used a free key;
- 429 - Too Many Requests Error, occurs when there are a large number of requests in a short time (may be caused by server load);
- 503 is a Transient Error, a temporary server error in which retrying the request may work.
The JSON format for the error is as follows:
You must reply before you can see the hidden data contained here.
The third version of the API allows you to:
- upload files for analysis to the server;
- get a URL for uploading a file larger than 32 MB to the server;
- receive reports on the results of file analysis;
- re-parse the file;
- get comments from VirusTotal users on the desired file;
- send your comment to a specific file;
- view voting results for a specific file;
- vote for the file;
- get extended information about a file.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
To get a URL to download a large file (more than 32 MB), you need to send a GET request, which specifies https://www.virustotal.com/api/v3/files/upload_url. Insert the access key into the header:
You must reply before you can see the hidden data contained here.
To get information about a file that the service has already parsed, you need to make a GET request with the file identifier in the URL (it can be a SHA-256, SHA-1 or MD5 hash). As in the previous cases, we specify the access key in the header:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You can view the comments of users of the service, as well as the results of voting on a file, by sending an appropriate GET request to the server. For comments:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
most interesting object behavioursFor example, for executable files, it will include information about loadable modules, processes created and launched, file system and registry operations, and network operations.
To get this information, we send a GET request:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
The list of possible operations with URLs includes:
- sending the URL to the server for analysis;
- getting information about the URL;
- URL parsing;
- receiving comments from VirusTotal users at the desired URL;
- posting your comments to a specific URL;
- receiving voting results for a specific URL;
- sending your vote for any URL;
- obtaining extended information about the URL;
- obtaining information about the domain or IP address of the desired URL.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You can get information about domains or IP addresses associated with a URL by using a GET request like /network_locationthis (here we use the Base64 or SHA-256 identifier of the URL):
You must reply before you can see the hidden data contained here.
Domain and IP Address
Features This list of features includes:
- obtaining information about a domain or IP address;
- receiving comments from VirusTotal users on the desired domain or IP address;
- sending your comments to a specific domain or IP address;
- receiving voting results for a specific domain or IP address;
- sending a vote for a domain or IP address;
- obtaining extended information about a domain or IP address.
For example, you can get information about the www.xakep.ru domain in the following way:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
This request allows you to get information about the results of the analysis of files or URLs after they have been uploaded to the server or after re-analysis. This must use the identifier contained in the id field of the file descriptor, or the URL obtained as a result of sending requests to download the file or URL to the server, or as a result of reparsing the file or URL.
For example, you can create a similar request for a file like this:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
We have gone through all the main functions of the VirusTotal API. You can borrow the given code for your projects. If you use the second version, you will need to make sure that you do not send requests too often, but in the third version there is no such restriction yet. I recommend choosing it, because the possibilities here are also much wider. In addition, sooner or later it will become the main one.
www