This guide puts a gate in front of the pages you choose. Before your server sends one of them, it gets Human Confidence for the visitor from the 51Degrees cloud and decides what to send. The worked example gates a retailer's product pages and price API, and the same gate suits a publisher's articles, a listing site's search results, a sign-up form, or any API that serves one person at a time.
You need a holding page, one server file in Node.js, PHP or Python, and a Resource Key. There's no 51Degrees package to install on the server.
If you'd rather see how much of your traffic is people before you change what anyone gets, start with Human and bot traffic in your analytics.
Get a License Key with Human Confidence: buy the Pro plan online for the cloud service, or talk to us about the Bespoke plan to run it on your own servers in a Docker container. Compare plans.
How it works🔗
- The first request for a protected page gets a small holding page instead. It runs the 51Degrees script, posts the script's values to your server and reloads. A person sees it for a moment.
- Your server sends those values to the cloud along with the request headers the cloud uses and the visitor's IP address. Human Confidence comes back in the response, and the server caches it in the session for 30 minutes.
- The server serves the page for High. In the examples Medium goes to a challenge and Low to a page about licensing your data, which you change to suit your site. The check is done on the server because anything a browser sends can be forged.
Step 1. Create a Resource Key🔗
Create a Resource Key from this link. It opens with the properties Human Confidence needs already ticked. Add the License Key from your plan. A free License Key won't work, because Human Confidence starts at Pro.
Don't add other properties to this key, as each one adds a script to the holding page and slows it down.
Leave the domain list empty. The server calls the cloud with the same key, and a server request has no Origin header, so a key limited to domains fails with 401 and This resource key is not authorised for the domain ''. If you want the limit anyway, send an Origin header naming one of your domains on the server's request, for example Origin: https://www.example.com.
Only the Resource Key goes in the holding page, never the License Key.
To check the key, open https://cloud.51degrees.com/api/v4/YOUR_RESOURCE_KEY.json in a browser. You should see this. Unknown is right at this point, because the script hasn't run yet.
Step 2. Add the holding page🔗
Save this as holding.html next to your server code. The server code in step 3 puts your Resource Key in place of RESOURCE_KEY.
fod-js-enable-cookies=trueasks the 51Degrees script to keep its values in cookies with names that start51D_. Without the parameter, the script keeps the values in session storage, which your server cannot read. See Client-side Evidence for more.- Clients that don't run JavaScript, such as curl, stay on the holding page.
Step 3. Ask the cloud from your server and decide🔗
- The server code sends the holding page to any session it has not checked, with
Cache-Control: no-storeso that no cache keeps the holding page. - When the holding page posts to
/human-check, the server asks the cloud. It posts a form tohttps://cloud.51degrees.com/api/v4/YOUR_RESOURCE_KEY.jsonwith the visitor's headers, every51D_value, and the visitor's IP address asclient-ip. It readsderived.humanconfidencefrom the JSON response and caches it in the session. - Every later request for a protected page or API uses the cached value.
Things to check when you adapt the code:
- The server sends only the headers the cloud uses, as the 51Degrees SDKs do. Their names are the entries starting
header.in the list at https://cloud.51degrees.com/api/v4/evidencekeys. Other headers, such asAuthorization, stay on your server. The Node.js and Python examples read that list on their first check and keep it. The PHP example reads it on every check, because PHP keeps nothing between requests, so cache it if you check often. - The server sets
client-iplast. A visitor's ownClient-IPheader can't then replace the address. If your site sits behind a load balancer or a CDN, make sure the address is the visitor's and not the load balancer's. Each example has a comment where this matters. - Node.js writes IPv4 addresses in the form
::ffff:203.0.113.7. The Node.js code removes the::ffff:part before sending the address.
If the cloud can't be reached, takes longer than 2 seconds or returns an error status, the server lets the visitor through for that page and tries again on the next request. If the cloud does respond but with Unknown, the visitor gets your challenge (step 4). The example price API only answers sessions that are High, so it refuses calls until a check has worked.
Step 4. Decide what each value gets🔗
| Value | What it means | Pages | APIs |
| High | A person is reading the page. | Show the page. | Answer the call. |
| Medium | It could be a person or a script. | Challenge with a CAPTCHA, a sign-in, or a notice, like ours. | Refuse with 403 until the visitor passes the challenge. |
| Low | Almost certainly no person is reading it. | Send the visitor to a page that says how to license your content or data, like ours, and log the visit. | Refuse with 403 and log the call. |
| Unknown | Not measured, for example because the script could not run. | Treat it as Medium. | Refuse with 403. |
A Low visit is almost always software, so you can serve it something made for software rather than a page made for people. The examples refuse it, and these are the other treatments websites use, alone or together:
- The page without what you sell. A retailer serves the product page without prices and stock, a listing site answers a search with no contact details, and a publisher serves the first paragraph of the article.
- Content for machines. Serve the same content as Markdown or plain text instead of HTML, with no navigation, scripts, or ads, so an AI gets what it came for cheaply and your page for people stays as it is.
- Your licence terms. Serve the terms the software has to accept to use your content, with a way to get a licence. Ours is the AI notice. The Movement for an Open Web's Search Only Contract is a published set of terms any website can adopt, and the robots.txt generator writes a robots.txt that cites it.
- No ads. Leave the ad slots empty, so nobody pays to show an ad to a script.
- A block. Refuse with
403, as the example API does, and log the visit.
Whatever Low gets, send Medium somewhere a person can prove themselves, and let the search engines you want through by name.
The examples send Medium and Unknown to /challenge and Low to /automated-access, and the example price API refuses every session that is not High. Replace those two pages with your own. When a visitor passes your challenge, set the cached value to High so they can carry on.
Search engine crawlers get the holding page too, like any session the gate has not checked. If your product pages must appear in search results, let genuine search engine crawlers skip the gate. Google and Bing explain how to check that a crawler really is theirs.
Test it🔗
Start one of the servers with your key and try the following. The addresses are the same whichever server you run.
- Run
curl -i http://localhost:3000/products/1. You get the holding page. curl runs no JavaScript, so it never gets further. - Run
curl -i http://localhost:3000/api/prices/1. The response is403 Forbidden. Nothing has checked the session yet. - Open http://localhost:3000/products/1 in your browser. After a moment the browser shows the challenge page. When you test on your own computer, expect Medium. On a public server, the same browser normally gets High and the product page.
- Open the same address in a headless browser, for example with Playwright. The browser reaches
/automated-access, and the server logs a line that startsLow:.
Find out more🔗
- Bots and humans
- How likely is your traffic to be from real humans?, our post on what each answer means
- Robots.txt generator
- Human Confidence in the property dictionary
- Resource Keys
- Human and bot traffic in your analytics
Human Confidence needs the Pro plan, which you can buy online, or the Bespoke plan for your own servers. Ask us about Bespoke through the contact page.
