Tendrl Surface

Your security layer.
Scan files and payloads. Stop threats.

Scan file uploads with ML-driven detection. Scan text payloads for prompt injection before they reach your model. One endpoint, full verdict, no security team required.

Coming soon Read the docs
Python
from surface import SurfaceClient

scanner = SurfaceClient(api_key="YOUR_KEY")
result = scanner.scan_file("upload.zip")

# {"score": 95, "verdict": "clean", "action": "allow"}

How it works

Four steps from upload to verdict

1

Upload

Send any file to the REST API with your API key. Any format, up to your plan limit.

2

Scan

Multiple detection engines run in parallel: pattern matching, ML, threat feeds, behavioral analysis, and more.

3

Score

Get a 0–100 safety score, a verdict, and a recommended action in the scan response.

4

Act

Allow, quarantine, or block. Trigger a Strand workflow to fan out from there.

Surface payload scanning for AI security
Payload Scanning

Scan text content for prompt injection, credential leaks, and malicious payloads

AI security

Scan what users type, not just what they upload

The payload endpoint scans text content instead of files, built for AI agents and user-input pipelines. Catch prompt injection, credential leaks, and malicious commands before they reach your model or your backend.

  • Prompt injection detection
  • Credential and secret leak detection
  • Suspicious tool call detection for AI agents
  • Same 0–100 score, same verdict
Python
# Scan user input before sending to your LLM
result = scanner.scan_payload(user_message)
if result["verdict"] == "malicious":
    reject()

AI integration

Give your AI agent a scanner

The Surface MCP server (@surface/mcp) exposes scanning as a native tool. Any agent that supports MCP can scan files and payloads without writing a single HTTP call.

Cursor integration Claude Desktop Built-in AI skills via MCP Any MCP-compatible agent scan_file tool scan_payload tool No HTTP client code needed

Detection

Multiple layers. One verdict.

No single technique catches everything. Surface combines pattern matching, trained ML models, and live threat data so each layer covers what the others miss.

Pattern matching

Known threat signatures are checked instantly across every file type: executables, documents, scripts, and archives. Updated automatically, no maintenance required.

ML classification

Per-format models trained on tens of thousands of real malware samples catch novel threats that have never been seen before, the ones signatures will always miss.

Live threat feeds

Continuously updated intelligence from across the threat landscape. Known-bad files and infrastructure are identified in milliseconds, before deeper analysis even runs.

Obfuscation detection

Malware that hides itself (packed executables, encoded payloads, disguised macros) is flagged even when the underlying content looks clean on the surface.

Deep file inspection

Archives are unpacked, documents are parsed, and embedded content is scanned recursively. Threats buried inside uploaded files don't get a free pass.

Indicator extraction

Every scan surfaces what it found: domains, IPs, URLs, and hashes pulled from the file itself. Useful context alongside the verdict, without any extra work.

Verdict

A score, not just a flag

Every scan returns a unified 0–100 safety score that combines all engine results into one signal. The verdict and recommended action tell you exactly what to do, no security expertise needed.

  • 91–100 Clean: allow the upload
  • 71–90 Informational: log and monitor
  • 31–70 Suspicious: quarantine for review
  • 0–30 Malicious: block immediately

Verdict confidence (High / Medium / Low) indicates how certain the scanner is, not how severe the threat is. Validated against 82K labeled malware samples.

Surface scan result
Scan Result

Score, verdict, confidence, and per-engine breakdown in a single response

Developer experience

Pick your language, start scanning.

SDKs for Python, Go, and JavaScript, or call the REST API directly. Same score, same verdict, same response shape regardless of how you integrate.

Python
from surface import SurfaceClient

scanner = SurfaceClient(api_key="YOUR_KEY")

# Scan a file upload
result = scanner.scan_file("upload.pdf")
if result["action"] != "allow":
    reject_upload()
Go
import surface "github.com/tendrl-inc-labs/surface-go"

client, _ := surface.NewClient("YOUR_KEY")

// Scan before writing to storage
result, _ := client.ScanFile(ctx, "upload.pdf", nil)
fmt.Println(result.ScanResult.SafetyScore.ThreatLevel)
JavaScript
import { SurfaceClient } from "@surface/sdk";

const scanner = new SurfaceClient({ apiKey });

// Scan before writing to storage
const result = await scanner.scanFile(file);
if (result.action !== "allow") throw new Error();
cURL
curl -X POST https://app.surface.com/api/scan \
  -H "Authorization: Bearer YOUR_KEY" \
  -F "[email protected]"

# Returns JSON with score, verdict, action

Drop-in UI

Embed scanning in any page

Add the Surface widget to any web app with one script tag. Users drag and drop files, the widget scans them, and your page receives the result. No backend changes required.

  • One script tag to add to any HTML page
  • Drag-and-drop or click-to-browse file input
  • Scan result surfaced directly in the widget UI
  • Configurable allowed file types and size limits
  • Fires a callback with the full scan result
HTML
<!-- Drop-in file scanner -->
<script src="/static/embed_scanner.js"></script>
<div id="surface-widget"
  data-api-key="YOUR_KEY"></div>
Surface embeddable widget
Embeddable Widget

Drag-and-drop file scanner that works in any web page with one script tag

Delivery

Push results wherever you need them

Configure webhooks to receive scan results as they finish. Useful for async scanning of large files: submit and move on, get the result pushed to your endpoint when it's ready.

  • POST scan results to any URL on completion
  • Multiple auth options: API key, Bearer token, custom header
  • Webhook credentials encrypted at rest with AES-256-GCM
  • Works with async scans, file scans, and payload scans
Surface webhook configuration
Webhooks

Configure delivery endpoints with auth and receive results on completion

Surface and Strand working together
Surface → Strand

Scan results trigger Strand workflows: quarantine, notify, archive, or block automatically

Native integration

Surface + Strand: scan and respond

A scan result can trigger a Strand workflow automatically. Block malicious uploads before they reach storage, notify your team on suspicious files, or archive clean uploads to S3, all without writing glue code.

  • Trigger workflows on malicious or suspicious verdicts
  • Pass the full scan result as workflow payload
  • Notify Slack or email from a single node
  • Quarantine files or update records via HTTP connector
Explore Strand

Observability

Full scan history and analytics

Every scan is recorded. See the full history, filter by verdict, and drill into any result for a per-engine breakdown: YARA matches, ML scores, threat feed hits, and extracted IOCs.

  • Scan history with verdict, score, and file metadata
  • Per-engine breakdown for every result
  • Filter by verdict, date range, or file type
  • Credit usage analytics and monthly quota tracking
  • IP block list, automatic and manual
Surface scan history dashboard
Dashboard

Scan history, per-engine breakdown, analytics, and IP management

Security

Designed to handle malicious content safely

Files are loaded to memory, scanned, and discarded. Nothing is stored except metadata, hashes, and results. Updates to rules, models, and feeds are verified by SHA-256 hash and Ed25519 signature before applying.

Files never written to disk Most scans complete in under a second Threat feeds updated every 30 minutes AES-256-GCM webhook credentials Ed25519-signed rule updates Scan history from 7 days to 1 year by plan, auto-purge

Start scanning in 5 minutes.

Free tier includes 100 scans per month, up to 10 MB per file. No credit card required.

Coming soon Quick start guide