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!

Overview

 

VirusTotal API v3 will be a complete update to current version 2, and will let allow you to interact fully with VirusTotal backend, while we polish it, here is published the documentation about users and groups that are necessary for interacting with some other currently open parts.

Users & Groups

 

Users and groups can be managed using the VirusTotal API. Using the API endpoints described in this section group administrators can programmatically add and remove users from their group, list the users existing users, and much more.

/users/{id}

Retrieve user information

 
gethttps://www.virustotal.com/api/v3/users/id
curl --request GET \
  --url https://www.virustotal.com/api/v3/users/{id} \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

User ID

Headers

x-apikey
string
required

Your API key

 
{
  "type": "user",
  "id": "wcoyote",
  "links": {
    "self": "https://www.virustotal.com/api/v3/users/wcoyote"
  },
  "data": {
    "attributes": {
      "apikey": "48e3f0c8d...",
      "email": "wcoyote@acme.com",
      "first_name": "Wile E.",
      "last_login": 1517212458,
      "last_name": "Coyote",
      "privileges": {
        "intelligence": {
          "granted": true,
          "inherited_from": "acme"
        },
        "monitor": {
          "granted": true,
          "inherited_from": "acme"
        },
        "monitor-partner": {
          "granted": true,
          "inherited_from": "acme"
        }
      },
      "quotas": {
        "api_requests_daily": {
          "allowed": 5760,
          "used": 0
        },
        "api_requests_hourly": {
          "allowed": 240,
          "used": 0
        },
        "api_requests_monthly": {
          "allowed": 178560,
          "used": 0
        },
        "intelligence_downloads_monthly": {
          "allowed": 0,
          "used": 0
        },
        "intelligence_retrohunt_jobs_monthly": {
          "allowed": 0,
          "used": 0
        },
        "intelligence_searches_monthly": {
          "allowed": 0,
          "used": 0
        },
        "monitor_storage_bytes": {
          "allowed": 104857600,
          "used": 0
        },
        "monitor_uploaded_bytes": {
          "allowed": 314572800,
          "used": 0
        }
      },
      "reputation": 100,
      "status": "active",
      "user_since": 1496049868
    }  
  }
}

/groups/{id}

Retrieve group information

 
gethttps://www.virustotal.com/api/v3/groups/id
curl --request GET \
  --url https://www.virustotal.com/api/v3/groups/{id} \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Group ID

Headers

x-apikey
string
required

Your API key

 
{
  "type": "group",
  "id": "acme",
  "links": {
    "self": "https://www.virustotal.com/api/v3/groups/acme"
  },
  "data": {
    "attributes": {
      "allowed_scanners": [],
      "apikey":"ebdc9dd69dcfc2...",
      "auto_add_users": [],
      "billing_address": "Coyote Road 1",
      "billing_country": "United States",
      "billing_country_iso": "US",
      "billing_emails": ["billing@acme.com"],
      "billing_organization_legal_name": "Acme Inc.",
      "billing_tax_id": "1234567",
      "contact_emails": ["contact@acme.com"],
      "country": "United States",
      "country_iso": "US",
      "domain_name": "acme.com",
      "organization": "Acme",
      "privileges": {
        "download": {
          "granted": false
        },
        "file-feed": {
          "granted": false
        },
        "intelligence": {
          "granted": true
        },
        "monitor": {
          "granted": false
        },
        "retrohunt": {
          "granted": false
        },
        "url-feed": {
          "granted": false
        },
      },
      "quota_usage_by_user": {},
      "quotas": {
        "api_requests_daily": {
          "allowed": 15000000,
          "used": 0
        },
        "api_requests_hourly": {
          "allowed": 3300000,
          "used": 0
        },
        "api_requests_monthly": {
          "allowed": 1000000000,
          "used": 0
        },
        "intelligence_downloads_monthly": {
          "allowed": 1000000,
          "used": 0
        },
        "intelligence_retrohunt_jobs_monthly": {
          "allowed": 300,
          "used": 0
        },
        "intelligence_searches_monthly": {
          "allowed": 1000000,
          "used": 0
        },
        "monitor_storage_bytes": {
          "allowed": 5242880000,
          "used": 0
        },
        "monitor_storage_files": {
          "allowed": 100000,
          "used": 0
        },
        "monitor_uploaded_bytes": {
          "allowed": 15728640000,
          "used": 0
        },
        "monitor_uploaded_files": {
          "allowed": 300000,
          "used": 0
        }
      }
    }
  }
}

/groups/{id}/relationships/{relationship}

Retrieve objects related to a group.

 

Header Auth

 Authentication is required for this endpoint.
gethttps://www.virustotal.com/api/v3/groups/id/relationships/relationship
curl --request GET \
  --url https://www.virustotal.com/api/v3/groups/{id}/relationships/{relationship} \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Group ID.

relationship
string
required

Relationship name (see table below)

Query Params

limit
string

Maximum number of related objects to retrieve

cursor
int32

Continuation cursor

Headers

x-apikey
string
required

Your API key

 

Group objects have number of relationships to other objects. As mentioned in the Relationships section, those related objects can be retrieved by sending GET requests to the relationship URL.

The relationships supported by group objects are:

Relationship
Description
Accessibility

graphs

Graphs created by group members.

Everyone

{
    "data": [
        {
            "attributes": {
                "creation_date": 1530175655,
                "graph_data": {
                    "description": "Piedpiper.com"
                },
                "links": [
                    {
                        "connection_type": "subdomains",
                        "source": "piedpiper.com",
                        "target": "relationships_subdomains_piedpipercom"
                    },
                    {
                        "connection_type": "subdomains",
                        "source": "relationships_subdomains_piedpipercom",
                        "target": "www.piedpiper.com"
                    },
                    {
                        "connection_type": "subdomains",
                        "source": "relationships_subdomains_piedpipercom",
                        "target": "assets.piedpiper.com"
                    },
                    {
                        "connection_type": "resolutions",
                        "source": "piedpiper.com",
                        "target": "relationships_resolutions_piedpipercom"
                    },
                    {
                        "connection_type": "resolutions",
                        "source": "relationships_resolutions_piedpipercom",
                        "target": "104.16.18.64"
                    },
                    {
                        "connection_type": "resolutions",
                        "source": "relationships_resolutions_piedpipercom",
                        "target": "104.16.19.64"
                    },
                    {
                        "connection_type": "resolutions",
                        "source": "relationships_resolutions_piedpipercom",
                        "target": "104.16.15.64"
                    },
                    {
                        "connection_type": "resolutions",
                        "source": "relationships_resolutions_piedpipercom",
                        "target": "104.16.16.64"
                    },
                    {
                        "connection_type": "resolutions",
                        "source": "relationships_resolutions_piedpipercom",
                        "target": "104.16.17.64"
                    },
                    {
                        "connection_type": "resolutions",
                        "source": "relationships_resolutions_piedpipercom",
                        "target": "198.185.159.136"
                    }
                ],
                "nodes": [
                    {
                        "entity_id": "piedpiper.com",
                        "index": 0,
                        "text": "piedpiper.com",
                        "type": "domain",
                        "x": -129,
                        "y": 229
                    },
                    {
                        "entity_id": "relationships_subdomains_piedpipercom",
                        "index": 1,
                        "type": "relationship",
                        "x": -114,
                        "y": 312
                    },
                    {
                        "entity_id": "www.piedpiper.com",
                        "index": 2,
                        "type": "domain",
                        "x": -136,
                        "y": 356
                    },
                    {
                        "entity_id": "assets.piedpiper.com",
                        "index": 3,
                        "type": "domain",
                        "x": -79,
                        "y": 347
                    },
                    {
                        "entity_id": "relationships_resolutions_piedpipercom",
                        "index": 4,
                        "type": "relationship",
                        "x": -154,
                        "y": 144
                    },
                    {
                        "entity_id": "104.16.18.64",
                        "index": 5,
                        "type": "ip_address",
                        "x": -129,
                        "y": 98
                    },
                    {
                        "entity_id": "104.16.19.64",
                        "index": 6,
                        "type": "ip_address",
                        "x": -178,
                        "y": 182
                    },
                    {
                        "entity_id": "104.16.15.64",
                        "index": 7,
                        "type": "ip_address",
                        "x": -201,
                        "y": 114
                    },
                    {
                        "entity_id": "104.16.16.64",
                        "index": 8,
                        "type": "ip_address",
                        "x": -105,
                        "y": 134
                    },
                    {
                        "entity_id": "104.16.17.64",
                        "index": 9,
                        "type": "ip_address",
                        "x": -208,
                        "y": 151
                    },
                    {
                        "entity_id": "198.185.159.136",
                        "index": 10,
                        "type": "ip_address",
                        "x": -170,
                        "y": 92
                    }
                ],
                "position": {
                    "scale": "1",
                    "x": 1346,
                    "y": 561
                },
                "private": false
            },
            "id": "bccd7d4c73f540cab15effd52164658f2a5aa510552f8507f98718f39a438b95",
            "links": {
                "self": "http://localhost:8080/api/v3/graphs/bccd7d4c73f540cab15effd52164658f2a5aa510552f8507f98718f39a438b95"
            },
            "type": "graph"
        },
        {
            "attributes": {
                "creation_date": 1530175617,
                "graph_data": {
                    "description": "Hooli.com"
                },
                "links": [
                    {
                        "connection_type": "subdomains",
                        "source": "hooli.com",
                        "target": "relationships_subdomains_hoolicom"
                    },
                    {
                        "connection_type": "subdomains",
                        "source": "relationships_subdomains_hoolicom",
                        "target": "www.hooli.com"
                    },
                    {
                        "connection_type": "downloaded_files",
                        "source": "hooli.com",
                        "target": "relationships_downloaded_files_hoolicom"
                    },
                    {
                        "connection_type": "downloaded_files",
                        "source": "relationships_downloaded_files_hoolicom",
                        "target": "993b97a069b66508366ee96b3d9a634664ddc13f0d3627b6df478518efd45637"
                    }
                ],
                "nodes": [
                    {
                        "entity_id": "hooli.com",
                        "index": 0,
                        "text": "hooli.com",
                        "type": "domain",
                        "x": 34,
                        "y": 162
                    },
                    {
                        "entity_id": "relationships_subdomains_hoolicom",
                        "index": 1,
                        "type": "relationship",
                        "x": -24,
                        "y": 152
                    },
                    {
                        "entity_id": "www.hooli.com",
                        "index": 2,
                        "type": "domain",
                        "x": -69,
                        "y": 154
                    },
                    {
                        "entity_id": "relationships_downloaded_files_hoolicom",
                        "index": 3,
                        "type": "relationship",
                        "x": 89,
                        "y": 185
                    },
                    {
                        "entity_id": "993b97a069b66508366ee96b3d9a634664ddc13f0d3627b6df478518efd45637",
                        "index": 4,
                        "type": "file",
                        "x": 128,
                        "y": 210
                    }
                ],
                "position": {
                    "scale": "1",
                    "x": 1132,
                    "y": 455
                },
                "private": false
            },
            "id": "272b78feda2261af16e23789baeba67989619b5ee736637ff0d474808248bd52",
            "links": {
                "self": "https://www.virustotal.com/api/v3/graphs/g272b78feda2261af16e23789baeba67989619b5ee736637ff0d474808248bd52"
            },
            "type": "graph"
        }
    ],
    "links": {
        "self": "https://www.virustotal.com/api/v3/groups/danigroup/graphs?limit=10"
    }
}

Monitor

 

Virustotal Monitor is designed to analyse goodware collections, helping antivirus companies and software developers with the early detection of false positives (mistakenly flagging legit files as malicious).

Software developers can upload their files to the service and they will be periodically scanned with the latest VirusTotal antivirus signature sets, notifying users in the event that any antivirus flags their files and keeping a historical record of all analyses performed on their software collection.

In order to simplify false positive management and allow fast remediation, Virustotal Monitor gives antivirus companies access to detected file metadata (file hash, file name and path, detection signature, and other user provided information).

For this purpose it is crucial that the user has an accurate and updated profile, as this information is going to be shared with the scanner companies if, and only if, files are detected. There is an API endpoint where the user can tweak their monitor preferences. This process can also be completed through the VirusTotal Monitor user interface:

Additionally you can use this example python script to upload your files, just provide a origin folder and a remote destination and will iterate over files in that directories and upload them to your monitor account. Use the "--help" parameter to obtain a list of upload modifiers.

Monitor Items

Details about objects stored in the VirusTotal Monitor service.

 

A MonitorItem object refers to a file or folder stored in VirusTotal Monitor and it is referenced via an ID. Using the right API calls it is not necessary to know how MonitorItem IDs are built, however, under certain circumstances you might find it easier to interact with the service by composing the IDs yourself.

A MonitorItem ID is made up of a base64 encoded string containing an utf8 formatted string following this pattern:

vtmonitor-v1://{owner_id}{path}

{owner_id} refers to the VirusTotal group your user belongs to and to whom the Monitor privilege was granted. This information can be retrieved using the GET /users/{id} endpoint with your user ID. The name of the group from which your user inherits its Monitor privileges will appear in the the inherited_from field of the monitor privilege.

{
  "type": "user",
  "id": "wcoyote",
  "links": {
    "self": "https://www.virustotal.com/api/v3/users/wcoyote"
  },
  "data": {
    "attributes": {
      "privileges": {
        "monitor": {
          "granted": true,
          "inherited_from": "acme"
        },
      }
    }  
  }
}

/items

Get a list of MonitorItem objects by path or tag

 
get/items
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

filter
string

Return the items matching the given criteria only

cursor
string

Continue listing after this offset

limit
int32

Maximum number of items to retrieve

Headers

x-apikey
string
required

Your API key

 

Items can be listed according to the parameters contained in filter:

  • path: folder (String: /myfolder/)
  • item: (MonitorItem ID describing a folder)
  • tag: (One or more space separated tags from the following list)
    • detected: files flagged by at least one antivirus engine.
    • new-detections: files that have been flagged by at least one antivirus engine and were previously undetected.
    • decreasing-detections: files flagged by at least one antivirus engine that have less detections with respect to their previous analysis.
    • increasing-detections: files flagged by at least one antivirus engine that have more detections with respect to their pervious analysis.
    • solved-detections: files that are no longer detected by any antivirus engine and were previously detected.
    • swapped-detections: files that are detected by the same number of antivirus engines as their previous analysis but either the set of engines detecting the file or their detection labels have changed.
    • [engine_name]: files detected by the given antivirus engine.

Here you can see some examples for the most common operations:

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor/items"
querystring = {"filter": "tag:detected"}

response = session.get(url, params=querystring)
print(response.text)
import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor/items"
querystring = {"filter": "tag:<av-name>"}

response = session.get(url, params=querystring)
print(response.text)
import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor/items"
querystring = {"filter": "path:/"}

response = session.get(url, params=querystring)
print(response.text)
import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor/items"
querystring = {"filter": "tag:new-detections"}

response = session.get(url, params=querystring)
print(response.text)
{
  "data": [
    {
      "type": "monitor_item", 
      "id": "{id}", 
      "attributes": {
        "size": 2981888, 
        "sha1": "521a85a43fc8ccbe3409e39bd8ef7719c6d747d5", 
        "first_detection_date": 1510080120, 
        "tags": [
          "detected", 
          "{engine name 1}", 
          "{engine name 2}"
        ], 
        "last_analysis_date": 1517234132, 
        "creation_date": 1510079766, 
        "item_type": "file", 
        "creator_id": "fsantos", 
        "last_analysis_results": {
          "{engine name 1}": {
            "category": "undetected", 
            "engine_name": "[{engine name 1}", 
            "engine_version": "1.3.0.9466", 
            "result": null, 
            "method": "blacklist", 
            "engine_update": "20180129"
          },
          "{engine name 2}": { 
            ... 
          }
        }, 
        "details": "This is a windows go executable file", 
        "path": "/go1.7.4_pkg_tool_windows_386/addr2line.exe", 
        "sha256": "e9a08208ade9afb630f3bad01461b552086fc675e547214c73ac966aa7806847", 
        "last_detections_count": 2, 
        "md5": "a17b39a3a280c48a6b8b4b0b7982606c"
      },
    }
  ]
}

/items

Upload a file or create a new folder

 
post/items
curl --request POST \
  --url https://www.virustotal.com/api/v3/monitor/items \
  --header 'x-apikey: <your API key>' \
  --form path='/' \
  --form file=@/path/to/file
A binary file was returned

You couldn't be authenticated

Try the API to see results

Body Params

file
file
required

Encoded file

path
string

A path relative to current monitor user root folder. In must include the filename at the end of the path or a / if it's a folder being created

item
string

A Monitor ID describing group and path

Headers

x-apikey
string
required

Your API key

 

This endpoint can be used to create or overwrite an already existing file using a multipart/form-data encoded request. The file has to be smaller than 32MB, for bigger files use a URL returned by /items/upload_url.

The parameter path indicates the path relative to your monitor root folder where the file is going to be stored. This path must include the name of the file being uploaded. For example /folder/myfile.exe. You can also provide a MonitorItemID representing a path to a file previously uploaded to VT Monitor and this will upload the new file to this path, overwriting the file referenced by the MonitorItemID.

To create a new folder just make a request with the desired path or item ending it with a slash (/), for example /mynewfolder/.

The MonitorItemID returned in the response can be used at a later stage to operate with the given file or folder and request its analysis information.

{
 "data": {
  "type": "monitor_item", 
  "id": "[MONITOR-ID]"
 }
}

/items/upload_url

Get a URL for uploading files larger than 32MB

 
get/items/upload_url
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items/upload_url \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Headers

x-apikey
string
required

Your API key

 

For uploading files smaller than 32MB you can simply send a POST request to the /items endpoint, but for larger files you need to get a special upload URL first. This endpoint returns one of those URLs. The returned URL can be used as a drop-in replacement for the /items endpoint. A new upload URL should be generated each big file upload.

{
  "data": "http://www.virustotal.com/_ah/upload/AMmfu6b-_DXUeFe36Sb3b0F4B8mH9Nb-CHbRoUNVOPwG/"
}

/items/{id}

Retrieve attributes and metadata for a specific MonitorItem.

 
get/items/id
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items/{id} \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Headers

x-apikey
string
required

Your API key

 
{
 "data": {
  "attributes": {
   "size": 8538624, 
   "sha1": "a9e2e47fd90b3552a072af482289532e878472fa", 
   "first_detection_date": 1502393426, 
   "next_analysis_date": 1504559882, 
   "last_analysis_date": 1504473518, 
   "tags": [
    "detected", 
    "new-detections", 
    "[ENGINE-NAME]"
   ], 
   "creation_date": 1501700980, 
   "item_type": "file", 
   "creator_id": "fsantos", 
   "last_analysis_results": {
    "[ENGINE-NAME]": {
     "category": "undetected", 
     "engine_name": "[ENGINE-NAME]", 
     "engine_version": "9.950.0.1006", 
     "result": null, 
     "method": "blacklist", 
     "engine_update": "20170903"
    }, 
    "[ENGINE-NAME]": {
     "category": "undetected", 
     "engine_name": "[ENGINE-NAME]", 
     "engine_version": "25.0.0.1", 
     "result": null, 
     "method": "blacklist", 
     "engine_update": "20170901"
    }
   }, 
   "path": "/go/bin/go.exe", 
   "sha256": "4db14737445edd2078a383520fabfd212f0979a31d0165dceac9f741fb1ab985", 
   "last_detections_count": 1, 
   "first_detection_date": 1504300116, 
   "md5": "3f389f88d18ba26e946a05883ea04130"
  }, 
  "type": "monitoritem", 
  "id": "[MONITOR-ID]"
 }
}

/items/{id}

Delete a VirusTotal Monitor file or folder.

 
delete/items/id
curl --request DELETE \
  --url https://www.virustotal.com/api/v3/monitor/items/{id} \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Headers

x-apikey
string
required

Your API key

 

/items/{id}/config

Configure a given VirusTotal Monitor item (file or folder).

 
patch/items/id/config
curl --request PATCH \
  --url https://www.virustotal.com/api/v3/monitor/items/{id}/config \
  --data="{'data': {\
        'id': <item-id>,\
        'type': 'monitoritem',\
        'attributes': {\
            'details': 'This is file metadata.'\
       }}}"
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Body Params

data
json
required

MonitorItem obj

Headers

x-apikey
string
required

Your API key

 

Is possible to set some file information/metadata into a MonitorItem by setting its details attribute, this information will be shared with Monitor Partners and should be used to give more context to them about the file in case of false positive. Folders does not support details.

import requests

item_id = '<item-id>'

url = "https://www.virustotal.com/api/v3/monitor/items/%s/config" % item_id
data = {'data': {
        'id': item_id,
        'type': 'monitoritem',
        'attributes': {
            'details': 'This is file metadata.'
       },
    }}

response = requests.request("PATCH", url, data=json.dumps(data))
print(response.text)
{
 "data": {
  "attributes": {
   "size": 49676, 
   "sha1": "892392d4f28b2dbe8ae45115a38c079dbcb14e18", 
   "first_detection_date": 1504175079, 
   "sha256": "cb9f9c1b271daa19fc78138dfd9d37686b1edb35e381f205c0b59911d8a004e1", 
   "next_analysis_date": 1504781041, 
   "last_detections_count": 1, 
   "last_analysis_date": 1504694733, 
   "tags": [
    "detected", 
    "visible", 
    "[ENGINE-NAME]"
   ], 
   "creation_date": 1504174971, 
   "item_type": "file", 
   "creator_id": "fsantos", 
   "last_analysis_results": {
    "[ENGINE-NAME]": {
     "category": "undetected", 
     "engine_name": "[ENGINE-NAME]", 
     "engine_version": "1.3.0.9330", 
     "result": null, 
     "method": "blacklist", 
     "engine_update": "20170906"
    },...
   }, 
   "details": "This is the metadata.", 
   "path": "/test/tac.exe", 
   "md5": "02c526e8efd42a1f57a75aa203cfb27f"
  }, 
  "type": "monitoritem", 
  "id": "[MONITOR-ID]"
 }
}

/items/{id}/download

Download a file in VirusTotal Monitor

 
get/items/id/download
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items/{id}/download \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Headers

x-apikey
string
required

Your API key

 

This handler allows you to download a file already uploaded to Virustotal Monitor.

/items/{id}/download_url

Retrieve a URL for downloading a file in VirusTotal Monitor

 
get/items/id/download_url
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items/{id}/download_url \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Headers

x-apikey
string
required

Your API key

 

This endpoint returns a signed URL from where you can download the specified file from VirusTotal Monitor. The URL expires after 1 hour.

/items/{id}/analyses

Retrieve latest file analyses

 
get/items/id/analyses
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items/{id}/analyses \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Query Params

cursor
string

Continue listing after this offset

limit
string

Maximum number of analyses to retrieve

Headers

x-apikey
string
required

Your API key

 

Retrieve item analyses, use cursor and limit to retrieve older ones.

{
  "data": [
    {
      "id": "d917dd47406322341cef40cf38091292962ba81d42983456aae4dc4f7967afb1-1517474700",
      "type": "monitor_analysis",
      "attributes": {
        "analysis_results": {
          "{engine name}": {
            "category": "undetected",
            "engine_name": "{engine name}",
            "engine_update": "20180201",
            "engine_version": "1.1.1.3",
            "method": "blacklist",
            "result": null
          }
        },
        "date": 1517474787,
        "detections_count": 1,
        "sha256": "d917dd47406322341cef40cf38091292962ba81d42983456aae4dc4f7967afb1",
        "tags": [
          "detected",
          "{engine name}"
        ]
      }
    }
  ]
}

/items/{id}/owner

Retrieve latest file analyses

 
get/items/id/owner
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items/{id}/owner \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Headers

x-apikey
string
required

Your API key

 

Retrieve item analyses, use cursor and limit to retrieve older ones.

{"data": [
  {
   "attributes": {
    "analysis_results": {
     "[ENGINE-NAME]": {
      "category": "undetected",
      "engine_name": "[ENGINE-NAME]",
      "engine_update": "20180129",
      "engine_version": "1.1.1.3",
      "method": "blacklist",
      "result": null
     },
     "[ENGINE-NAME]": {
      "category": "undetected",
      "engine_name": "[ENGINE-NAME]",
      "engine_update": "20180130",
      "engine_version": "17.9.3761.0",
      "method": "blacklist",
      "result": null
     }...
    },
    "date": 1517308584,
    "detections_count": 0,
    "sha256": "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2",
    "tags": []
   },
   "id": "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2-1517308500",
   "type": "monitor_analysis"
  }...
 ]
}

/items/{id}/comments

Retrieve partner's comments on a file

 
get/items/id/comments
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/items/{id}/comments \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Monitor item identifier

Query Params

cursor
string

Continue listing after this offset

limit
string

Maximum number of analyses to retrieve

Headers

x-apikey
string
required

Your API key

 
{
  "data": [
    {
      "type": "monitor_hash_comment",
      "id": "6620bdb508ab363eee95fd511ae88e2e38daf948b117bd49bcf8609f87cc86de-{engine name}",
      "attributes": {
        "comment": "This is an example comment.",
        "date": 1519222846,
        "detection": "confirmed",
        "engine": "{engine name}",
        "sha256": "6620bdb508ab363eee95fd511ae88e2e38daf948b117bd49bcf8609f87cc86de"
      }
    }
  ]
}

/statistics

Retrieve statistics about analyses performed on your software collection.

 
get/statistics
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor/statistics \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

cursor
string

List after this date

limit
string

Maximum number of statistic periods to return

Headers

x-apikey
string
required

Your API key

 

This endpoint returns information about your stored files, including quota consumption, detected files, top signatures, offending engines and oldest detections pending remediation.

A dictionary with data and meta properties is received, each data attributes will reflect past days statistics and meta realtime will reflect current detection counts. Data attributes also contains information about last day consumed storage (for realtime quota consumption user data should be check /ui/signin).

{"data": [
 {
  "attributes": {
  "date": 1517270400,
  "items_detected_count": 28,
  "increasing_detections_count": 6,
  "owner_id": "monitor_group",
  "period": "day",
  "storage_bytes_count": 166709820,
  "storage_files_count": 34,
  "top_age_items": [
   {
   "age": 7621121,
   "detections_count": 46,
   "monitor_key": "[MONITOR-ID]",
   "total_engines_count": 71
   }...
  ],
  "top_detected_items": [
   {
   "detections_count": 47,
   "monitor_key": "[MONITOR-ID]",
   "total_engines_count": 71
   }...
  ],
  "top_engines": [
   {
   "count": 20,
   "engine": "[ENGINE-NAME]"
   }...
  ],
  "top_signatures": [
   {
   "count": 20,
   "signature": "Unsafe"
   }...
  ]
  },
  "id": "monitor_group-day-2018-01-30",
  "type": "monitor_statistics"
 }...
 ],
 "meta": {
 "realtime": {
  "decreasing_detections_count": 0,
  "increasing_detections_count": 6,
  "items_detected_count": 28,
  "new_detections_count": 0,
  "solved_detections_count": 0,
  "swapped_detections_count": 0
 }
 }
}

Monitor Partner

 

VirusTotal Monitor Partner's aim is to ease false positive handling by antivirus companies. It is designed to provide VirusTotal participating AV scanners with hashes, file content, metadata and ownership information for any detection of a file in a Monitor collection. Note that files will only be shared upon a false positive.

As stated in VirusTotal Monitor overview software developers having an account in Monitor can upload their goodware collection to be periodically analysed by participating antivirus scanners. Note that these accounts are handed over to users once VirusTotal staff verifies and identifies them. Any of the hashes detected by your engine will be available in the Monitor Partner webapp or via the API calls documented bellow.

A common flow is described below:

  • A Monitor account is handed over to a user.
  • Users upload some files and make some comments on them in the details metadata section.
  • At some point in time or just after being uploaded a file is detected by your engine.
  • A new hash appears in the /hashes endpoint or in the website Analyses tab.
  • You request items to get files with that particular hash from any user collection, a hash could appear in different collections with different details. This situation (one hash/many files) may happen for example because sometimes software developers include certain versions of operating system files with their binaries, so one owner may be the operating system developer and the rest some other software developers. The details about each item owner can be obtained requesting the Monitor API endpoint.
  • You can also request hash analyses to get hash historic scanning information.
  • Once a false positive is confirmed your engine signatures may be updated and in the next cycle and the hash will disappear from the Analyses.
  • Alternatively, you can confirm that the detection is correct and hide it from your analyses posting
    a comment over it. You can always access these hashes filtering with ignored tag over hashes and revert this action.

For your convenience we generate a daily CSV formatted file with company name, hash and url with your detections. A new bundle is available each day at 1am UTC.
Additionally you can use this example python script to generate a similar report for your account at the current time, it will download all related hash files and its metadata storing it on your filesystem in json format.

You can also access information about your engine detections and collection size in daily statistics.

Here are some Monitor Partner website captures:

/hashes

Get a list of MonitorHashes detected by an engine

 
get/hashes
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/hashes \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

filter
string

Retrive hashes matching this condition, refer to the right block of the documentation

cursor
string

Continue listing after this offset

limit
int32

Maximum number of items to retrieve (max: 40)

Headers

x-apikey
string
required

Your API key

 

In some cases your user may have access to analyses of more than one engine, in this case you can provide a filter query with one engine name. To retrieve your preconfigured engine names you need to access the preferences/monitor_partner/engines property calling /groups/{group_id}, in case you do not know your monitor_partner group_id, it can be obtained from privileges/monitor-partner/inherited_from property calling /users/{your_user_id}.

To display the latest hash analyses for a specific engine use the filter parameter with the modifier:

  • engine: (String: <engine-name>)

To display ignored hashes (detection confirmed ones /hashes/{sha256}/comments):

  • tag:ignored

Here you can see an example:

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/hashes"
querystring = {"filter": "engine:<engine-name>"}

response = session.get(url, params=querystring)
print(response.text)
{
 "data": [
  {
   "attributes": {
    "last_analysis_date": 1517433370,
    "last_analysis_results": {
     "[ENGINE-NAME]": {
      "category": "undetected",
      "engine_name": "[ENGINE-NAME]",
      "engine_update": "20180131",
      "engine_version": "1.1.1.3",
      "method": "blacklist",
      "result": null
     }...
    },
    "last_detections_count": 1,
    "md5": "432fb4158186f0c8268813741939239a",
    "sha1": "6d06bba4f7625409e8a2f7e201c38b1b5925609a",
    "sha256": "29037cca6156dbf44a80a0c785f2b9d5c205cecd3bf7b044d99b462149bc5ae8",
    "size": 16384
   },
   "id": "29037cca6156dbf44a80a0c785f2b9d5c205cecd3bf7b044d99b462149bc5ae8",
   "type": "monitor_hash"
  }...
 ]
}

/hashes/{sha256}/analyses

Get a list of analyses for a given sha256 hash

 
get/hashes/sha256/analyses
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/hashes/{sha256}/analyses \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

sha256
string
required

Hash sha256

Query Params

cursor
string

Continue listing after this offset

limit
string

Maximum number of items to retrieve (max: 40)

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to retrieve all analyses performed on a certain sha256 hash using cursored listings.

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/hashes/<sha256>/analyses"
response = session.get(url)
print(response.text)
{
  "data": [
    {
      "id": "d917dd47406322341cef40cf38091292962ba81d42983456aae4dc4f7967afb1-1517474700",
      "type": "monitor_analysis",
      "attributes": {
        "analysis_results": {
          "{engine name}": {
            "category": "undetected",
            "engine_name": "{engine name}",
            "engine_update": "20180201",
            "engine_version": "1.1.1.3",
            "method": "blacklist",
            "result": null
          }
        },
        "date": 1517474787,
        "detections_count": 1,
        "sha256": "d917dd47406322341cef40cf38091292962ba81d42983456aae4dc4f7967afb1",
        "tags": [
          "detected",
          "{engine name}"
        ]
      }
    }
  ]
}

/hashes/{sha256}/items

Get a list of items with a given sha256 hash

 
get/hashes/sha256/items
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/hashes/{sha256}/items \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

sha256
string
required

Hash sha256

Query Params

cursor
string

Continue listing after this offset

limit
string

Maximum number of items to retrieve (max: 40)

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to retrieve file paths, descriptions, etc. for all files in monitor with a certain sha256 hash.

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/hashes/<sha256>/items"
response = session.get(url)
print(response.text)
{
 "data": [
  {
   "attributes": {
    "creation_date": 1517387994,
    "details": "Original filename: \"shvlres.dll\"",
    "first_detection_date": 1517388090,
    "last_analysis_date": 1517474787,
    "last_analysis_results": {
     "[ENGINE-NAME]": {
      "category": "undetected",
      "engine_name": "[ENGINE-NAME]",
      "engine_update": "20180201",
      "engine_version": "1.1.1.3",
      "method": "blacklist",
      "result": null
     }...
    },
    "last_detections_count": 1,
    "md5": "1d5544d6ca1ac6674e9ea11d4b947c35",
    "path": "shvlres.dll",
    "sha1": "9024e1b34143321f4fb6ea717cde48a293bf99e0",
    "sha256": "d917dd47406322341cef40cf38091292962ba81d42983456aae4dc4f7967afb1",
    "size": 2178131
   },
   "id": "[MONITOR-ID]",
   "type": "monitor_item"
  }
 ]}
}

/hashes/{sha256}/comments

Create a comment and if necessary confirm detection over a hash

 
post/hashes/sha256/comments
curl --request POST \
  --url https://www.virustotal.com/api/v3/monitor_partner/hashes/{sha256}/comments \
  --header 'x-apikey: <your API key>' \
  --data-binary "{'data': [{'attributes': {\
                      'comment': '[TEXT]',\
                      'detection': 'confirmed',\
                      'engine': '[ENGINE-ID]',\
                      'sha256': '[HASH-SHA256]'},\
                    'type': 'monitor_hash_comment'}]}"
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

sha256
string
required

Hash sha256

Body Params

data
json

A json object with a MonitorHashComment

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to create a comment over certain hash, this comment may be visible to other partners (for example if they also detect the hash) and to monitor users who have a file with this hash.
A MonitorHashComment also have a detection attribute that could be set to 'confirmed' to ignore this particular hash from that moment on. Once the hash comment is marked as confirmed any new monitor analysis for this file that your engine will detect will not be shown anymore when requesting latests analyses. This behabiour can be reverted deleting the comment or updating it with detection attribute set to None.
Ignored hashes with detections still can be retrieved using /hashes endpoint with a filter "tag:ignored"

import requests

sha256 = '<hash-sha256>'
engine = '<your-engine-id>'

url = "https://www.virustotal.com/api/v3/monitor_partner/hashes/%s/comments" % sha256
data = {'data': [{'attributes': {
          'comment': '[TEXT]',
          'detection': 'confirmed',
          'engine': engine,
          'sha256': sha256},
        'type': 'monitor_hash_comment'}]}

response = requests.request("POST", url, data=json.dumps(data))
print(response.text)
{
  'data': [
    {
      'type': 'monitor_hash_comment',
      'id': '{id}',
      'attributes': {
        'comment': '{text}',
        'detection': 'confirmed',
        'engine': '{engine name}',
        'sha256': '{sha256}'
      }
    }
  ]
}

/comments/{id}

Retrieve comment data

 
get/comments/id
curl --method GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/comments/{id}/ \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Comment ID

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to retrieve partner comments over a certain sha256 hash.

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/comments/<comment-id>/"
response = session.get(url)
print(response.text)
{
  'data': [
    {
      'type': 'monitor_hash_comment',
      'id': '{id}',
      'attributes': {
        'comment': '{text}',
        'detection': 'confirmed',
        'engine': '{engine name}',
        'sha256': '{sha256}'
      }
    }
  ]
}

/comments/{id}

Create a comment and if necessary confirm detection over a hash

 
patch/comments/id
curl --request PATCH \
  --url https://www.virustotal.com/api/v3/monitor_partner/comments/{id} \
  --header 'x-apikey: <your API key>' \
  --data-binary "{'data': [{'attributes': {\
                      'comment': '[TEXT]',\
                      'detection': 'confirmed',\
                      'engine': '[ENGINE-ID]',\
                      'sha256': '[HASH-SHA256]'},\
                    'type': 'monitor_hash_comment'}]}"
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Comment identifier

Body Params

data
json

A json object with a MonitorHashComment

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to update a comment and change detection if necessary. More information about detection attribute could be found in /hashes/{sha256}/comments.

import requests

comment_id = '<comment-id>'

url = "https://www.virustotal.com/api/v3/monitor_partner/comments/{comment_id}" % comment_id
data = {'data': [{'attributes': {
          'comment': '[TEXT]',
          'detection': 'confirmed',
          'engine': '[ENGINE]',
          'sha256': '[HASH-SHA256]},
        'id': comment_id,
        'type': 'monitor_hash_comment'}]}

response = requests.request("POST", url, data=json.dumps(data))
print(response.text)
{'data': [
  {'attributes': {
     'comment': '[TEXT]',
     'detection': 'confirmed',
     'engine': '[ENGINE-ID]',
     'sha256': '[HASH-SHA256]'
   },
   'id': '[MONITOR-COMMENT-ID]',
   'type': 'monitor_hash_comment'
  }]}

/comments/{id}

Remove a comment and reset confirmed detection for a hash.

 
delete/comments/id
curl --request DELETE \
  --url https://www.virustotal.com/api/v3/monitor_partner/comments/{id} \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

id
string
required

Comment identifier

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to delete a comment and change detection to None so hash will appear over analysis listings if detected. More information about detection attribute could be found in /hashes/{sha256}/comments.

import requests

comment_id = '<comment-id>'

url = "https://www.virustotal.com/api/v3/monitor_partner/comments/{comment_id}" % comment_id

response = requests.request("DELETE", url)
print(response.text)

/files/{sha256}/download

Download a file with a given sha256 hash

 
get/files/sha256/download
curl --method GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/files/{sha256}/download \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

sha256
string
required

Hash sha256

Query Params

cursor
string

Continue listing after this offset

limit
int32

Maximum number of items to retrieve (max: 40)

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to download a file by sha256 hash.

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/files/{sha256}/download"
response = session.get(url)
print(response.text)

/files/{sha256}/download_url

Retrieve a download url for a file with a given sha256 hash

 
get/files/sha256/download_url
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/files/{sha256}/download_url \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

sha256
string
required

Hash sha256

Query Params

cursor
string

Continue listing after this offset

limit
int32

Maximum number of items to retrieve (max: 40)

Headers

x-apikey
string
required

Your API key

 

This endpoint allows you to get a download url for a file with a given sha256 hash. These URLs are ephemeral and have a one hour expiration date.

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/files/{sha256}/download_url"
response = session.get(url)
print(response.text)

/detections_bundle/download

Download a daily detection bundle

 
get/detections_bundle/download
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/detections_bundle/download \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

sha256
string
required

Hash sha256

Query Params

cursor
string

Continue listing after this offset

limit
string

Maximum number of items to retrieve (max: 40)

Headers

x-apikey
string
required

Your API key

 

Each day a CSV formated list with hash detections is generated for each engine. Each line contains an owner company, hash, analysis history link and a hash download url.
If your account is set up for more than one engine you should access each engine bundle pointing to /api/v3/monitor/detections_bundle/{engine}/download
To download previous bundles you can use: /api/v3/monitor/detections_bundle/{engine}/{date('%Y-%m-%d')}/download

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/detections_bundle/download"
response = session.get(url)
print(response.text)

/detections_bundle/download_url

Get daily detection bundle URL

 
get/detections_bundle/download_url
curl --request GET \
  --url https://www.virustotal.com/api/v3/monitor_partner/detections_bundle/download_url \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

sha256
string
required

Hash sha256

Query Params

cursor
string

Continue listing after this offset

limit
string

Maximum number of items to retrieve (max: 40)

Headers

x-apikey
string
required

Your API key

 

Refer to /detections_bundle/download for additional options.

import requests

session = requests.Session()
session.headers = {'X-Apikey': '<api-key>'}

url = "https://www.virustotal.com/api/v3/monitor_partner/detections_bundle/download_url"
response = session.get(url)
print(response.text)

/statistics

Get a list of MonitorHashes detected by an engine

 
get/statistics
curl --request GET \
  --url "https://www.virustotal.com/api/v3/monitor_partner/statistics" \
  --header 'x-apikey: <your API key>'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

cursor
string

List after this date

limit
string

Maximum number of statistic periods to return

filter
string

Filter parameters

Headers

x-apikey
string
required

Your API key

 

Statistics provide information about hashes detected and total hashes analyzed by your engine. In case you have more than one engine you can use filter=engine:<engine-name>

{
  "data": [
    {
      "attributes": {
        "date": 1517356800,
        "engine": "[ENGINE-NAME]",
        "hashes_count": 1840,
        "hashes_detected_count": 34,
        "items_count": 1840,
        "items_detected_count": 34,
        "period": "day"
      },
      "id": "[ENGINE-NAME]-day-2018-01-31",
      "links": {
        "self": "https://www.virustotal.com/api/v3/monitor_partner/statistics/[ENGINE-NAME]-day-2018-01-31"
      },
      "type": "monitor_partner_statistics"
    }...
  ]
}