Stopping monitoring submissions reaching your team
A form check sends one real enquiry, because nothing else proves the form works. Teach your server to recognise it by our header and discard it: the check still proves the path up to your server, and nothing reaches a person.
X-Senriko-Monitor headerReal visitors never send the header, so their enquiries go through as before.
How to check a form without bothering your team
These are three of the check depths in your dashboard. The header fits when the form handler is yours and you can add a few lines to it.
Safe Check
The enquiry never leaves the browser. Proves the page loads and the form submits.
What it takes: nothing, every form starts here.
With the header
This pageThe enquiry reaches your server, which discards it. On top of Safe Check: your server accepted it and the conversion was recorded.
What it takes: a few lines in your form handler, which is what this page is about.
With a CRM filter
The enquiry reaches your CRM and a rule moves it straight to a test pipeline. All five steps, CRM delivery included.
What it takes: a rule in your CRM and the site owner’s consent. Recipes for 12 systems
Steps: 1 the page loads, 2 the form submits, 3 the server accepts it, 4 the conversion is recorded, 5 the CRM receives it.
What this buys you
Two things. Nobody on your team ever sees a monitoring enquiry, because it never becomes one - your handler answers normally and stores nothing. And the frequency ceiling lifts: a check whose submissions reach a person is held to once a day on purpose, because twenty-four synthetic leads a day is a decision about somebody's working morning rather than a monitoring setting. A check that reaches nobody can run as often as your plan allows.
What the test enquiry looks like in your CRM
Every check submits as the same made-up person, and keeps the same values for as long as the check exists. All four are things a CRM rule can match on.
Match the domain checks.senriko.com, not the whole address: the address carries the check’s id, and a new check gets a new one. If the handler cannot be changed, a CRM filter catches the enquiry by the same signs.
monitor-<id>@checks.senriko.com- Phone
+1 201 555 01NN- Hidden field
utm_source=senriko-monitor- Message starts with
[SENRIKO TEST <id> - DO NOT CONTACT]
What we send, and where to find the token
Every request a check makes to your website carries a header naming the workspace it belongs to. Requests to other services on your pages, such as analytics or a chat widget, do not, with one exception: when your own site redirects a request to another service, the browser carries the header there too. Nothing else sends it, and nobody else can guess it.
X-Senriko-Monitor: your-workspace-tokenYour token is in the form check wizard, beside the box that declares this is set up, and in Settings, Test identity, where the owner can replace it. Treat it as a secret: anything that knows it can make a request your site will discard.
Four steps in your form handler
Read the header
It is X-Senriko-Monitor, on the incoming request. Only our checks’ requests carry it.
Compare it to the token
With your workspace token, using a constant-time comparison if your language offers one.
Skip the side effects
If it matches, skip everything the submission would normally trigger - no CRM record, no notification, no email to your sales team.
Answer as usual
The same status code, the same redirect, the same thank-you page.
That last step is the one that matters. The check reads what a visitor would see, so a handler that discards the submission and then returns an error will be reported as a broken form - correctly, because that is what a visitor would get.
The same four steps, in code
Whichever of these your site is built on, the shape is identical: read the header, compare it in constant time, skip the side effects, and answer exactly as you would have.
SENRIKO_TOKEN is your workspace token, from the form check wizard. Keep it in your environment, not in the file: anything that knows it can make a request your site will discard.
$token = getenv('SENRIKO_TOKEN');
$sent = $_SERVER['HTTP_X_SENRIKO_MONITOR'] ?? '';
// Both must be set: an empty token would match every visitor who sends no header.
if (is_string($token) && $token !== '' && $sent !== '' && hash_equals($token, $sent)) {
// Answer exactly as you would have, and do nothing else.
header('Location: /thank-you', true, 303);
exit;
}import { timingSafeEqual } from 'node:crypto';
function isMonitor(req) {
const token = Buffer.from(process.env.SENRIKO_TOKEN ?? '');
const sent = Buffer.from(req.get('x-senriko-monitor') ?? '');
// Both must be set: an empty token would match every visitor who sends no header.
if (token.length === 0 || sent.length === 0) return false;
// Lengths first: timingSafeEqual throws when they differ, which would
// turn a short header into a 500 for anybody who sends one.
return sent.length === token.length && timingSafeEqual(sent, token);
}
app.post('/contact', (req, res) => {
if (isMonitor(req)) return res.redirect(303, '/thank-you');
// ... your normal handling
});import hmac, os
def is_monitor(request):
token = os.environ.get('SENRIKO_TOKEN', '')
sent = request.headers.get('X-Senriko-Monitor', '')
# Both must be set: an empty token would match every visitor who sends no header.
return bool(token) and bool(sent) and hmac.compare_digest(sent, token)
def contact(request):
if is_monitor(request):
return redirect('/thank-you')
# ... your normal handlingdef monitor?
token = ENV.fetch('SENRIKO_TOKEN', '')
sent = request.headers['X-Senriko-Monitor'].to_s
# Both must be set: an empty token would match every visitor who sends no header.
token.present? && sent.present? && ActiveSupport::SecurityUtils.secure_compare(sent, token)
end
def create
return redirect_to('/thank-you', status: :see_other) if monitor?
# ... your normal handling
end// Runs before the form plugin sends anything. The hook name differs by
// plugin: this one is Contact Form 7; WPForms uses wpforms_process.
add_action('wpcf7_before_send_mail', function ($form) {
$token = getenv('SENRIKO_TOKEN');
$sent = $_SERVER['HTTP_X_SENRIKO_MONITOR'] ?? '';
// Both must be set: an empty token would match every visitor who sends no header.
if (is_string($token) && $token !== '' && $sent !== '' && hash_equals($token, $sent)) {
$form->skip_mail = true;
}
});On something else? Any framework that can read a request header can do this. The only part worth care is the comparison: use your language's constant-time equality rather than ==, and handle a header of the wrong length without erroring.
The wizard sends a trial enquiry with the header
Tick “Our website discards submissions carrying this header” and press “Try it once”. If your server answers an unfamiliar header with an error, you see it at once rather than silently every hour after setup.
What developers ask
Is this a hole in your form?
Do you need to check the token?
Why does SENRIKO take your word for it?
What does it not change?
Four steps of five. Only your CRM can prove the fifth
With the submission discarded, the check still proves the page loads, the form can be filled in and submitted, the server accepts it, and your conversion signals fire. It stops proving that a lead reaches your CRM, because you have asked us not to send one. If that last step is what you need watched, leave the submissions arriving and filter them in your CRM instead.
- The page loadsProved
- The form submitsProved
- The server accepts itProved
- The conversion is recordedProved
- The CRM receives itNot checked