Prove you're human by the way you move.
AOCaptcha is a self hosted, drag and drop CAPTCHA for PHP. A visitor nudges a shape into place, and your server weighs the whole motion that got it there, not just where it landed. No third party, nothing phoning home.
Four steps, and the answer never leaves your server.
The visitor only ever sees a shape to drag. Everything that decides human or bot happens in your own code, with the correct answer held server side the whole way through.
Challenge
The server picks a shape, a target and a starting spin, and keeps the answer to itself.
Drag
The visitor drags the piece into place while the widget records the whole path, roughly a point every 25 milliseconds.
Snap
Once the piece is close enough it snaps home, and the full motion trace is sent to your verify endpoint.
Verify
The server checks the drop against the stored target, then scores the motion. Only a solve that is right and human earns a one time token.
It judges the gesture, not just the destination.
A bot can drop a piece in the right place. What it struggles to fake is the messy, human way a real hand gets it there. AOCaptcha scores that motion before it trusts the solve.
Path curvature
Real hands rarely travel in a perfect line. A dead straight drag is a tell.
Speed variance
People speed up and slow down as they go, so a perfectly constant velocity reads as a script.
Direction corrections
Humans overshoot and nudge back. That self correction is hard to fake.
Acceleration noise
Organic micro jitter in the motion data that a clean synthetic drag lacks.
Drop position
The piece still has to land within tolerance of the target it was never shown.
No lockout on a miss
If a solve fails, a fresh challenge is issued, so a real person is never shut out.
Three small pieces, no framework required.
An endpoint to serve and verify challenges, a container in your form, and one check on submit. Plain PHP 8.1+ and vanilla JavaScript, installed with Composer and npm or just copied in.
One config file, and it wears your brand.
Colours, fonts, radii, the piece size and the whole shape pool live in a single JSON file, each mapped to a CSS custom property. Override the theme at runtime for per tenant styling, no rebuild needed.
What is in the box.
Run composer require weanteomnio/aocaptcha and here is what you actually get. No account, no API key, no database unless you want one.
Drop-in PHP core
CaptchaHandler, Challenge and BehaviorAnalyzer. Plain PHP 8.1+, and you can wire it without Composer.
Storage adapters
Session and Redis out of the box, or implement the interface and bring your own.
The widget
A vanilla JavaScript widget with no framework, shipped as both UMD and ESM builds.
One stylesheet
A single stylesheet driven entirely by CSS variables, so it wears your brand with no overrides.
A library of shapes
421 shapes across nine parametric families to draw challenges from, all listed in config.
A real test suite
21 PHPUnit tests and 653 assertions covering challenge generation, storage and the motion scoring.
One config file
Shapes, colours, fonts and sizing in a single JSON file, each mapped to a CSS variable.
Zero dependencies
Nothing to pull in from outside, and nothing that phones home once it is running.
The hard parts are decided where a bot cannot see.
The client is only ever handed a puzzle to draw. Every judgement, and the answer itself, stays in your process.
Answer stays server side
The correct drop position is stored on the server and never sent to the browser.
Behaviour is scored
A positionally correct but mechanically synthetic drag is rejected, not trusted.
One time tokens
A pass token is deleted the moment it is read and compared, so it cannot be replayed.
Short lived state
Challenges expire in minutes and tokens soon after, both tunable to your needs.
No stale caching
Explicit no store and CDN surrogate headers stop a proxy serving an old challenge.
No external calls
Nothing leaves your server, so there is no vendor outage and no data to share.
Open, honest, and still early.
AOCaptcha is young. The PHP core is tested and the security model is deliberate, but it has not yet been battle tested across thousands of sites, and a couple of things are honestly still missing.
It is free under GPL-3.0 with no lock in. Read it, run it, fork it, and if you find a gap, the issues are open.
Self hosted, no lock in
Runs entirely on your own server. No account, no metering, nothing to rent.
Tested PHP core
21 PHPUnit tests and 653 assertions cover challenge generation, storage and the motion scoring thresholds.
Keyboard fallback is not there yet
The challenge is drag only today, so it is not usable by keyboard alone. Until that lands, pair it with a honeypot or keep an accessible path open for forms that must reach everyone.
JavaScript tests still to come
The front end is not yet covered by automated tests. It is on the list, and contributions are welcome.
Want a form that keeps bots out, cleanly?
AOCaptcha is one of the tools we reach for. If you have a site or a form that needs protecting without handing visitors to a third party, the next step is a short call with the person who would build it.