Document Classification API

Classify documents more accurately
so they can be better protected

Scan a document for personal data, semantically match it against a configurable set of document types, and derive a classification label from both. One call, no LLM in the request path.

Try it

Drop in a document of any type listed on the right and hit Analyse. Samples are downloadable from that list. Click + for the full JSON response.

Click to upload or drag and drop

PDF, DOCX, TXT — up to 10 MB

Free demo – no API key needed. Limited to 10 analyses per minute per IP.


            
Document Types
  • Loading...

Pipeline

How it works

Three steps run over every document, in order. Steps 1 and 2 are independent — the personal-data scan does not depend on the type match, and vice versa. Step 3 is a pure function of their two outputs.

01

Scan the whole document for personal data

Names, locations, dates, identifiers. Runs over all extracted text rather than a sampled region, because sensitive values turn up anywhere. Each hit carries its entity type, character offsets and a detection confidence.

02

Semantically match the document to a type

The document is chunked and embedded, then compared by cosine similarity against reference vectors for each configured type. If nothing clears the threshold the answer is unrecognized — a stated non-answer rather than a forced guess into the nearest known type.

03

Derive a classification label

public / internal / confidential / restricted, computed from the outputs of steps 1 and 2. Each type has a base tier; detected personal data escalates it, further for government and financial identifiers. This is a policy lookup, not a model — it ships as an editable JSON file and carries no confidence score, because given the same inputs it is the same answer every time.

Implementation

What it runs on

Step 1 uses Microsoft Presidio. Step 2 uses a small sentence-transformer embedding model — tens of millions of parameters, not billions — which is enough for semantic type matching and cheap enough to run locally. Reference vectors are computed once, offline, so a request costs one forward pass per chunk plus a matrix multiply. Three properties follow from that:

=

Deterministic

The same document returns the same output every time. No sampling, no temperature, no drift between calls — so a downstream policy built on the result stays stable, and a regression is a real regression rather than noise.

Sub-second

Fast enough to sit inline rather than in a nightly batch. Nothing on the request path waits on a hosted model, so latency is bounded by local compute instead of somebody else's queue.

🔒

On-premises, no GPU

Runs on ordinary CPU hardware, so it can be deployed inside your own perimeter. Documents never need to leave the network to be classified — which for a lot of financial and legal content is the difference between usable and not.

Reference profiles

Configuring document types

The set of types is not fixed in the code. Each type is described by a reference profile — a short set of natural-language descriptors of what documents of that type contain. Profiles are compiled offline into a training artifact of embedding vectors, which is what step 2 actually matches against at runtime.

Training a type takes two or three sample documents. For types that are universally understood, it may take none at all — the descriptors can simply be written by hand, and the classifier cannot tell the difference between a hand-authored profile and a generated one.

Because the profile is natural-language descriptors rather than opaque weights, a result can be traced back to the specific descriptors that matched. The list on the demo above is whatever profiles are currently loaded, not a hardcoded menu.

Use Cases

Where it gets called from

It is an API other systems call, not a dashboard. Four places that call it:

01

AI firewall & prompt inspection

Sit inline between users and your LLM. Classify every prompt and attachment before it reaches the model — block or flag sensitive content based on document type and PII presence, at latencies that don't degrade UX.

02

DSPM enrichment

Add semantic document-type classification to your data security posture. Know whether a flagged file is a payslip, a loan application, or a financial statement — not just that it contains PII — so sensitivity tiers and access controls are actually meaningful.

03

RAG pipeline governance

Classify and score documents at index time. Tag sensitivity metadata before content enters a retrieval store, so your AI application never unknowingly retrieves and surfaces restricted material.

04

Data loss prevention

Route documents by type and sensitivity before they leave your systems. A DLP rule that knows "this is a credit agreement containing an NRIC" makes far fewer mistakes than one that only knows "this file contains a 9-digit number."

API Reference

The endpoint

One POST, multipart body, JSON back. No SDK.

Full API access coming soon — join the waitlist via Contact
POST /classify

Classify a document or pasted text and surface sensitive content. Returns document type, confidence, matched features, and PII hits with character offsets.

Field Type Description
file multipart Required. A PDF, DOCX, or TXT file. To classify pasted/raw text, send it through this same field as a plain-text blob (any filename works — see the curl examples below).
fields query param Optional, comma-separated. Adds debug/telemetry fields to the response: raw_scores, raw_margin, timings_ms. Omitted by default.

Example requests

# File upload
curl -F "file=@document.pdf" https://petablade.com/classify

# Paste/raw text — send as a file (any filename with an extension works)
curl -F "file=@-;filename=input.txt" https://petablade.com/classify < document.txt

# Include debug fields
curl -F "file=@document.pdf" "https://petablade.com/classify?fields=raw_scores,timings_ms"
RES Response schema (default)
"document_type": "bank_statement",
"confidence": 0.94,
"matched_features": [
  "chronological transaction ledger with date, description, and amount per row",
  "running or closing balance that changes line by line"
],
"pii_detected": true,
"pii_hits": [
  {
    "pii_type": "PERSON",
    "start": 47,
    "end": 65,
    "confidence": 0.94,
    "masked": "JOHN S•••"
  },
  {
    "pii_type": "EMAIL_ADDRESS",
    "start": 112,
    "end": 128,
    "confidence": 0.88,
    "masked": "jo•••••••@example.com"
  }
]

Add ?fields=raw_scores,raw_margin,... to include per-type similarity scores and pipeline timings — see the fields parameter above.

Contact

Get in touch