This is a Next.js example application demonstrating file upload with malware scanning using the attachmentAV API. It showcases how to integrate real-time virus scanning into your web application to protect users from malicious files.
┌─────────────────┐
│ User Browser │
└────────┬────────┘
│
│ POST /upload (single file)
│ POST /multiupload (multiple files)
▼
┌─────────────────┐
│ Next.js App │
│ (API Routes) │
└────────┬────────┘
│
│ POST /v1/scan/sync/binary
│ (max 3 concurrent for multiupload)
▼
┌─────────────────┐
│ attachmentAV │
│ API │
└─────────────────┘
- Node.js 18+ installed
- An attachmentAV API key (get one at https://attachmentav.com)
# Install dependencies
npm install
# or
yarn install
# or
pnpm installCreate a .env.local file in the root directory and add your attachmentAV API key:
ATTACHMENTAV_API_KEY=your_api_key_herenpm run dev
# or
yarn dev
# or
pnpm devOpen http://localhost:3000 in your browser. You should see two file upload forms:
Single File Upload:
- Select a file from your computer
- Click "Upload File"
- View the scan results (clean or infected)
Multi File Upload:
- Select multiple files from your computer
- Click "Upload Files"
- View the scan results for all files (scanned with max 3 concurrent requests)
The frontend is a React component that provides two file upload interfaces:
- File Selection: Uses an HTML file input to let users select one file
- Form Submission: Creates a
FormDataobject containing the file - API Call: Sends a POST request to
/uploadwith the file data - Result Display: Shows success/error messages based on the scan results
- File Selection: Uses an HTML file input with
multipleattribute to let users select multiple files - Form Submission: Creates a
FormDataobject containing all selected files - API Call: Sends a POST request to
/multiuploadwith all files - Result Display: Shows aggregated results for all files with individual status per file
Key features:
- Two side-by-side upload forms (responsive design)
- Disables forms during upload to prevent multiple submissions
- Displays the selected filename(s) and count
- Shows color-coded success (green) or error (red) messages
- Displays detailed scan results for each file in multi-upload
- Automatically resets forms after successful upload
The API route handles the server-side logic for single file malware scanning:
- Receive File: Extracts the file from the incoming FormData request
- Convert to Buffer: Converts the file to an ArrayBuffer for transmission
- Submit to attachmentAV:
- Sends the binary data to the attachmentAV API endpoint
- Includes the API key in the
x-api-keyheader - Sets
Content-Type: application/octet-streamfor binary data
- Process Results: Analyzes the scan response:
status: 'infected'→ Returns 400 error with malware detailsstatus: 'no'→ Logs warning (file couldn't be scanned)status: 'clean'→ Returns success response
- Return Response: Sends the scan results back to the frontend
The multi-upload API route handles parallel scanning of multiple files with concurrency control:
- Receive Files: Extracts all files from the incoming FormData using
formData.getAll('file') - Initialize Concurrency Limiter: Uses
p-limitwithMAX_CONCURRENT_REQUESTS = 3to limit parallel scans - Parallel Scanning:
- Maps each file to a scan promise wrapped with the limiter
- Ensures only 3 files are scanned simultaneously
- Queues remaining files until a slot becomes available
- Individual File Processing: For each file:
- Converts to ArrayBuffer
- Submits to attachmentAV API
- Captures scan results or errors
- Aggregate Results: Collects all scan results and checks for:
- Infected files → Returns 400 error with details
- Scan failures → Returns 500 error with details
- All clean → Returns 200 success with all results
- Return Response: Sends comprehensive results for all files back to the frontend
Key features:
- Concurrency Control: Uses
p-limitto prevent overwhelming the API - Individual Error Handling: Each file scan is isolated; one failure doesn't stop others
- Detailed Results: Returns status for every file in the batch
- Configurable Limit:
MAX_CONCURRENT_REQUESTSconstant for easy adjustment
- API key is stored in environment variables (never exposed to the client)
- File validation on both client and server
- Synchronous scanning ensures malware is detected before the file is processed
- Error handling for API failures and network issues
The application uses the synchronous binary scan endpoint:
- Endpoint:
https://eu.developer.attachmentav.com/v1/scan/sync/binary - Method: POST
- Authentication: API key via
x-api-keyheader - Content: Raw binary file data
The API returns a JSON response with:
{
"status": "clean" | "infected" | "no",
// Additional scan metadata
}.
├── app/
│ ├── page.tsx # Frontend with single and multi-file upload forms
│ ├── upload/
│ │ └── route.ts # Backend API route for single file scanning
│ ├── multiupload/
│ │ └── route.ts # Backend API route for multi-file scanning (max 3 concurrent)
│ └── ...
├── .env.local # Environment variables (create this)
└── package.json
The easiest way to deploy your Next.js app is to use the Vercel Platform.
Remember to add your ATTACHMENTAV_API_KEY environment variable in the Vercel project settings.

