Code Examples
Working malware-scanning examples in 7 languages. Scan by file upload or URL. The API is a single REST endpoint — any language that can make an HTTP request will work.
Every field, status code and response shape is in the API reference.
curl
Terminal — the 30-second test
# 1. Submit a file (you get a ticket back instantly) curl -H "Authorization: Bearer $UPSCAN_KEY" \ -F file=@upload.pdf \ https://api.upscan.example/v1/scans # → { "id": "4821…", "status": "pending" } # 2. Collect the verdict a couple of seconds later curl -H "Authorization: Bearer $UPSCAN_KEY" \ https://api.upscan.example/v1/scans/4821… # → { "status": "done", "verdict": "clean", "sha256": "…" } # Or scan a URL instead of uploading: curl -H "Authorization: Bearer $UPSCAN_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://example.com/report.pdf"}' \ https://api.upscan.example/v1/scans
Node.js / TypeScript
Framework: Express · Client: built-in fetch (Node 18+)
import fs from "node:fs/promises"; const API = "https://api.upscan.example"; const KEY = process.env.UPSCAN_KEY; async function scanFile(path) { // 1. Submit const form = new FormData(); form.append("file", new Blob([await fs.readFile(path)]), path); const res = await fetch(`${API}/v1/scans`, { method: "POST", headers: { Authorization: `Bearer ${KEY}` }, body: form, }); const { id } = await res.json(); // 2. Poll until the verdict lands (or use webhook_url instead) while (true) { await new Promise((r) => setTimeout(r, 1500)); const scan = await (await fetch(`${API}/v1/scans/${id}`, { headers: { Authorization: `Bearer ${KEY}` }, })).json(); if (scan.status === "done" || scan.status === "error") return scan; } } const scan = await scanFile("upload.pdf"); if (scan.verdict === "infected") { console.log(`Blocked: ${scan.signature}`); // reject the upload }
Prefer push over polling? Add form.append("webhook_url", "https://yoursite.com/hooks/upscan") and we'll POST the verdict to you, signed with your webhook secret.
Python
Framework: Flask / Django · Client: requests
Install: pip install requests
import os, time, requests API = "https://api.upscan.example" HEADERS = {"Authorization": f"Bearer {os.environ['UPSCAN_KEY']}"} def scan_file(path): # 1. Submit with open(path, "rb") as f: r = requests.post(f"{API}/v1/scans", headers=HEADERS, files={"file": f}) scan_id = r.json()["id"] # 2. Poll until done (or pass webhook_url and skip this) while True: time.sleep(1.5) scan = requests.get(f"{API}/v1/scans/{scan_id}", headers=HEADERS).json() if scan["status"] in ("done", "error"): return scan scan = scan_file("upload.pdf") if scan["verdict"] == "infected": raise ValueError(f"Blocked: {scan['signature']}")
PHP
Framework: plain PHP / Laravel · Client: built-in cURL
<?php $api = "https://api.upscan.example"; $key = getenv("UPSCAN_KEY"); // 1. Submit $ch = curl_init("$api/v1/scans"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer $key"], CURLOPT_POSTFIELDS => ["file" => new CURLFile("upload.pdf")], ]); $scan = json_decode(curl_exec($ch), true); // 2. Poll until the verdict lands do { usleep(1500000); $ch = curl_init("$api/v1/scans/{$scan['id']}"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer $key"], ]); $scan = json_decode(curl_exec($ch), true); } while (!in_array($scan["status"], ["done", "error"])); if ($scan["verdict"] === "infected") { http_response_code(422); exit("Blocked: {$scan['signature']}"); }
Ruby
Framework: Rails / Sinatra · Client: net/http (stdlib)
require "net/http" require "json" API = URI("https://api.upscan.example") KEY = ENV.fetch("UPSCAN_KEY") def scan_file(path) # 1. Submit req = Net::HTTP::Post.new("#{API}/v1/scans") req["Authorization"] = "Bearer #{KEY}" req.set_form([["file", File.open(path)]], "multipart/form-data") scan = JSON.parse(Net::HTTP.start(API.host, API.port, use_ssl: true) { |h| h.request(req) }.body) # 2. Poll until done loop do sleep 1.5 res = Net::HTTP.get(URI("#{API}/v1/scans/#{scan['id']}"), { "Authorization" => "Bearer #{KEY}" }) scan = JSON.parse(res) break scan if %w[done error].include?(scan["status"]) end end scan = scan_file("upload.pdf") raise "Blocked: #{scan['signature']}" if scan["verdict"] == "infected"
Go
Client: net/http + mime/multipart (stdlib)
package main import ( "bytes"; "encoding/json"; "fmt"; "io" "mime/multipart"; "net/http"; "os"; "time" ) const api = "https://api.upscan.example" func scanFile(path string) (map[string]any, error) { key := os.Getenv("UPSCAN_KEY") // 1. Submit var buf bytes.Buffer w := multipart.NewWriter(&buf) fw, _ := w.CreateFormFile("file", path) f, _ := os.Open(path); defer f.Close() io.Copy(fw, f); w.Close() req, _ := http.NewRequest("POST", api+"/v1/scans", &buf) req.Header.Set("Authorization", "Bearer "+key) req.Header.Set("Content-Type", w.FormDataContentType()) res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } var scan map[string]any json.NewDecoder(res.Body).Decode(&scan) // 2. Poll until done for scan["status"] != "done" && scan["status"] != "error" { time.Sleep(1500 * time.Millisecond) req, _ := http.NewRequest("GET", fmt.Sprintf("%s/v1/scans/%v", api, scan["id"]), nil) req.Header.Set("Authorization", "Bearer "+key) res, _ := http.DefaultClient.Do(req) json.NewDecoder(res.Body).Decode(&scan) } return scan, nil } func main() { scan, _ := scanFile("upload.pdf") if scan["verdict"] == "infected" { fmt.Println("Blocked:", scan["signature"]) } }
C# / .NET
Framework: Minimal API · Client: HttpClient
using System.Net.Http.Headers; using System.Text.Json; var api = "https://api.upscan.example"; var key = Environment.GetEnvironmentVariable("UPSCAN_KEY"); var http = new HttpClient(); http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", key); // 1. Submit using var form = new MultipartFormDataContent(); form.Add(new ByteArrayContent(File.ReadAllBytes("upload.pdf")), "file", "upload.pdf"); var res = await http.PostAsync($"{api}/v1/scans", form); var scan = JsonDocument.Parse(await res.Content.ReadAsStringAsync()).RootElement; var id = scan.GetProperty("id").GetString(); // 2. Poll until the verdict lands string status; do { await Task.Delay(1500); var body = await http.GetStringAsync($"{api}/v1/scans/{id}"); scan = JsonDocument.Parse(body).RootElement; status = scan.GetProperty("status").GetString()!; } while (status != "done" && status != "error"); if (scan.GetProperty("verdict").GetString() == "infected") Console.WriteLine($"Blocked: {scan.GetProperty("signature")}");
Need a different language?
The API is a simple REST endpoint. If you can make an HTTP request, you can scan files.
Get your free API key