NAV
shell python java go

Introduction

INLYSE API for all malware classification services. It serves as the central access point for all requests to the backend services. It has several functions that should make the API much more stable. For this purpose a Job and Worker pool was implemented to scale and stabilize the service more easily.

Features

Getting started

Dependencies

cURL
import requests
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.12</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.5.12</version>
</dependency>
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.text.MessageFormat;
import(
    "bytes"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "mime/multipart"
    "net/http"
    "os"
)

To use the provided code, you need to have the following imports/dependencies for the language you are using.

Rate Limits

Request

curl -v --stderr - https://malware.ai/api/stats --header "Authorization: Bearer {api-key}" | grep "x-ratelimit"
key = "{api-key}"

header = {"Authorization": "Bearer {key}".format(key=key)}
response = requests.get("https://www.malware.ai/api/stats", headers=header)
if response.ok:
    print("X-Ratelimit-Limit:", response.headers["X-Ratelimit-Limit"])
    print("X-Ratelimit-Remaining", response.headers["X-Ratelimit-Remaining"])
    print("X-Ratelimit-Reset", response.headers["X-Ratelimit-Reset"])
else:
    response.raise_for_status()
String key = "{api-key}";
CloseableHttpClient httpclient = HttpClients.createDefault();

HttpGet get_request = new HttpGet("https://www.malware.ai/api/stats");
get_request.addHeader("Authorization", MessageFormat.format("Bearer {0}", key));

HttpResponse response = httpclient.execute(get_request);

System.out.println(Arrays.toString(response.getHeaders("X-Ratelimit-Limit")));
System.out.println(Arrays.toString(response.getHeaders("X-Ratelimit-Remaining")));
System.out.println(Arrays.toString(response.getHeaders("X-Ratelimit-Reset")));
var key = "{api-key}"
request, err := http.NewRequest("GET", "https://www.malware.ai/api/stats", nil)
if err != nil {
    log.Fatalln(err)
}
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key))

client := &http.Client{}
response, err := client.Do(request)
if err != nil {
    log.Fatalln(err)
}

fmt.Println(fmt.Sprintf("X-Ratelimit-Limit: %s", response.Header.Get("X-Ratelimit-Limit")))
fmt.Println(fmt.Sprintf("X-Ratelimit-Remaining: %s", response.Header.Get("X-Ratelimit-Remaining")))
fmt.Println(fmt.Sprintf("X-Ratelimit-Reset: %s", response.Header.Get("X-Ratelimit-Reset")))

Console output (the format can change a little depending on what language you are using)

X-Ratelimit-Limit: int
X-Ratelimit-Remaining: int
X-Ratelimit-Reset: DateTime

The API has rate limits that cannot be exceeded.

x-ratelimit-limit describes how many requests you can make in total
x-ratelimit-remainingdescribes how many requests are remaining
x-ratelimit-reset describes when the rate limit gets reset

You can check your rate limits like this

If the code does not compile, make sure you installed/imported all the dependencies

Endpoints Overview

Documentation

Ping /ping

Request

curl -s https://www.malware.ai/ping
response = requests.get("https://www.malware.ai/ping")
if response.ok:
    print(response.text)
else:
    response.raise_for_status()
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get_request = new HttpGet("https://www.malware.ai/ping");
ResponseHandler<String> responseHandler = response -> {
    int status = response.getStatusLine().getStatusCode();
    if (status >= 200 && status < 300) {
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
    } else {
        throw new ClientProtocolException("Unexpected response status: " + status);
    }
};
String responseBody = httpclient.execute(get_request, responseHandler);
System.out.println(responseBody);
resp, err := http.Get("https://www.malware.ai/ping")
if err != nil{
    log.Fatalln(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil{
    log.Fatalln(err)
}
log.Println(string(body))

Response

PONG

Service still alive?

This is an extra endpoint for the sole purpose of expressing its availability

If the code does not compile, make sure you installed/imported all the dependencies

Stats /api/stats

Request

curl -s https://malware.ai/api/stats --header "Authorization: Bearer {api-key}"
key = "{api-key}"

header = {"Authorization": "Bearer {key}".format(key=key)}
response = requests.get("https://www.malware.ai/api/stats", headers=header)
if response.ok:
    print(response.text)
else:
    response.raise_for_status()
String key = "{api-key}";

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get_request = new HttpGet("https://www.malware.ai/api/stats");
get_request.addHeader("Authorization", MessageFormat.format("Bearer {0}", key));

ResponseHandler<String> responseHandler =
    response -> {
      int status = response.getStatusLine().getStatusCode();
      if (status >= 200 && status < 300) {
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
      } else {
        throw new ClientProtocolException("Unexpected response status: " + status);
      }
    };

String responseBody = httpclient.execute(get_request, responseHandler);

System.out.println(responseBody);
var key = "{api-key}"

request, err := http.NewRequest("GET", "https://www.malware.ai/api/stats", nil)
if err != nil {
    log.Fatalln(err)
}
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key))

client := &http.Client{}
response, err := client.Do(request)
if err != nil {
    log.Fatalln(err)
}

responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(responseData))

Response

{
   "AnalysedFiles": "int",
   "Traffic": "int"
}

User statistics

Returns user statistics. How many files and how much traffic has already been analyzed

If the code does not compile, make sure you installed/imported all the dependencies

Scan File /api/files/

Request

curl -s -F 'file=@{absolute_path_to_file}' https://malware.ai/api/files/ --header "Authorization: Bearer {api-key}"
key = "{api-key}"
path = "{absolute_path_to_file}"

header = {"Authorization": "Bearer {key}".format(key=key)}
files = {"file": open("{path}".format(path=path), "br",)}
response = requests.post(
    "https://www.malware.ai/api/files/", files=files, headers=header
)
if response.ok:
    print(response.text)
else:
    response.raise_for_status()
String path = "{absolute_path_to_file}";
String key = "{api-key}";

File file = new File(path);

MultipartEntityBuilder builder =
    MultipartEntityBuilder.create()
        .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
        .addBinaryBody("file", file, ContentType.DEFAULT_BINARY, "filename");

CloseableHttpClient httpclient = HttpClients.createDefault();

HttpPost post_request = new HttpPost("https://www.malware.ai/api/files/");
post_request.addHeader("Authorization", MessageFormat.format("Bearer {0}", key));

ResponseHandler<String> responseHandler =
    response -> {
      int status = response.getStatusLine().getStatusCode();
      if (status >= 200 && status < 300) {
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
      } else {
        throw new ClientProtocolException("Unexpected response status: " + status);
      }
    };

post_request.setEntity(builder.build());

String responseBody = httpclient.execute(post_request, responseHandler);

System.out.println(responseBody);
var path = "{absolute_path_to_file}"
var key = "{api-key}"

file, err := os.Open(path)
if err != nil {
    log.Fatalln(err)
}
defer file.Close()

var requestBody bytes.Buffer

multiPartWriter := multipart.NewWriter(&requestBody)
fileWriter, err := multiPartWriter.CreateFormFile("file", "filename")
if err != nil {
    log.Fatalln(err)
}

_, err = io.Copy(fileWriter, file)

multiPartWriter.Close()

request, err := http.NewRequest("POST", "https://www.malware.ai/api/files/", &requestBody)
if err != nil {
    log.Fatalln(err)
}
request.Header.Set("Content-Type", multiPartWriter.FormDataContentType())
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key))

client := &http.Client{}
response, err := client.Do(request)
if err != nil {
    log.Fatalln(err)
}

responseData,err := ioutil.ReadAll(response.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(responseData))

Response

{
    "id":"492366f7-1806-4d33-a9bb-eac4ef2007ce"
}

Upload and scan a file

This endpoint allows you to upload a file for scanning. 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.

Restrictions

File size limit is 17MB File format has to be PDF or a ZIP with one PDF inside.

If the code does not compile, make sure you installed/imported all the dependencies

Scan File by URL /api/files/url

Request

curl -s -X POST https://malware.ai/api/files/url --header "Authorization: Bearer {api-key}"  --header 'Content-Type: application/json' -d '{"url":"{url}"}'
key = "{api-key}"
file_url = "{url}"

headers = {"Authorization": "Bearer {key}".format(key=key)}
data = {"url": file_url}
response = requests.post(
    "https://www.malware.ai/api/files/url", headers=headers, data=data
)
if response.ok:
    print(response.text)
else:
    response.raise_for_status()
String file_url = "{url}";
String key = "{api-key}";

List<NameValuePair> data = new ArrayList<>(0);
data.add(new BasicNameValuePair("url", file_url));

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost post_request = new HttpPost("https://www.malware.ai/api/files/url");
post_request.addHeader("Authorization", MessageFormat.format("Bearer {0}", key));

ResponseHandler<String> responseHandler =
    response -> {
      int status = response.getStatusLine().getStatusCode();
      if (status >= 200 && status < 300) {
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
      } else {
        throw new ClientProtocolException("Unexpected response status: " + status);
      }
    };

post_request.setEntity(new UrlEncodedFormEntity(data, "UTF-8"));

String responseBody = httpclient.execute(post_request, responseHandler);

System.out.println(responseBody);
var data = []byte(`{"url":"{url}"}`)
var key = "{api-key}"

request, err := http.NewRequest("POST", "https://www.malware.ai/api/files/url", bytes.NewBuffer(data))
if err != nil {
    log.Fatalln(err)
}
request.Header.Set("Content-Type", "application/json")
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key))

client := &http.Client{}
response, err := client.Do(request)
if err != nil {
    log.Fatalln(err)
}

responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(responseData))

Response

{
    "id":"492366f7-1806-4d33-a9bb-eac4ef2007ce"
}

Scan a file by URL

This endpoint allows you to submit a file for scanning, by uploading an url pointing to the file.

Restrictions

File size limit is 17MB File format has to be PDF or a ZIP with one PDF inside.

If the code does not compile, make sure you installed/imported all the dependencies

Retrieve Classification /api/analysis/:id

Request

curl -s https://malware.ai/api/analysis/{analysis_id} --header "Authorization: Bearer {api-key}"
a_id = "{analysis-id}"
key = "{api-key}"

header = {"Authorization": "Bearer {key}".format(key=key)}
response = requests.get(
    "https://www.malware.ai/api/analysis/{id}".format(id=a_id),
    headers=header,
)
if response.ok:
    print(response.text)
else:
    response.raise_for_status()
String id = "{analysis-id}";
String key = "{api-key}";

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get_request =
    new HttpGet(
        MessageFormat.format("https://www.malware.ai/api/analysis/{0}", id));
get_request.addHeader("Authorization", MessageFormat.format("Bearer {0}", key));

ResponseHandler<String> responseHandler =
    response -> {
      int status = response.getStatusLine().getStatusCode();
      if (status >= 200 && status < 300) {
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
      } else {
        throw new ClientProtocolException("Unexpected response status: " + status);
      }
    };

String responseBody = httpclient.execute(get_request, responseHandler);

System.out.println(responseBody);
var id = "{analysis-id}"
var key = "{api-key}"

request, err := http.NewRequest("GET", fmt.Sprintf("https://www.malware.ai/api/analysis/%s", id), nil)
if err != nil {
    log.Fatalln(err)
}
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key))

client := &http.Client{}
response, err := client.Do(request)
if err != nil {
    log.Fatalln(err)
}

responseData,err := ioutil.ReadAll(response.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(responseData))

Response normal

{
   "ID":"0b7d2cde-1d5f-4a59-961e-928569af46dd",
   "MD5":"d9583012ec400655dfda421c3ce6b225",
   "SHA1":"13e1b5be530c46f040e668d52d48e00ed2b9e986",
   "SHA256":"4bff806b8f05235cfca3e80ec19d271ebec33a1a8ece84c12a7ffd3a6348c3a7",
   "SHA512":"71c92e95a209a2aecb5f01f4a5ac2f396ab31199b2c932c688141db53dca122df1d9d20ae3c7951a6fea7c6a301fe9375105b0b5852f99ec5d2a71fc8a917861",
   "Filename":"file.pdf",
   "Size":174811,
   "FileType":"application/pdf",
   "Label":"benign"
}

Response extended

{
    "ID":"9d3db18f-c67a-428f-816b-8bf15a4344c6",
    "MD5":"5b8865422e95462ecb6cb23ba8597cc9",
    "SHA1":"5a105b34b1f1eabbc4b261477b60fa3b30408f54",
    "SHA256":"fc0dd80c491c2cd88f3bb863affa313f118c009640ecb8573a192117628e9b28",
    "SHA512":"f3827e583a3d882b5ad39b83dae879d1733836eb7dbb8fefdbfac932acd42fdd3655a0f216ef51c63450f65dd89955be521b32cc90e1b9fa0449e1f0770a622b",
    "Filename":"test.pdf",
    "Size":12344,
    "FileType":"application/pdf",
    "Label":"malicious",
    "ScoreBenign":"0.3390300050287237",
    "ScoreMalicious":"0.6609699949712763"
}

Retrieve file scan reports

Returns the data of the analysis depending on the API key. There are three different classes. Normal and Extended Keys. Extenden keys also return the benign and malicous Scores in addition to the normal information.

If the code does not compile, make sure you installed/imported all the dependencies

List Analysis /api/analysis?filter=all

Request

curl -s https://malware.ai/api/analysis?filter={search-filter} --header "Authorization: Bearer {api-key}"
key = "{api-key}"
s_filter = {"search-filter"}

header = {"Authorization": "Bearer {key}".format(key=key)}
response = requests.get(
    "https://www.malware.ai/api/analysis?filter={filter}".format(filter=s_filter),
    headers=header,
)
if response.ok:
    print(response.text)
else:
    response.raise_for_status()
String filter = "{search-filter}";
String key = "{api-key}";

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get_request =
    new HttpGet(MessageFormat.format("https://www.malware.ai/api/analysis?filter={0}", filter));
get_request.addHeader("Authorization", MessageFormat.format("Bearer {0}", key));

ResponseHandler<String> responseHandler =
    response -> {
      int status = response.getStatusLine().getStatusCode();
      if (status >= 200 && status < 300) {
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
      } else {
        throw new ClientProtocolException("Unexpected response status: " + status);
      }
    };

String responseBody = httpclient.execute(get_request, responseHandler);

System.out.println(responseBody);
var filter = "{search-filter}"
var key = "{api-key}"

request, err := http.NewRequest("GET", fmt.Sprintf("https://www.malware.ai/api/analysis?filter=%s", filter), nil)
if err != nil {
    log.Fatalln(err)
}
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", key))

client := &http.Client{}
response, err := client.Do(request)
if err != nil {
    log.Fatalln(err)
}

responseData,err := ioutil.ReadAll(response.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(responseData))

Response

["1c67bcf5-6458-43bb-a7a9-f8a0d4e86d30"]

Retrieve a list of submitted files

Returns a list with the last 1000 analyses. It is possible to specify a filter.

Possible Filters are: all, finished, unfinished, error

If the code does not compile, make sure you installed/imported all the dependencies

Errors

The API returns normal HTTP status codes to indicate if the request was successful or not.

Status Code Explanation
200 - OK successful request
201 - Created The analysis just started
202 - Accepted The analysis is still in progress
400 - Bad Request There was an error in the request (perhaps a missing parameter)
401 - Unauthorized The provided API-key is not valid (or missing)
404 - Not Found The requested API endpoint does not exist
500 - Internal Server Error Something went wrong and you should try to upload the file again