API (SaaS): API Definition
| Action | HTTP Method | HTTP Resource / Path |
|---|---|---|
| Scan URL and return scan result | POST | /v1/scan/sync/download |
| Scan file and return scan result | POST | /v1/scan/sync/binary |
| Scan file and return scan result | POST | /v1/scan/sync/form |
| Scan S3 object and return scan result | POST | /v1/scan/sync/s3 |
| Scan URL and invoke callback with scan result | POST | /v1/scan/async/download |
| Scan S3 object and invoke callback with scan result | POST | /v1/scan/async/s3 |
| Test authentication | GET | /v1/test |
| Get information about yourself | GET | /v1/whoami |
Authentication (#)
Accessing the API requires an active subscription and API key. Pass the API key via a x-api-key HTTP header.
Actions (#)
POST /v1/scan/sync/download (#)
Download a file from a remote location (HTTP/HTTPS), scan the file, and return the scan result.
Maximum file size is 200 MB. The request timeout is 60 seconds.
The request body is JSON formatted with these properties:
download_url(string): URL to download and scan via HTTP(S) GET.download_headers: (object, optional): Headers to send when downloading the file.
The response status code is 200, and the body is JSON formatted with these properties:
status(string (clean,infected,no)): The scan result.finding(string, optional): For infected files, the type of virus/malware that was detected.size(number, optional): The file size in bytes.realfiletype(string, optional): The Real File Type detected by the Sophos engine.
Example:
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
curl \
-X POST \
-H 'x-api-key: <API_KEY_PLACEHOLDER>' \
-H 'Content-Type: application/json' \
-d '{"download_url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"}' \
'https://eu.developer.attachmentav.com/v1/scan/sync/download'
{"status":"clean","size":2903045,"realfiletype":"Adobe Portable Document Format (PDF)"}
Find the latest version of the virus-scan-sdk on Maven Central and add it to the dependencies of your project.
<dependency>
<groupId>com.attachmentav</groupId>
<artifactId>virus-scan-sdk</artifactId>
<version>0.4.0</version>
</dependency>
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import com.attachmentav.api.AttachmentAvApi;
import com.attachmentav.client.ApiClient;
import com.attachmentav.client.ApiException;
import com.attachmentav.client.Configuration;
import com.attachmentav.model.ScanResult;
import com.attachmentav.model.SyncDownloadScanRequest;
// ...
ApiClient client = Configuration.getDefaultApiClient();
client.setApiKey("<API_KEY_PLACEHOLDER>");
AttachmentAvApi api = new AttachmentAvApi();
SyncDownloadScanRequest request = new SyncDownloadScanRequest();
request.setDownloadUrl("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf");
ScanResult result = api.scanSyncDownloadPost(request);
System.out.println("Scan Result: " + result.getStatus());
Source: GitHub
Find the latest version of the attachmentav-virus-malware-scan-sdk on PyPI and add it to the dependencies of your project.
pip install attachmentav-virus-malware-scan-sdk
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import attachmentav
configuration = attachmentav.Configuration()
configuration.api_key['apiKeyAuth'] = "<API_KEY_PLACEHOLDER>"
with attachmentav.ApiClient(configuration) as api_client:
api_instance = attachmentav.AttachmentAVApi(api_client)
sync_download_scan_request = attachmentav.SyncDownloadScanRequest(
download_url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
)
scan_result = api_instance.scan_sync_download_post(sync_download_scan_request)
print(scan_result)
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
ESM
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const scanResult = await api.scanSyncDownloadPost({
syncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
}
});
console.log('Sync download scan result:', scanResult);
Source: GitHub
CommonJs
const { AttachmentAVApi, Configuration } = require('@attachmentav/virus-scan-sdk-ts');
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
api.scanSyncDownloadPost({
syncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
}
}).then(scanResult => {
console.log('Sync download scan result:', scanResult);
});
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const scanResult = await api.scanSyncDownloadPost({
syncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
}
});
console.log('Sync download scan result:', scanResult);
Source: GitHub
POST /v1/scan/sync/binary (#)
Upload a file, scan the file, and return the scan result.
Maximum file size is 10 MB. The request timeout is 60 seconds.
The request body contains the binary data (application/octet-stream).
The response status code is 200, and the body is JSON formatted with these properties:
status(string (clean,infected,no)): The scan result.finding(string, optional): For infected files, the type of virus/malware that was detected.size(number, optional): The file size in bytes.realfiletype(string, optional): The Real File Type detected by the Sophos engine.
Example:
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
curl \
-X POST \
-H 'x-api-key: <API_KEY_PLACEHOLDER>' \
-H 'Content-Type: application/octet-stream' \
-d '@path/to/file' \
https://eu.developer.attachmentav.com/v1/scan/sync/binary
{"status":"clean","size":73928372,"realfiletype":"Adobe Portable Document Format (PDF)"}
Find the latest version of the virus-scan-sdk on Maven Central and add it to the dependencies of your project.
<dependency>
<groupId>com.attachmentav</groupId>
<artifactId>virus-scan-sdk</artifactId>
<version>0.4.0</version>
</dependency>
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import com.attachmentav.api.AttachmentAvApi;
import com.attachmentav.client.ApiClient;
import com.attachmentav.client.ApiException;
import com.attachmentav.client.Configuration;
import com.attachmentav.model.ScanResult;
import java.io.File;
// ...
ApiClient client = Configuration.getDefaultApiClient();
client.setApiKey("<API_KEY_PLACEHOLDER>");
AttachmentAvApi api = new AttachmentAvApi();
ScanResult result = api.scanSyncBinaryPost(new File("/path/to/file"));
System.out.println("Scan Result: " + result.getStatus());
Source: GitHub
Find the latest version of the attachmentav-virus-malware-scan-sdk on PyPI and add it to the dependencies of your project.
pip install attachmentav-virus-malware-scan-sdk
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import attachmentav
configuration = attachmentav.Configuration()
configuration.api_key['apiKeyAuth'] = "<API_KEY_PLACEHOLDER>"
with attachmentav.ApiClient(configuration) as api_client:
api_instance = attachmentav.AttachmentAVApi(api_client)
with open("/path/to/file", "rb") as file:
file_content = file.read()
scan_result = api_instance.scan_sync_binary_post(file_content)
print(scan_result)
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
ESM
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
import { readFileSync } from 'node:fs';
import { Blob } from 'node:buffer';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const scanResult = await api.scanSyncBinaryPost({
body: new Blob([readFileSync('/path/to/file')])
});
console.log('Sync binary scan result:', scanResult);
Source: GitHub
CommonJs
const { AttachmentAVApi, Configuration } = require('@attachmentav/virus-scan-sdk-ts');
const { readFileSync } = require('node:fs');
const { Blob } = require('node:buffer');
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
api.scanSyncBinaryPost({
body: new Blob([readFileSync('/path/to/file')])
}).then(scanResult => {
console.log('Sync binary scan result:', scanResult);
});
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
import { readFileSync } from 'node:fs';
import { Blob } from 'node:buffer';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const scanResult = await api.scanSyncBinaryPost({
body: new Blob([readFileSync('/path/to/file')])
});
console.log('Sync binary scan result:', scanResult);
Source: GitHub
POST /v1/scan/sync/form (#)
Upload a file, scan the file, and return the scan result.
Maximum file size is 10 MB. The request timeout is 60 seconds.
The request body is multipart/form-data formatted and contains one file.
The response status code is 200, and the body is JSON formatted with these properties:
status(string (clean,infected,no)): The scan result.finding(string, optional): For infected files, the type of virus/malware that was detected.size(number, optional): The file size in bytes.realfiletype(string, optional): The Real File Type detected by the Sophos engine.
Example:
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
curl \
-H 'x-api-key: <API_KEY_PLACEHOLDER>' \
-F file=@path/to/file \
https://eu.developer.attachmentav.com/v1/scan/sync/form
{"status":"clean","size":73928372,"realfiletype":"Adobe Portable Document Format (PDF)"}
POST /v1/scan/sync/s3 (#)
Download a file from S3, scan the file, and return the scan result.
A bucket policy is required to grant attachmentAV access to the S3 objects.
Maximum file size is 200 MB. The request timeout is 60 seconds.
The request body is JSON formatted with these properties:
bucket(string): The bucket name.key(string): The object key.version(string, optional): If versioning is turned on, the object version.
The response status code is 200, and the body is JSON formatted with these properties:
status(string (clean,infected,no)): The scan result.finding(string, optional): For infected files, the type of virus/malware that was detected.size(number, optional): The file size in bytes.realfiletype(string, optional): The Real File Type detected by the Sophos engine.
Example:
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
curl \
-X POST \
-H 'x-api-key: <API_KEY_PLACEHOLDER>' \
-H 'Content-Type: application/json' \
-d '{"bucket": "your-bucket", "key": "path/to/file.pdf"}' \
'https://eu.developer.attachmentav.com/v1/scan/sync/s3'
{"status":"clean","size":105255200,"realfiletype":"Adobe Portable Document Format (PDF)"}
Find the latest version of the virus-scan-sdk on Maven Central and add it to the dependencies of your project.
<dependency>
<groupId>com.attachmentav</groupId>
<artifactId>virus-scan-sdk</artifactId>
<version>0.4.0</version>
</dependency>
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import com.attachmentav.api.AttachmentAvApi;
import com.attachmentav.client.ApiClient;
import com.attachmentav.client.ApiException;
import com.attachmentav.client.Configuration;
import com.attachmentav.model.ScanResult;
import com.attachmentav.model.SyncS3ScanRequest;
// ...
ApiClient client = Configuration.getDefaultApiClient();
client.setApiKey("<API_KEY_PLACEHOLDER>");
AttachmentAvApi api = new AttachmentAvApi();
SyncS3ScanRequest request = new SyncS3ScanRequest();
request.setBucket("<BUCKET_NAME_PLACEHOLDER>");
request.setKey("<OBJECT_KEY_PLACEHOLDER>");
//request.setVersion("<OBJECT_VERSION_PLACEHOLDER>"); // for versioned buckets only
ScanResult result = api.scanSyncS3Post(request);
System.out.println("Scan Result: " + result.getStatus());n
Source: GitHub
Find the latest version of the attachmentav-virus-malware-scan-sdk on PyPI and add it to the dependencies of your project.
pip install attachmentav-virus-malware-scan-sdk
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import attachmentav
configuration = attachmentav.Configuration()
configuration.api_key['apiKeyAuth'] = "<API_KEY_PLACEHOLDER>"
with attachmentav.ApiClient(configuration) as api_client:
api_instance = attachmentav.AttachmentAVApi(api_client)
sync_s3_scan_request = attachmentav.SyncS3ScanRequest(
bucket = "<BUCKET_NAME_PLACEHOLDER>",
key = "<OBJECT_KEY_PLACEHOLDER>"
)
scan_result = api_instance.scan_sync_s3_post(sync_s3_scan_request)
print(scan_result)
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
ESM
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const scanResult = await api.scanSyncS3Post({
syncS3ScanRequest: {
bucket: '<BUCKET_NAME_PLACEHOLDER>',
key: '<OBJECT_KEY_PLACEHOLDER>'
}
});
console.log('Sync S3 scan result:', scanResult);
Source: GitHub
CommonJs
const { AttachmentAVApi, Configuration } = require('@attachmentav/virus-scan-sdk-ts');
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
api.scanSyncS3Post({
syncS3ScanRequest: {
bucket: '<BUCKET_NAME_PLACEHOLDER>',
key: '<OBJECT_KEY_PLACEHOLDER>'
}
}).then(scanResult => {
console.log('Sync S3 scan result:', scanResult);
});
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const scanResult = await api.scanSyncS3Post({
syncS3ScanRequest: {
bucket: '<BUCKET_NAME_PLACEHOLDER>',
key: '<OBJECT_KEY_PLACEHOLDER>'
}
});
console.log('Sync S3 scan result:', scanResult);
Source: GitHub
POST /v1/scan/async/download (#)
Download a file from a remote location (HTTP/HTTPS), scan the file, and send the scan result.
Maximum file size is 5 GB. The request timeout is 29 seconds, the asynchronous scan job is not affected by this limit.
The request body is JSON formatted with these properties:
download_url(string): URL to download and scan via HTTP(S) GET.download_headers: (object, optional): Headers to send when downloading the file.callback_url(string): URL to receive the scan result via HTTPS POST (see Callback).callback_headers: (object, optional): Headers to send when invoking the callback. The headersContent-TypeandContent-Lengthare always added and can not be changed.trace_id(string, optional): ID allowing you to trace the scan request with a custom ID.custom_data(string, optional): Custom data that attachmentAV passes through-maximum of 16 KB in UTF-8.
The response status code is 204.
Example:
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
curl \
-vvv \
-X POST \
-H 'x-api-key: <API_KEY_PLACEHOLDER>' \
-H 'Content-Type: application/json' \
-d '{"download_url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", "callback_url": "https://api.yourcompany.com/attachmentav/callback"}' \
'https://eu.developer.attachmentav.com/v1/scan/async/download'
The scan result is send to your callback via an HTTPS POST request to your callback_url.
Find the latest version of the virus-scan-sdk on Maven Central and add it to the dependencies of your project.
<dependency>
<groupId>com.attachmentav</groupId>
<artifactId>virus-scan-sdk</artifactId>
<version>0.4.0</version>
</dependency>
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
package com.attachmentav.api.examples;
import com.attachmentav.api.AttachmentAvApi;
import com.attachmentav.client.ApiClient;
import com.attachmentav.client.ApiException;
import com.attachmentav.client.Configuration;
import com.attachmentav.model.AsyncDownloadScanRequest;
// ...
ApiClient client = Configuration.getDefaultApiClient();
client.setApiKey("<API_KEY_PLACEHOLDER>");
AttachmentAvApi api = new AttachmentAvApi();
AsyncDownloadScanRequest request = new AsyncDownloadScanRequest();
request.setCallbackUrl("https://api.yourcompany.com/attachmentav/callback");
request.setDownloadUrl("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf");
api.scanAsyncDownloadPost(request);
The scan result is send to your callback via an HTTPS POST request to your CallbackUrl.
Source: GitHub
Find the latest version of the attachmentav-virus-malware-scan-sdk on PyPI and add it to the dependencies of your project.
pip install attachmentav-virus-malware-scan-sdk
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
import attachmentav
configuration = attachmentav.Configuration()
configuration.api_key['apiKeyAuth'] = "<API_KEY_PLACEHOLDER>"
with attachmentav.ApiClient(configuration) as api_client:
api_instance = attachmentav.AttachmentAVApi(api_client)
async_download_scan_request = attachmentav.AsyncDownloadScanRequest(
download_url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
callback_url = "https://api.yourcompany.com/attachmentav/callback"
)
api_instance.scan_async_download_post(async_download_scan_request)
The scan result is send to your callback via an HTTPS POST request to your callback_url.
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
ESM
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
await api.scanAsyncDownloadPost({
asyncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
callbackUrl: 'https://api.yourcompany.com/attachmentav/callback'
}
});
console.log('Async download submitted');
The scan result is send to your callback via an HTTPS POST request to your callbackUrl.
Source: GitHub
CommonJs
const { AttachmentAVApi, Configuration } = require('@attachmentav/virus-scan-sdk-ts');
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
api.scanAsyncDownloadPost({
asyncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
callbackUrl: 'https://api.yourcompany.com/attachmentav/callback'
}
}).then(() => {
console.log('Async download submitted');
});
The scan result is send to your callback via an HTTPS POST request to your callbackUrl.
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
await api.scanAsyncDownloadPost({
asyncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
callbackUrl: 'https://api.yourcompany.com/attachmentav/callback'
}
});
console.log('Async download submitted');
The scan result is send to your callback via an HTTPS POST request to your callbackUrl.
Source: GitHub
POST /v1/scan/async/s3 (#)
Download a file from S3, scan the file, and send the scan result.
A bucket policy is required to grant attachmentAV access to the S3 objects.
Maximum file size is 5 GB. The request timeout is 29 seconds, the asynchronous scan job is not affected by this limit.
The request body is JSON formatted with these properties:
bucket(string): The bucket name.key(string): The object key.version(string, optional): If versioning is turned on, the object version.callback_url(string): URL to receive the scan result via HTTPS POST (see Callback).callback_headers: (object, optional): Headers to send when invoking the callback. The headersContent-TypeandContent-Lengthare always added and can not be changed.trace_id(string, optional): ID allowing you to trace the scan request with a custom ID.custom_data(string, optional): Custom data that attachmentAV passes through-maximum of 16 KB in UTF-8.
The response status code is 204.
Example:
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
curl \
-vvv \
-X POST \
-H 'x-api-key: <API_KEY_PLACEHOLDER>' \
-H 'Content-Type: application/json' \
-d '{"bucket": "your-bucket", "key": "path/to/file.pdf", "callback_url": "https://api.yourcompany.com/attachmentav/callback"}' \
'https://eu.developer.attachmentav.com/v1/scan/async/s3'
The scan result is send to your callback via an HTTPS POST request to your callback_url.
Find the latest version of the virus-scan-sdk on Maven Central and add it to the dependencies of your project.
<dependency>
<groupId>com.attachmentav</groupId>
<artifactId>virus-scan-sdk</artifactId>
<version>0.4.0</version>
</dependency>
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
import com.attachmentav.api.AttachmentAvApi;
import com.attachmentav.client.ApiClient;
import com.attachmentav.client.ApiException;
import com.attachmentav.client.Configuration;
import com.attachmentav.model.AsyncS3ScanRequest;
// ...
ApiClient client = Configuration.getDefaultApiClient();
client.setApiKey("<API_KEY_PLACEHOLDER>");
AttachmentAvApi api = new AttachmentAvApi();
AsyncS3ScanRequest request = new AsyncS3ScanRequest();
request.setCallbackUrl("https://api.yourcompany.com/attachmentav/callback");
request.setBucket("<BUCKET_NAME_PLACEHOLDER>");
request.setKey("<OBJECT_KEY_PLACEHOLDER>");
//request.setVersion("<OBJECT_VERSION_PLACEHOLDER>"); // for versioned buckets only
api.scanAsyncS3Post(request);
System.out.println("Async S3 submitted");
The scan result is send to your callback via an HTTPS POST request to your CallbackUrl.
Source: GitHub
Find the latest version of the attachmentav-virus-malware-scan-sdk on PyPI and add it to the dependencies of your project.
pip install attachmentav-virus-malware-scan-sdk
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
import attachmentav
configuration = attachmentav.Configuration()
configuration.api_key['apiKeyAuth'] = "<API_KEY_PLACEHOLDER>"
with attachmentav.ApiClient(configuration) as api_client:
api_instance = attachmentav.AttachmentAVApi(api_client)
async_s3_scan_request = attachmentav.AsyncS3ScanRequest(
bucket = "<BUCKET_NAME_PLACEHOLDER>",
key = "<OBJECT_KEY_PLACEHOLDER>",
callback_url = "https://api.yourcompany.com/attachmentav/callback"
)
api_instance.scan_async_s3_post(async_s3_scan_request)
print("Async S3 submitted")
The scan result is send to your callback via an HTTPS POST request to your callback_url.
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
ESM
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
await api.scanAsyncS3Post({
asyncS3ScanRequest: {
bucket: '<BUCKET_NAME_PLACEHOLDER>',
key: '<OBJECT_KEY_PLACEHOLDER>',
callbackUrl: 'https://api.yourcompany.com/attachmentav/callback'
}
});
console.log('Async S3 submitted');
The scan result is send to your callback via an HTTPS POST request to your callback_url.
Source: GitHub
CommonJs
const { AttachmentAVApi, Configuration } = require('@attachmentav/virus-scan-sdk-ts');
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
api.scanAsyncS3Post({
asyncS3ScanRequest: {
bucket: '<BUCKET_NAME_PLACEHOLDER>',
key: '<OBJECT_KEY_PLACEHOLDER>',
callbackUrl: 'https://api.yourcompany.com/attachmentav/callback'
}
}).then(() => {
console.log('Async S3 submitted');
});
The scan result is send to your callback via an HTTPS POST request to your callback_url.
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace https://api.yourcompany.com/attachmentav/callback with your callback URL.
import { AttachmentAVApi, Configuration } from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
await api.scanAsyncS3Post({
asyncS3ScanRequest: {
bucket: '<BUCKET_NAME_PLACEHOLDER>',
key: '<OBJECT_KEY_PLACEHOLDER>',
callbackUrl: 'https://api.yourcompany.com/attachmentav/callback'
}
});
console.log('Async S3 submitted');
The scan result is send to your callback via an HTTPS POST request to your callback_url.
Source: GitHub
GET/v1/test (#)
Check if your API key is valid.
The response status code is 204.
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
curl \
-X GET \
-H 'x-api-key: xxx' \
'https://eu.developer.attachmentav.com/v1/test'
GET/v1/whoami (#)
Get information abour yourself.
The response status code is 200, and the body is JSON formatted with these properties:
tenantId(string): The tenant ID.
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
curl \
-X GET \
-H 'x-api-key: xxx' \
'https://eu.developer.attachmentav.com/v1/whoami'
{"tenantId":"f15gulb49i"}
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
ESM
import {AttachmentAVApi, Configuration} from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const res = await api.whoamiGet();
console.log('Who am I?', res);
Source: GitHub
CommonJs
const { AttachmentAVApi, Configuration } = require('@attachmentav/virus-scan-sdk-ts');
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
api.whoamiGet().then(res => {
console.log('Who am I?', res);
});
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
import {AttachmentAVApi, Configuration} from '@attachmentav/virus-scan-sdk-ts';
const config = new Configuration({
apiKey: '<API_KEY_PLACEHOLDER>'
});
const api = new AttachmentAVApi(config);
const res = await api.whoamiGet();
console.log('Who am I?', res);
Source: GitHub
Callback (#)
The callback URL is called by attachmentAV via an HTTPS POST request with a JSON payload with this properties:
status(string (clean,infected,no)): The scan result.finding(string, optional): For infected files, the type of virus/malware that was detected.size(number): The file size in bytes.download_time(number): Time to download the file in seconds.scan_time(number): Time to scan the file in seconds.download_url(string): The downloaded URL.trace_id(string, optional): ID to trace custom scan jobs.custom_data(string, optional): Custom data defined when submitting a custom scan job.realfiletype(string, optional): The Real File Type detected by the Sophos engine.
For security reasons, we recommend verifying callbacks to ensure that the callback was made by attachmentAV.
Verify (#)
attachmentAV signs callback invocations by adding the following headers to callback invocations:
X-Signature: RSA-SHA25 signature hex encoded.X-Timestamp: Unix time in milliseconds.
To verify the signature:
- Get public key from attachmentAV.
- Parse public key.
- Construct verification string:
${timestamp}.${tenantId}.${callbackUrl}.${body}.- Replace
${timestamp}with theX-Timestampheader value. - Replace
${tenantId}with your tenant ID. Get your tenant ID from GET /v1/whoami. - Replace
${callbackUrl}with the value you used forcallback_urlwhen sending the scan job. - Replace
${body}with the raw callback body.
- Replace
- Initialize RSA-SHA256 verifier with public key.
- Verify that the verification string produces the same signature as the
X-Signatureheader value. - Validate the timestamp is within an acceptable window (we recommend ± 5 minutes) to prevent replay attacks.
The following snippets implement the logic described above.
Find the latest version of the virus-scan-sdk on Maven Central and add it to the dependencies of your project.
<dependency>
<groupId>com.attachmentav</groupId>
<artifactId>virus-scan-sdk</artifactId>
<version>0.4.0</version>
</dependency>
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key.
package com.attachmentav;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.security.KeyFactory;
import java.nio.charset.StandardCharsets;
import javax.xml.bind.DatatypeConverter;
public class CallbackSignatureX509 {
private static final long SIGNATURE_TOLERANCE_IN_MILLIS = 5 * 60 * 1000; // 5 minutes
/**
* Verifies the signature of a callback.
*
* @param unixtimeInMillis Current unixtime in milliseconds (System.currentTimeMillis())
* @param publicKeyPEM The public key in PEM X509 format (available at https://attachmentav.com/help/virus-malware-scan-api/developer/publickey.html)
* @param timestamp The value of the X-Timestamp header of the callback
* @param tenantId Your tenant ID (get your tenant ID from https://attachmentav.com/help/virus-malware-scan-api/developer/definition.html#action-whoami)
* @param callbackUrl The callback URL used when submitting the scan job
* @param body The body of the callback
* @param signature The value of the X-Signature header of the callback
* @return true if the callback is valid
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
* @throws SignatureException
*/
static boolean verify(final long unixtimeInMillis, final String publicKeyPEM, final String timestamp, final String tenantId, final String callbackUrl, final String body, final String signature) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
final Signature verifier = Signature.getInstance("SHA256withRSA");
final PublicKey pubKey = parsePublicKey(publicKeyPEM);
verifier.initVerify(pubKey);
final String dataToVerify = timestamp + "." + tenantId + "." + callbackUrl + "." + body;
verifier.update(dataToVerify.getBytes(StandardCharsets.UTF_8));
final byte[] signatureBytes = DatatypeConverter.parseHexBinary(signature);
final boolean valid = verifier.verify(signatureBytes);
final boolean withinTolerance = Math.abs(unixtimeInMillis - Long.parseLong(timestamp)) <= SIGNATURE_TOLERANCE_IN_MILLIS;
return valid && withinTolerance;
}
private static PublicKey parsePublicKey(final String publicKeyPEM) throws NoSuchAlgorithmException, InvalidKeySpecException {
final String cleanKey = publicKeyPEM
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s", "");
final byte[] keyBytes = DatatypeConverter.parseBase64Binary(cleanKey);
final X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(spec);
}
}
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace <CALLBACK_URL_PLACEHOLDER> as described in the code.
ESM
import {createPublicKey, createVerify} from 'node:crypto';
const SIGNATURE_TOLERANCE_IN_MILLIS = 5 * 60 * 1000;
/**
* Verifies the signature of a callback.
*
* @param {number} unixtimeInMillis - Current unixtime in milliseconds (Date.now())
* @param {string} publicKeyPEM - The public key in PEM PKCS1 format (available at https://attachmentav.com/help/virus-malware-scan-api/developer/publickey.html)
* @param {string} timestamp - The value of the X-Timestamp header of the callback
* @param {string} tenantId - Your tenant ID (get your tenant ID from https://attachmentav.com/help/virus-malware-scan-api/developer/definition.html#action-whoami)
* @param {string} callbackUrl - The callback URL used when submitting the scan job
* @param {string} body - The body of the callback
* @param {string} signature - The value of the X-Signature header of the callback
* @return {boolean} - true if the callback is valid
*/
function verify(unixtimeInMillis, publicKeyPEM, timestamp, tenantId, callbackUrl, body, signature) {
const publicKey = createPublicKey({
key: publicKeyPEM,
format: 'pem',
type: 'pkcs1'
});
const verify = createVerify('sha256');
verify.update(timestamp);
verify.update('.');
verify.update(tenantId);
verify.update('.');
verify.update(callbackUrl);
verify.update('.');
verify.update(body);
verify.end();
const valid = verify.verify(publicKey, signature, 'hex');
return valid && Math.abs(unixtimeInMillis-parseInt(timestamp, 10)) <= SIGNATURE_TOLERANCE_IN_MILLIS;
}
Usage example:
import {AttachmentAVApi, Configuration} from '@attachmentav/virus-scan-sdk-ts';
import {createServer} from 'node:http';
const API_KEY = '<API_KEY_PLACEHOLDER>';
// To make your server runmning on localhost accessible from the Internet, we recommend to use ngrok.
// 1. Install and configure it as described here: https://ngrok.com/docs/getting-started
// 2. In your terminal, run:
// ngrok http 8081
// 3. Insert the ngrok URL (e.g. https://42d3a8497f95.ngrok-free.app) below:
const CALLBACK_URL = '<CALLBACK_URL_PLACEHOLDER>';
const PUBLIC_KEY_PEM = `-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAyLoZzjo1cQV9ZN2TH/alrxWiQ3u/ndT0HMrLMdBTVO3Tz1nUjLt6
SqKZsN8dQhvPoEjfyhCTEg7MPWopG3n0cf3NRxtoeXy/Z62b1zdUd426kMuKOQP8
Yy6cxa/RtK2tkHCnTGxjfvNmMK+m68sFmsilR88LnIN71my4cG8bIDGDftWublvK
AEOWhxSECYn1XEtyrQL5lm8HFnHdE9ys56xTJkdr5Mmkvanrnd/hXzTHzjruGcLv
bjciI82+Z335AzYgJcnmH4/zsBuyPL2FJSfQF9NsPaTJuQgkw1usAKBQcujcEriY
UDNWgTe1a+LOnCEMb+9mAYw8lMRYRd3CBwIDAQAB
-----END RSA PUBLIC KEY-----`;
const config = new Configuration({
apiKey: API_KEY
});
const api = new AttachmentAVApi(config);
const {tenantId: TENANT_ID} = await api.whoamiGet(); // the tenantId never changes. we recommend to hard code it to avoid yet another HTTPS call.
//const TENANT_ID = '<TENANT_ID_PLACEHOLDER>';
const server = createServer((req, res) => {
const chunks = [];
req.on('data', (chunk) => {
chunks.push(chunk);
});
req.on('end', () => {
const body = Buffer.concat(chunks).toString();
if (verify(Date.now(), PUBLIC_KEY_PEM, req.headers['x-timestamp'], TENANT_ID, CALLBACK_URL, body, req.headers['x-signature'])) {
res.writeHead(204);
res.end();
console.log('Received valid callback', body);
} else {
res.writeHead(403);
res.end();
console.error('Received invalid callback', body);
}
server.close();
});
});
server.listen(8081);
await api.scanAsyncDownloadPost({
asyncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
callbackUrl: CALLBACK_URL
}
});
console.log('Async download submitted');
Source: GitHub
CommonJs
Source: GitHub
Find the latest version of the virus-scan-sdk-ts on npm and add it to the dependencies of your project.
npm i @attachmentav/virus-scan-sdk-ts
An active subscription and API key is required. Replace <API_KEY_PLACEHOLDER> with your API key. Replace <CALLBACK_URL_PLACEHOLDER> as described in the code.
import {createPublicKey, createVerify} from 'node:crypto';
const SIGNATURE_TOLERANCE_IN_MILLIS = 5 * 60 * 1000;
/**
* Verifies the signature of a callback.
*
* @param {number} unixtimeInMillis - Current unixtime in milliseconds (Date.now())
* @param {string} publicKeyPEM - The public key in PEM PKCS1 format (available at https://attachmentav.com/help/virus-malware-scan-api/developer/publickey.html)
* @param {string} timestamp - The value of the X-Timestamp header of the callback
* @param {string} tenantId - Your tenant ID (get your tenant ID from https://attachmentav.com/help/virus-malware-scan-api/developer/definition.html#action-whoami)
* @param {string} callbackUrl - The callback URL used when submitting the scan job
* @param {string} body - The body of the callback
* @param {string} signature - The value of the X-Signature header of the callback
* @return {boolean} - true if the callback is valid
*/
function verify(unixtimeInMillis, publicKeyPEM, timestamp, tenantId, callbackUrl, body, signature) {
const publicKey = createPublicKey({
key: publicKeyPEM,
format: 'pem',
type: 'pkcs1'
});
const verify = createVerify('sha256');
verify.update(timestamp);
verify.update('.');
verify.update(tenantId);
verify.update('.');
verify.update(callbackUrl);
verify.update('.');
verify.update(body);
verify.end();
const valid = verify.verify(publicKey, signature, 'hex');
return valid && Math.abs(unixtimeInMillis-parseInt(timestamp, 10)) <= SIGNATURE_TOLERANCE_IN_MILLIS;
}
Usage example:
import {AttachmentAVApi, Configuration} from '@attachmentav/virus-scan-sdk-ts';
import {createServer} from 'node:http';
const API_KEY = '<API_KEY_PLACEHOLDER>';
// To make your server runmning on localhost accessible from the Internet, we recommend to use ngrok.
// 1. Install and configure it as described here: https://ngrok.com/docs/getting-started
// 2. In your terminal, run:
// ngrok http 8081
// 3. Insert the ngrok URL (e.g. https://42d3a8497f95.ngrok-free.app) below:
const CALLBACK_URL = '<CALLBACK_URL_PLACEHOLDER>';
const PUBLIC_KEY_PEM = `-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAyLoZzjo1cQV9ZN2TH/alrxWiQ3u/ndT0HMrLMdBTVO3Tz1nUjLt6
SqKZsN8dQhvPoEjfyhCTEg7MPWopG3n0cf3NRxtoeXy/Z62b1zdUd426kMuKOQP8
Yy6cxa/RtK2tkHCnTGxjfvNmMK+m68sFmsilR88LnIN71my4cG8bIDGDftWublvK
AEOWhxSECYn1XEtyrQL5lm8HFnHdE9ys56xTJkdr5Mmkvanrnd/hXzTHzjruGcLv
bjciI82+Z335AzYgJcnmH4/zsBuyPL2FJSfQF9NsPaTJuQgkw1usAKBQcujcEriY
UDNWgTe1a+LOnCEMb+9mAYw8lMRYRd3CBwIDAQAB
-----END RSA PUBLIC KEY-----`;
const config = new Configuration({
apiKey: API_KEY
});
const api = new AttachmentAVApi(config);
const {tenantId: TENANT_ID} = await api.whoamiGet(); // the tenantId never changes. we recommend to hard code it to avoid yet another HTTPS call.
//const TENANT_ID = '<TENANT_ID_PLACEHOLDER>';
const server = createServer((req, res) => {
const chunks: Buffer[] = [];
req.on('data', (chunk) => {
chunks.push(chunk);
});
req.on('end', () => {
const body = Buffer.concat(chunks).toString();
if (verify(Date.now(), PUBLIC_KEY_PEM, req.headers['x-timestamp'], TENANT_ID, CALLBACK_URL, body, req.headers['x-signature'])) {
res.writeHead(204);
res.end();
console.log('Received valid callback', body);
} else {
res.writeHead(403);
res.end();
console.error('Received invalid callback', body);
}
server.close();
});
});
server.listen(8081);
await api.scanAsyncDownloadPost({
asyncDownloadScanRequest: {
downloadUrl: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
callbackUrl: CALLBACK_URL
}
});
console.log('Async download submitted');
Source: GitHub
S3 Bucket Policy (#)
In case you want to use POST /api/v1/scan/async/s3 or POST /api/v1/scan/sync/s3 it is neccessary to grant attachmentAV access to download the object from S3. Therefore, you need to attach the following bucket policy. Ensure to replace BUCKET_NAME with the name of the bucket.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "attachmentAV",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::450892694845:root"
},
"Action": "s3:GetObject*",
"Resource": "arn:aws:s3:::BUCKET_NAME/*"
}]
}
Please note, attachmentAV does not support scanning S3 objects encrypted with KMS.