iTranslated by AI
Implementing HubSpot Form Submission Limits with HubDB and Serverless Functions (Code Included)
How to Implement HubSpot Form Submission Limits with HubDB & Serverless Functions (with Code) 💻
2025-04-29 · Reina
Introduction 🌿
HubSpot forms do not have a built-in feature to set a submission limit. To solve this challenge, I implemented a solution using HubDB and Serverless Functions 💻

Mechanism (Behavior in the Demo Video) 🎥
This is how the system works!
Increments the HubDB count via a Serverless Function.
Hides the form (displays a message) when the limit is reached.
Automatically hides the form once the application deadline (UTC-based) has passed!
Organizing the Prerequisites ☕
Scenario
- Users sign up via a HubSpot form.
- We want to limit the number of registrants.
- Automatically hide the form once the limit is exceeded.
- Also, add a deadline timing for form submissions.
Configuration Overview
- Manage information for each form in HubDB.
- Use within CMS templates.
- Increment the count upon form submission.
- Update via the HubDB API on the Serverless Function side.

Technologies, Files, and Tools Used ⚡
- HubL if statements
- HubDB (v3 API)
- Serverless Functions
- JavaScript (hbspt.forms)
Implementation Code Overview 🔧
HubDB Table (Example)
| Column Name | Purpose | Data Type |
|---|---|---|
| form_guid | Target form ID (used to identify the sender) | text |
| current_submissions | Current number of submissions | number |
| max_submissions | Maximum allowable submissions | number |
| deadline | Application deadline (UTC) | datetime |
This table is for managing the submission status of each form. The if statement in the template will toggle the form visibility based on the submission limit and deadline.
HubL within Templates
{# Getting the current local time and converting it to UNIX timestamp #}
{% set today = unixtimestamp(local_dt) %}
{# Fetch data by specifying the HubDB Table ID! #}
{% set table = hubdb_table_rows("HUBDB_ID_HERE") %}
{% for row in table %}
{% if row.form_guid "FORM_GUID_HERE" %}
{% set current_submissions = row.current_submissions %}
{% set submission_limit = row.max_submissions %}
{% set deadline_timestamp = row.deadline %}
{% if current_submissions < submission_limit and today < deadline_timestamp %}
{# Display the form if both submission count and deadline are OK! #}
<div id="my-form-wrapper">
<div id="my-form-target"></div>
<script src="https://js.hsforms.net/forms/v2.js"></script>
<script>
hbspt.forms.create({
region: "na1",
portalId: "YOUR_PORTAL_ID",
formId: "FORM_GUID_HERE",
target: '#my-form-target',
onFormSubmit: function($form) {
// Call the serverless function to increment the count upon submission!
fetch('/_hcms/api/update-form-submissions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ form_guid: 'FORM_GUID_HERE' })
});
}
});
</script>
</div>
{% else %}
{# Show a deadline message if the limit is reached or the deadline has passed! #}
<div class="form-closed-message">
<p>This form is now closed 🙇♀️</p>
</div>
{% endif %}
{% endif %}
{% endfor %}
Using if current_submissions < submission_limit and today < deadline_timestamp ensures that the form is only displayed if neither the submission count nor the deadline has been reached.
Serverless Functions
const HUBSPOT_PRIVATE_APP_TOKEN = process.env.FORM_LIMIT_MANAGER; // Set the token in an environment variable!
exports.main = async (context = {}, sendResponse) => {
try {
const body = context.body || {};
const formGuid = body.form_guid;
const tableId = 'YOUR_TABLE_ID'; // Specify the HubDB table ID
if (!formGuid) {
return sendResponse({ statusCode: 400, body: { message: 'form_guid is missing from the request' } });
}
// Fetch HubDB row data and find the corresponding form_guid
const recordsResponse = await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/rows`, { ... });
const records = await recordsResponse.json();
const targetRecord = records.results.find(record => record.values.form_guid = formGuid);
if (!targetRecord) {
return sendResponse({ statusCode: 404, body: { message: 'Corresponding record not found' } });
}
// Prepare to increment the current submission count by 1!
const rowResponse = await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/rows/${targetRecord.id}`, { ... });
const rowData = await rowResponse.json();
const updatedValues = {
...rowData.values,
current_submissions: (targetRecord.values.current_submissions || 0) + 1
};
// Update to draft...
await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/rows/${targetRecord.id}/draft`, { ... });
// Then publish to finalize!
await fetch(`https://api.hubapi.com/cms/v3/hubdb/tables/${tableId}/draft/publish`, { ... });
return sendResponse({ statusCode: 200, body: { message: 'Submission count updated and published', newCount: updatedValues.current_submissions } });
} catch (error) {
return sendResponse({ statusCode: 500, body: { message: 'An error occurred', error: error.message } });
}
};
serverless.json (Example)
{
"runtime": "nodejs18.x",
"version": "1.0",
"secrets": ["FORM_LIMIT_MANAGER"],
"endpoints": {
"update-form-submissions": { "method": "POST", "file": "form-limit-updater.js" }
}
}
This serverless function is triggered by a form submission event, executing a request that increments the value of the "current_submissions" column in HubDB by 1.
Points of Caution ⚡
-
deadline/max_submissionsrequire manual management. - When handling multiple forms, you need to be strategic about how
form_guidis specified on the template side. - Be careful not to mess up the flow of updating HubDB drafts and then publishing them.
Summary ✨
Even "submission limits & deadline control," which were difficult with standard HubSpot features alone, can be achieved with a little customization!
By building a solid mechanism, managing events and workshops becomes much easier 🌸

Related Reading 📚
- Part 1 (Design of limits and mechanism overview): https://blog.ryamagami.com/hubspot-limit_form_01
- Overview of Serverless Functions: https://developers.hubspot.jp/docs/guides/cms/content/data-driven-content/serverless-functions/overview
Discussion