How to Limit Form Submissions in SureForm
If you’re using SureForm on WordPress, controlling how users submit forms is essential, especially for quizzes, competitions, and lead generation campaigns.
By default, SureForm doesn’t provide advanced submission limits, such as restricting entries per email or capping total submissions. However, with a simple code snippet, you can implement powerful submission controls with ease.
In this guide, you’ll learn how to limit submissions by email address, set total submission caps, and prevent duplicate entries.
Why You Should Limit Form Submissions
Without submission limits, users can:
- Submit forms multiple times unfairly
- Abuse quizzes or competitions
- Skew your data or analytics
- Overload your campaigns or offers
Adding submission restrictions helps you maintain fairness, improve data quality, and control access to your content.
What You’ll Learn in This Tutorial
By the end of this guide, you’ll know how to:
- Restrict submissions by email address
- Set limits like daily, yearly, or lifetime submissions
- Prevent duplicate quiz entries
- Display custom error messages when limits are reached
- Apply submission rules across multiple forms
How to Limit SureForm Submissions (Step-by-Step)
1. Identify Your Form and Fields
Start by inspecting your form in the browser to find:
- The form ID
- The email field name
These values are required to apply submission rules correctly.

2. Add a Custom Code Snippet
Using a plugin like WPCodeBox, create a new snippet that hooks into SureForm’s submission process.
This allows you to intercept submissions and apply validation rules before the form is accepted.
<?php
/**
* Plugin Name: SureForms Simple Rules
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function sf_simple_rules_config() {
return [
6 => [
'submission_limit' => [
'limit' => 5,
'period' => 'daily',
'message' => 'This form has reached its submission limit for today.',
],
'duplicate_rules' => [
[
// Replace with the REAL field key from your debug tab.
'field' => 'srfm-input-833283cb-lbl-VGV4dCBGaWVsZA-text-field',
'mode' => 'text', // text or email
'allowed_total' => 2,
'period' => 'all_time',
'message' => 'You have already used both allowed attempts for this Form, no additional submissions are allowed..',
],
],
],
];
}
add_action( 'wp_ajax_sf_simple_rules_precheck', 'sf_simple_rules_precheck' );
add_action( 'wp_ajax_nopriv_sf_simple_rules_precheck', 'sf_simple_rules_precheck' );
function sf_simple_rules_precheck() {
check_ajax_referer( 'sf_simple_rules_nonce', 'nonce' );
$form_id = isset( $_POST['form_id'] ) ? absint( $_POST['form_id'] ) : 0;
if ( ! $form_id ) {
wp_send_json_error( [ 'message' => 'Invalid form.' ], 400 );
}
$submission = $_POST;
unset( $submission['action'], $submission['nonce'], $submission['_wp_http_referer'], $submission['_wpnonce'] );
$result = sf_simple_rules_evaluate( $form_id, $submission );
if ( $result['allowed'] ) {
wp_send_json_success( [ 'message' => 'Allowed' ] );
}
wp_send_json_error( [ 'message' => $result['message'] ], 429 );
}
add_action( 'wp_enqueue_scripts', function() {
if ( is_admin() ) {
return;
}
wp_register_script( 'sf-simple-rules', '', [], '1.0.1', true );
wp_enqueue_script( 'sf-simple-rules' );
wp_localize_script(
'sf-simple-rules',
'SFSimpleRules',
[
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'sf_simple_rules_nonce' ),
]
);
$js = <<<'JS'
(function(){
const pending = new WeakSet();
function showMessage(detail, message) {
const form = detail.form || null;
const successElement = detail.successElement || null;
const successContainer = detail.successContainer || null;
if (successContainer && successElement) {
successContainer.style.display = 'block';
successElement.innerHTML =
'<div style="background:#fff2f2;border:1px solid #d63638;color:#8a2424;padding:12px 14px;border-radius:6px;margin-top:16px;margin-bottom:12px;">'
+ String(message)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''') +
'</div>';
return;
}
if (form) {
let box = form.querySelector('.sf-simple-rules-error');
if (!box) {
box = document.createElement('div');
box.className = 'sf-simple-rules-error';
box.style.background = '#fff2f2';
box.style.border = '1px solid #d63638';
box.style.color = '#8a2424';
box.style.padding = '12px 14px';
box.style.borderRadius = '6px';
box.style.marginTop = '16px';
box.style.marginBottom = '12px';
const button = form.querySelector('button[type="submit"], input[type="submit"], .srfm-submit');
if (button && button.parentNode) {
button.parentNode.insertAdjacentElement('afterend', box);
} else {
form.prepend(box);
}
}
box.textContent = message;
}
}
document.addEventListener('srfm_on_trigger_form_submission', async function(event){
const detail = event.detail || {};
const form = detail.form || null;
const formId = parseInt(detail.formId || 0, 10);
if (!form || !formId) return;
if (form.dataset.sfSimpleRulesApproved === '1') {
delete form.dataset.sfSimpleRulesApproved;
return;
}
event.preventDefault();
event.stopImmediatePropagation();
if (pending.has(form)) return;
pending.add(form);
try {
const fd = new FormData(form);
fd.append('action', 'sf_simple_rules_precheck');
fd.append('nonce', SFSimpleRules.nonce);
fd.append('form_id', String(formId));
const response = await fetch(SFSimpleRules.ajaxUrl, {
method: 'POST',
body: fd,
credentials: 'same-origin'
});
const json = await response.json();
if (!json || !json.success) {
showMessage(detail, (json && json.data && json.data.message) ? json.data.message : 'This form cannot be submitted right now.');
return;
}
form.dataset.sfSimpleRulesApproved = '1';
const button = form.querySelector('button[type="submit"], input[type="submit"], .srfm-submit');
if (button) {
button.click();
} else if (typeof form.requestSubmit === 'function') {
form.requestSubmit();
} else {
form.submit();
}
} catch (e) {
showMessage(detail, 'We could not verify this submission. Please try again.');
} finally {
pending.delete(form);
}
}, true);
})();
JS;
wp_add_inline_script( 'sf-simple-rules', $js );
} );
function sf_simple_rules_evaluate( $form_id, $submission ) {
global $wpdb;
$rules = sf_simple_rules_config();
if ( empty( $rules[ $form_id ] ) ) {
return [ 'allowed' => true, 'message' => '' ];
}
$table = $wpdb->prefix . 'srfm_entries';
$config = $rules[ $form_id ];
if ( ! empty( $config['submission_limit'] ) ) {
$limit_rule = $config['submission_limit'];
if ( 'all_time' === $limit_rule['period'] ) {
$count = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM {$table} WHERE form_id = %d",
$form_id
)
);
} else {
$start = sf_simple_rules_period_start( $limit_rule['period'] );
$count = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM {$table} WHERE form_id = %d AND created_at >= %s",
$form_id,
$start
)
);
}
if ( ( $count + 1 ) > (int) $limit_rule['limit'] ) {
return [ 'allowed' => false, 'message' => $limit_rule['message'] ];
}
}
if ( ! empty( $config['duplicate_rules'] ) ) {
foreach ( $config['duplicate_rules'] as $rule ) {
$field = $rule['field'];
$value = sf_simple_rules_find_value( $submission, $field );
if ( null === $value || '' === trim( (string) $value ) ) {
continue;
}
$current = sf_simple_rules_normalize( $value, $rule['mode'] );
if ( '' === $current ) {
continue;
}
if ( 'all_time' === $rule['period'] ) {
$entries = $wpdb->get_results(
$wpdb->prepare(
"SELECT form_data FROM {$table} WHERE form_id = %d",
$form_id
)
);
} else {
$start = sf_simple_rules_period_start( $rule['period'] );
$entries = $wpdb->get_results(
$wpdb->prepare(
"SELECT form_data FROM {$table} WHERE form_id = %d AND created_at >= %s",
$form_id,
$start
)
);
}
$prior_matches = 0;
foreach ( $entries as $entry ) {
$data = json_decode( $entry->form_data, true );
if ( ! is_array( $data ) ) {
continue;
}
$prior_value = sf_simple_rules_find_value( $data, $field );
if ( null === $prior_value ) {
continue;
}
$prior = sf_simple_rules_normalize( $prior_value, $rule['mode'] );
if ( '' !== $prior && $prior === $current ) {
$prior_matches++;
}
}
if ( ( $prior_matches + 1 ) > (int) $rule['allowed_total'] ) {
return [ 'allowed' => false, 'message' => $rule['message'] ];
}
}
}
return [ 'allowed' => true, 'message' => '' ];
}
function sf_simple_rules_find_value( $data, $field ) {
if ( ! is_array( $data ) ) {
return null;
}
if ( isset( $data[ $field ] ) ) {
return sf_simple_rules_flatten( $data[ $field ] );
}
foreach ( $data as $key => $value ) {
if ( is_string( $key ) && sanitize_key( $key ) === sanitize_key( $field ) ) {
return sf_simple_rules_flatten( $value );
}
if ( is_array( $value ) ) {
foreach ( [ 'slug', 'name', 'fieldSlug', 'field_name', 'inputName', 'block_id' ] as $slug_key ) {
if ( isset( $value[ $slug_key ] ) && sanitize_key( (string) $value[ $slug_key ] ) === sanitize_key( $field ) ) {
if ( isset( $value['value'] ) ) {
return sf_simple_rules_flatten( $value['value'] );
}
return sf_simple_rules_flatten( $value );
}
}
$nested = sf_simple_rules_find_value( $value, $field );
if ( null !== $nested ) {
return $nested;
}
}
}
return null;
}
function sf_simple_rules_flatten( $value ) {
if ( is_array( $value ) ) {
$parts = [];
array_walk_recursive(
$value,
function( $v ) use ( &$parts ) {
if ( is_scalar( $v ) ) {
$parts[] = (string) $v;
}
}
);
return implode( ' ', $parts );
}
return is_scalar( $value ) ? (string) $value : '';
}
function sf_simple_rules_normalize( $value, $mode ) {
$value = trim( wp_strip_all_tags( sf_simple_rules_flatten( $value ) ) );
if ( 'email' === $mode ) {
$value = sanitize_email( strtolower( $value ) );
return $value ?: '';
}
return preg_replace( '/\s+/u', ' ', strtolower( $value ) );
}
function sf_simple_rules_period_start( $period ) {
$tz = wp_timezone();
$now = new DateTimeImmutable( 'now', $tz );
switch ( $period ) {
case 'daily':
$start = $now->setTime( 0, 0, 0 );
break;
case 'weekly':
$weekday = (int) $now->format( 'N' );
$start = $now->setTime( 0, 0, 0 )->modify( '-' . ( $weekday - 1 ) . ' days' );
break;
case 'monthly':
$start = $now->modify( 'first day of this month' )->setTime( 0, 0, 0 );
break;
case 'annual':
$start = new DateTimeImmutable( $now->format( 'Y-01-01 00:00:00' ), $tz );
break;
default:
$start = $now->setTime( 0, 0, 0 );
break;
}
return $start->format( 'Y-m-d H:i:s' );
}PHP3. Set Submission Limits
You can define limits such as:
- Per email address (e.g. 2 attempts per user)
- Total submissions (e.g. 300 entries per month)
- Time-based limits:
- Daily
- Weekly
- Monthly
- Yearly
- Lifetime
For example, you might allow only 2 submissions per email per year.
So, taking our information from above, our return becomes
8 => [
'submission_limit' => [
'limit' => 6,
'period' => 'daily',
'message' => 'This form has reached its submission limit for today.',
],
'duplicate_rules' => [
[
// Replace with the REAL field key from your debug tab.
'field' => 'srfm-email-3d1cc764-lbl-RW1haWwgQWRkcmVzcw-email-address',
'mode' => 'email', // text or email
'allowed_total' => 2,
'period' => 'annual',
'message' => 'You have already used both allowed attempts for this Form, no additional submissions are allowed..',
],
],
],
];
}PHP4. Enable Email-Based Validation
By normalising the email field, you ensure:
- Duplicate emails are detected properly
- Submissions are tracked accurately
- Users cannot bypass limits with minor variations
This is why we have set it to email mode rather than text.
5. Add Custom Error Messages
When a user reaches the submission limit, you can display a message like:
“You’ve already used all allowed attempts for this form. No additional submissions are allowed.”
This improves user experience and clearly explains why the form is blocked.

Final Thoughts
While SureForm doesn’t natively support advanced submission limits, its flexibility allows you to implement them easily with custom code.
Whether you’re running a quiz, competition, or marketing campaign, adding submission guards ensures fairness, improves data quality, and gives you full control over your forms.
You can watch the accompanying Video to this article below
