Blog / Product Brand Operations
Wholesale Application Form That Scores and Answers Itself (Google Forms + Sheets)
By Keyona Meeks, Founder, ReRev Labs · Oct 31, 2026 · 9 min read
The short answer: Build the form in Google Forms and send its answers to a Google Sheet. Then add a short Google Apps Script that runs each time someone submits. It adds up a fit score from rules you write, labels the application Strong fit, Possible fit or Low fit, emails you one summary and sends the applicant a receipt. A person still reads every application and decides. The score only sorts the pile.
By the end of this post, you'll be able to:
- Choose the questions a wholesale form needs, and which answers are worth points.
- Send form answers to a Google Sheet.
- Install a script that scores each application, emails you and replies to the applicant.
- Test it, and know what can stop it from running.
A brand opens wholesale. Applications arrive by email, a contact form and Instagram messages. Some are stores with a real shop and a clear order. Some are a name and a question. Someone has to read all of them, write back to all of them and remember who got what answer.
A form fixes the first half of that. It asks the same questions of everyone. A sheet and a script fix the second half. The sheet holds every application in one place, and the script does the sorting and the first reply. This post builds that, using Google tools you may already have.
The results I saw for this search on October 30, 2026 were mostly form-builder template pages. They give you fields to copy. This post adds what happens after someone presses submit.
What questions should a wholesale inquiry form ask?
Ask only what you will use. Every question you ask should change what you do next, and a long form can cost you applicants. A starting set:
| Question | Type | Why it is there |
|---|---|---|
| Business name | Short answer | So you know who it is |
| Contact name | Short answer | For the reply |
| Short answer | For the reply | |
| Business type | Multiple choice | Retail store, Online store, Restaurant or cafe, Reseller or distributor, Other |
| Expected first order | Multiple choice | Three ranges that match your minimum order, in your currency |
| Website | Short answer | A way to see the business. Optional |
| Anything else we should know | Paragraph | Optional. The script does not score it |
Two cautions. First, write the choices so they match how you sell. If your minimum is different from the example, change the ranges. Second, do not collect sensitive numbers in a form, such as tax IDs or resale certificate numbers, unless you have a plan for who can open the sheet. I would ask for those in a later step, once you decide to open an account. That is my suggestion, not a legal rule. Check what your state or your accountant requires.
How do you send the form answers to a Google Sheet?
Google's help page gives the steps. In Google Forms: open your form, click Responses, then the Summary tab. At the top right, click More, then Select destination for responses. Choose Create a new spreadsheet or Select existing spreadsheet, then click Create or Select. Source: Google's help page on choosing where to save form responses, checked October 30, 2026.
The same page says later permission changes on the form do not carry over to the sheet. Anyone who can open the sheet can read every application, so set its sharing on purpose.
Each form question becomes a column in the sheet. The script reads the answers by question title, so the titles in the script must match the titles in your form exactly.
How does a script score and reply to each application?
Apps Script can run a function every time the form lands a row in the sheet. Google's docs describe the event the function receives. It includes namedValues, "An object containing the question names and values from the form submission," and values, an "Array with values in the same order as they appear in the spreadsheet." It also includes range, which Google describes as "A Range object, representing the cell or range of cells that were edited." Source: Event Objects in Google's Apps Script guide, checked October 30, 2026.
The script uses namedValues to read each answer by its question, and range to find the row to write the score into.
It needs an installable trigger, because sending email needs authorization. Google's docs say installable triggers "can call services that require authorization" and "always run under the account of the person who created them." Source: Installable Triggers, checked October 30, 2026. So the emails go out from the account that installs the trigger. Use an address you are happy to send from.
If you have not used Apps Script before, read what Google Apps Script is first.
What do the points mean?
You choose them. In the example, a retail store scores 3, an online store 3, a restaurant or cafe 2, a reseller or distributor 2 and Other 0. A larger expected first order scores 1, 2 or 3. A website scores 2. A total of 6 or more is a Strong fit, 3 to 5 is a Possible fit and anything lower is a Low fit.
These numbers are examples. I do not know your products, your minimums or your customers. Set them so the labels match what you would say if you read the application yourself, then check a handful of real ones.
Install the script
- In the response sheet, click Extensions, then Apps Script.
- Delete what is in the editor and paste the code below.
- Change the settings at the top: your email, your company name, the form question titles and the points.
- Click Save.
- In the function list, choose
setupWholesaleTriggerand click Run. Google asks you to allow the script. Read what it asks for and approve it if you agree.
// Score a wholesale application and reply to it. Paste into Extensions > Apps Script
// in the Google Sheet that receives your form responses.
const CONFIG = {
OWNER_EMAIL: 'you@yourcompany.com', // gets one email per application
FROM_NAME: 'Your Company Wholesale', // name shown on the reply
EMAIL_QUESTION: 'Email', // each value below must match a form question title exactly
NAME_QUESTION: 'Contact name',
BUSINESS_QUESTION: 'Business name',
SCORING: [
{ question: 'Business type', points: {
'Retail store': 3, 'Online store': 3, 'Restaurant or cafe': 2,
'Reseller or distributor': 2, 'Other': 0 } },
{ question: 'Expected first order', points: {
'Under 250': 1, '250 to 1,000': 2, 'Over 1,000': 3 } },
{ question: 'Website', ifFilled: 2 }
],
STRONG_AT: 6, // this score or higher = Strong fit
MAYBE_AT: 3, // this score or higher = Possible fit; below = Low fit
REPLY_TEXT: {
'Strong fit': 'Thanks for applying. We have your application and a person will read it and write to you within [your timeframe].',
'Possible fit': 'Thanks for applying. We have your application and a person will read it and write to you within [your timeframe].',
'Low fit': 'Thanks for applying. We have your application. A person will read it and write to you if we can set up an account.'
}
};
function onWholesaleSubmit(e) {
const sheet = e.range.getSheet();
const row = e.range.getRow();
const answers = e.namedValues;
const get = function (q) {
return answers[q] && answers[q][0] ? String(answers[q][0]).trim() : '';
};
const scoreCol = ensureColumn_(sheet, 'Fit score');
const labelCol = ensureColumn_(sheet, 'Fit label');
const sentCol = ensureColumn_(sheet, 'Reply sent');
if (sheet.getRange(row, sentCol).getValue() !== '') return;
const score = scoreApplication_(get);
const label = score >= CONFIG.STRONG_AT ? 'Strong fit'
: score >= CONFIG.MAYBE_AT ? 'Possible fit' : 'Low fit';
sheet.getRange(row, scoreCol).setValue(score);
sheet.getRange(row, labelCol).setValue(label);
const business = get(CONFIG.BUSINESS_QUESTION) || '(no business name)';
const body = Object.keys(answers).map(function (q) {
return q + ': ' + get(q);
}).join('\n');
MailApp.sendEmail({
to: CONFIG.OWNER_EMAIL,
subject: label + ' (' + score + '): wholesale application from ' + business,
body: body + '\n\nSheet row: ' + row
});
const email = get(CONFIG.EMAIL_QUESTION);
if (/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
const name = get(CONFIG.NAME_QUESTION);
MailApp.sendEmail({
to: email,
replyTo: CONFIG.OWNER_EMAIL,
name: CONFIG.FROM_NAME,
subject: 'We received your wholesale application',
body: (name ? 'Hi ' + name + ',\n\n' : 'Hello,\n\n') + CONFIG.REPLY_TEXT[label]
});
sheet.getRange(row, sentCol).setValue(new Date());
} else {
sheet.getRange(row, sentCol).setValue('No valid email, no reply sent');
}
}
function scoreApplication_(get) {
let total = 0;
CONFIG.SCORING.forEach(function (rule) {
const answer = get(rule.question);
if (rule.points) {
total += rule.points[answer] || 0;
} else if (rule.ifFilled && answer !== '') {
total += rule.ifFilled;
}
});
return total;
}
function ensureColumn_(sheet, header) {
const lastCol = sheet.getLastColumn();
const headers = sheet.getRange(1, 1, 1, lastCol).getValues()[0];
const i = headers.map(function (h) { return String(h).trim(); }).indexOf(header);
if (i !== -1) return i + 1;
sheet.getRange(1, lastCol + 1).setValue(header);
return lastCol + 1;
}
function setupWholesaleTrigger() {
ScriptApp.getProjectTriggers().forEach(function (t) {
if (t.getHandlerFunction() === 'onWholesaleSubmit') ScriptApp.deleteTrigger(t);
});
ScriptApp.newTrigger('onWholesaleSubmit')
.forSpreadsheet(SpreadsheetApp.getActive())
.onFormSubmit()
.create();
}
On its first run for a row, the script adds three columns to the end of the sheet if they are missing: Fit score, Fit label and Reply sent. It fills Reply sent with the time the reply went out. If that cell already has a value, the script skips the row, so a re-run does not send a second reply.
What the script does
- Scores. It adds up the points for each answer that matches a rule. An answer with no rule scores nothing.
- Labels. It turns the total into Strong fit, Possible fit or Low fit using the two cutoffs you set.
- Emails you. One email per application, with the label and score in the subject and every answer in the body.
- Replies to the applicant. It sends a short receipt that says a person will read the application. It uses the reply text you set for that label and sets your address as the reply-to.
- Handles a bad email address. If the Email answer does not look like an address, it sends you the summary, sends no reply and writes that in
Reply sent.
Write the reply text yourself. I left [your timeframe] as a placeholder because I do not know how fast you answer. Do not promise a speed you will not keep.
How do you test it before you trust it?
I tested the script with made-up answers in a mock harness and a syntax check. I did not run it in a live Google account. Test it on a copy of the form and sheet:
- Submit the form once with answers that should score as a Strong fit, using an email address you own.
- Check that the sheet row gets a score, a label and a time in
Reply sent, and that you got the summary email. - Check that the reply arrived in your inbox and shows the reply-to address you set.
- Submit once with the lowest answers and check the label is Low fit.
- Submit once with a bad email address and check that no reply goes out.
- Open Executions in the Apps Script editor if anything fails, and read the error.
Three things I could not confirm without a live account: that e.range points to the new row in every case, that the three new columns land where you expect when the form has many questions, and how the reply looks in each mail app. Test those on your own copy.
What if the form changes later?
The script finds answers by question title. If you rename a question in the form, change the same text in the script. If the title no longer matches, the answer reads as empty and scores nothing, and nothing warns you. After any edit to the form, submit a test response.
Add new questions at the end of the form, then check where they land in the sheet next to the three columns the script added.
Can you build this without Google Forms?
Yes. If your wholesale page lives on your own site, the same sheet and script can sit behind your own form, as long as the form writes its answers into the sheet as a row with the same column titles. That part depends on your site, so I am not describing it here. I did not test it.
Where does an LLM fit in this?
Not in the scoring. Points from fixed choices are a rule, and a rule gives the same answer every time, which is what you want when you explain why an application was labeled Low fit. An LLM could help with the free-text box, such as summarizing a long "Anything else" answer for you, and a person should read the original too. The stance I use: AI writes the code, plain automation runs it, and an LLM shows up only where the input is messy and a person checks the result.
Where this has limits
- The score is a sort, not a decision. A Low fit label means the form answers did not match your rules. It does not mean the buyer is a bad one. The example reply tells every applicant a person will read their application, so make that true.
- Your rules can be biased. If the points reward a business type or order size that you favor, you will favor it without noticing. Read a sample of each label every month.
- The script is untested in a live account. Test it on a copy first.
- Quotas apply. Apps Script limits how many emails a script can send each day. On the quotas page I read on October 30, 2026, the limit was 100 recipients a day for consumer accounts and 1,500 for Google Workspace accounts. Each application uses two. Limits change, so see Google's quotas page.
- Auto-replies and email rules. Keep the reply to a receipt and a next step. If you add promotions, rules for commercial email apply, and they depend on where you and the buyer live. The FTC's CAN-SPAM compliance guide for business is the US starting point, checked October 30, 2026. Check with an attorney if you are unsure.
- Access to the sheet. Anyone with access can read every application. Limit who can open it.
- Spam. A public form can be filled by bots. This post does not cover spam filtering.
If you are moving pieces of your business onto your own accounts and want a hand, you can apply for the free rebuild on /letstalk. Bring a list of the tools you pay for and which one you would replace first. Do not send passwords or login details.
If you are weighing which paid tools to drop, read how to replace paid software subscriptions. To decide what to fix first, read what to automate first in a small business.
Frequently asked questions
What is a wholesale inquiry form?
It is a form a store, restaurant or reseller fills out to ask about buying from you at wholesale prices. It collects the details you need to decide whether to open an account.
Do I need Typeform or another paid form tool for this?
Not for this. Google Forms is free with a Google account and sends answers to a Google Sheet. Paid form tools can offer more design control. Whether that is worth paying for depends on what you use.
Can I score applications without code?
You can add a formula column to the sheet that adds points, and sort by it. The script adds the automatic label, the emails and the reply, so you do not have to check the sheet to know a new application arrived.
Will the buyer see the score?
No. The score and label go in the sheet and in your email. The reply to the buyer is a plain receipt that does not mention the score.
Can the form set up their account automatically?
Not in this post. The form and script sort and reply. Opening an account is a decision for a person, and it usually needs checks that this script does not do.
What if someone applies twice?
Each submission is a new row and gets its own score and reply. The script does not detect duplicates. Sort the sheet by business name or email to spot them.
Why did the script not send a reply?
Check the Reply sent cell for that row. It may say the email did not look valid, or the row may have been skipped because the cell already had a value. If nothing ran, open Executions in the Apps Script editor and read the error.
Read next: Remind wholesale accounts to reorder once the new accounts this form approves start ordering, and operations automation for product brands for the rest of the order-side work.