If your product ingests documents on someone else's behalf — an ATS, a claims system, a procurement tool, an AI assistant with an upload button — the hidden-text question now lands in your inbox, not ours. Embedding a scanner is a week of your roadmap or an afternoon of ours.
Flat or per-scan, whichever suits your volume. Includes the self-hosted build, updates as new concealment techniques appear, and a direct line when something looks wrong.
Start a conversation>>> from docxray.api import scan, safe_text, clean >>> result = scan("uploads/candidate_4471.pdf") >>> result["verdict"] 'CRITICAL' >>> result["findings"][0].kind 'hidden-text' >>> safe_text(result) # feed this to your model instead 'Jordan Avery Ellis Portland, OR ...'
Three calls: is it clean, what was found, and give me the text that is safe to pass on. There is an HTTP endpoint too if a library is the wrong shape for you.
You can, and the first eighty percent is genuinely easy — look for white text and tiny fonts. The remainder is where the engineering is:
That last one is the expensive part. A detector that cries wolf gets switched off in a fortnight.
We will tell you honestly whether embedding makes sense or whether you should just write it yourself.