Validating UK VAT and company numbers in Zoho CRM with a client script
To validate UK VAT and company numbers in Zoho CRM, add three client scripts to the Accounts page. Two scripts check the format of each number when the user leaves the field. A third script blocks the save if either number is still wrong. This catches typing errors when the account is created, not months later on an invoice.
A client script is a piece of JavaScript that runs in the user's web browser rather than on Zoho's server. Zoho describes it in its Client Script overview. Because the code runs in the browser, it reacts instantly to what the user types on the page.
This guide is the first of three UK posts on Zoho CRM automation with code. It covers the client script, which checks format on screen. A workflow function that checks a company against Companies House is the better choice when you need to confirm the company itself. A weekly scheduled Companies House check suits records you already hold. Both are covered in later posts in this set.
A format check has one honest limit. It tells you a number has the right shape. It cannot tell you the number is real, current or belongs to the business in front of you. The next section explains how to close that gap.
A format check is not a validity check
A format check confirms that a number has the right number of digits and an allowed prefix. It does not confirm that HMRC or Companies House issued that number to this business. HMRC's own staff manual makes the same point about its format checker. The HMRC enquiry manual on false invoices says the checker "can only confirm whether a VAT registration number complies with the required format". It adds that it "cannot check whether the number is a current valid registration number, or whether it belongs to the person who is using it."
The same manual names the most reliable method: the UK VAT number checker. On GOV.UK this is the free Check a UK VAT number service. It tells you whether a number is valid and shows the name and address of the business it is registered to. You need the number itself, because you cannot search by business name. If you are VAT-registered, you can also use the service to prove when you checked, using your own VAT number.
These three checks differ in what they confirm and where they happen:
| Check | What it confirms | Where it runs |
|---|---|---|
| Client script format check | Length, digits and prefix look right | Zoho CRM Accounts page, in the browser |
| GOV.UK Check a UK VAT number | The VAT number is valid, plus the registered name and address | GOV.UK, by hand |
| Companies House check | The company number matches a registered company | A workflow function, covered in a later post |
One timing detail matters. HMRC's manual warns that its databases may not yet include VAT registrations made within the last 48 hours.
UK VAT registration number formats the script accepts
A UK VAT registration number is 9 numbers, sometimes with GB at the start. That is how HMRC's design pattern for the VAT registration number puts it, with the examples 123456789 and GB123456789. HMRC's enquiry manual agrees: all UK VAT registration numbers have nine digits.
Some businesses use an XI prefix instead of GB. GOV.UK says you need a VAT registration number starting with XI to trade under the Northern Ireland Protocol. Once HMRC confirms eligibility, the business uses XI before its usual number, for example XI 123456789 instead of GB 123456789. The details are on the GOV.UK page on selling goods between Northern Ireland and the EU.
HMRC's design pattern gives three rules worth copying into Zoho CRM:
- Use a single text input that accepts 9 numbers with or without spaces or GB.
- Remove the spaces before validating.
- Label the field "VAT registration number", not "VAT number".
The script in this guide strips spaces, dots and hyphens, turns letters to capitals and saves the tidied value. It keeps the GB or XI prefix, because an XI number tells your finance team something useful.
The reference pattern is slightly wider than the 9-digit rule. It also lets through a 12-digit form and a GD form with three digits. The HMRC pages used for this guide describe only the 9-digit form, so keep or remove those branches as your own policy decides. HMRC's manual also says the last two digits come from a standard formula applied to the other seven. The formula is not published in those pages, so the script does not attempt it.
Companies House company number formats the script accepts
A Company Registration Number, or CRN, is the unique number Companies House gives a company. HMRC's manual page on company registration numbers says a CRN cannot change even if the company changes its name or registered office address. That makes it the most stable identifier you can hold on an account record. HMRC itself uses CRNs for data matching and risk assessment.
The same manual describes the format. A CRN is up to eight numerals, or normally a two-letter prefix followed by up to six alphanumeric characters. The reference script is stricter than that description, and you should know where the two differ. It accepts:
- eight digits, such as 01234567;
- two letters followed by exactly six digits, such as SC123456;
- R0 followed by six digits.
The script also restores leading zeros. If a user types 1234567, it saves 01234567. Spreadsheets often drop that zero, and a number missing it will not match anything later.
The strictness is a choice. A suffix with letters in it passes HMRC's description but fails the script. If your customers include such companies, widen the pattern after testing.
Foreign companies need a decision too. HMRC's manual says the FC prefix is used only for foreign companies registered with Companies House in England and Wales. It adds that a numeric CRN issued by another country should never be given an FC prefix. HMRC sets up those companies with no CRN at all. Your team can follow the same rule and leave the field empty.
Client script requirements: edition, permissions and layouts
Client Script is available in the Professional, Enterprise and Ultimate editions of Zoho CRM. The person building the scripts needs a profile with Developer Permissions enabled. Both requirements come from Zoho's Client Script overview.
Client Script supports only JavaScript. A script runs in response to an event, which Zoho defines as a user action in the Zoho CRM client. This guide uses two kinds of event:
- A field onChange event runs when the user leaves the field, by clicking outside it or moving to another field. It does not run while the user is still typing.
- A page onSave event runs after the user clicks Save or Save and New, but before the record is saved. Ending the script with
return falsestops the save.
Zoho also offers an onType event, which fires as each character is typed. For number checks, onChange is kinder. Nobody wants an error after typing the first digit.
Layouts matter. According to Zoho's Client Script FAQs, a script runs only for the layout chosen when it was configured. If your Accounts module has two layouts, you need a copy of each script for each layout.
The execution timeout is 10 seconds. These scripts only read and write fields on the page, so they finish well inside that limit.
Step 1: create the two custom fields on Accounts
The scripts need two single-line text fields on the Accounts layout. Create one labelled "VAT registration number" and one labelled "Company number". Use text fields, not number fields. A number field would strip the leading zero from 01234567 and reject the GB prefix.
The code refers to each field by its API name, not its label. The reference code uses VAT_Number and Company_Number. These are examples. Your org may give the fields different API names, especially if similar fields already exist. Check the API name of each field after you create it and change the code to match.
If you are still building the Accounts layout, the Zoho CRM setup checklist for a UK firm covers fields and layouts in order. The guide to customising your CRM explains the wider options.
Make both fields optional unless your process truly needs them. HMRC's design pattern says that if there is a good reason to ask for a VAT registration number but the user does not have to enter one, the field should be optional. Plenty of small customers are not VAT-registered. A mandatory field invites staff to type a made-up number just to save.
Build and test everything in a sandbox first, not in your live org. The scripts can block saves, and a mistake would stop your whole team creating accounts.
Step 2: the VAT registration number onChange script
The first script checks the VAT registration number when the user leaves that field. In Setup, go to Developer Hub, then Client Script. Create a script for the Accounts module, choose your layout and the Create page, and pick a field event of type onChange on the VAT field. Paste this code into the editor:
var vatField = ZDK.Page.getField('VAT_Number');
var raw = (value === null || value === undefined) ? '' : String(value);
var vat = raw.replace(/[\s.\-]/g, '').toUpperCase();
// GB or XI optional; 9 digits, or 12 digits; legacy GD + 3 digits
var vatPattern = /^((GB|XI)?(\d{9}|\d{12})|(GB)?GD\d{3})$/;
if (vat !== '') {
if (vat !== raw) { vatField.setValue(vat); }
if (!vatPattern.test(vat)) {
vatField.showError(
'UK VAT numbers are 9 digits, optionally after GB or XI, e.g. GB123456789.'
);
}
}
In the script, value holds the new value of the field. The script removes spaces, dots and hyphens, turns letters into capitals and writes the tidied value back with setValue. It then tests the result against the pattern and shows an error under the field if it fails.
Here is a worked example. A user types "gb 123 456 789" and tabs out. The field changes to GB123456789 and no error appears. If the user types "GB12345678", with one digit missing, the error message appears straight away.
Two lines are yours to change. Replace 'VAT_Number' with your own field's API name. Edit the message text if you prefer HMRC's wording, "Enter your VAT registration number in the correct format". Empty values are ignored, so the field stays optional.
Repeat the same script for the Edit page, so corrections to existing accounts are checked too.
Step 3: the company number onChange script
The second script checks the Companies House number when the user leaves that field. Create it the same way: Accounts module, your layout, the Create page, a field onChange event, this time on the company number field. Paste this code:
var crnField = ZDK.Page.getField('Company_Number');
var raw = (value === null || value === undefined) ? '' : String(value);
var crn = raw.replace(/\s/g, '').toUpperCase();
// 8 digits, or 2-letter prefix + 6 digits (SC, NI, OC, SO, NC, LP, SL, NL ...)
var crnPattern = /^(\d{8}|[A-Z]{2}\d{6}|R0\d{6})$/;
if (crn !== '') {
// England and Wales numbers are eight digits: restore dropped leading zeros
if (/^\d{1,7}$/.test(crn)) { crn = ('00000000' + crn).slice(-8); }
if (crn !== raw) { crnField.setValue(crn); }
if (!crnPattern.test(crn)) {
crnField.showError(
'Company numbers are 8 digits, or 2 letters and 6 digits, e.g. SC123456.'
);
}
}
The script removes spaces and capitalises letters. If the result is one to seven digits only, it pads the number with leading zeros to eight digits. It then writes the tidied value back and tests it against the pattern.
The worked example continues. A user pastes "1234567" from a spreadsheet. The field becomes 01234567 and passes. Another user types "sc 12345", with a digit missing. The field becomes SC12345 and the error appears, because the pattern needs six digits after the two letters.
Change 'Company_Number' to your own API name. If you decide to accept letters in the suffix, as HMRC's description allows, the crnPattern line is the one to widen. Test any change against real numbers from your customer list before you enable it. Then repeat the script for the Edit page.
Step 4: the onSave script that blocks a bad save
The third script stops an account being saved while either number has the wrong format. The onChange scripts only warn. A user can ignore a warning and click Save, so this script is the gate. Create a page event of type onSave on the Accounts Create page for your layout, and paste this code:
var vatField = ZDK.Page.getField('VAT_Number');
var crnField = ZDK.Page.getField('Company_Number');
var vat = String(vatField.getValue() || '').replace(/[\s.\-]/g, '').toUpperCase();
var crn = String(crnField.getValue() || '').replace(/\s/g, '').toUpperCase();
if (/^\d{1,7}$/.test(crn)) { crn = ('00000000' + crn).slice(-8); }
var vatPattern = /^((GB|XI)?(\d{9}|\d{12})|(GB)?GD\d{3})$/;
var crnPattern = /^(\d{8}|[A-Z]{2}\d{6}|R0\d{6})$/;
var blocked = false;
if (vat !== '' && !vatPattern.test(vat)) {
vatField.showError('Check the VAT number format: 9 digits, optionally starting GB or XI.');
blocked = true;
}
if (crn !== '' && !crnPattern.test(crn)) {
crnField.showError('Check the company number format: 8 digits, or 2 letters and 6 digits.');
blocked = true;
}
if (blocked) {
ZDK.Client.showMessage('Not saved: check the VAT or company number.', { type: 'error' });
return false;
}
The script reads both fields with getValue, tidies them the same way as the onChange scripts and tests them against the same patterns. If either fails, it shows the error under the field and a message at the top of the page. The final return false is what stops the save, as Zoho's Client Script events documentation describes.
Change both API names to match your fields. If you edit a pattern in Step 2 or Step 3, copy the same change here. Two scripts with different patterns would warn about one thing and block another.
Repeat the script for the Edit page. That means an old account with a badly formatted number will be blocked the next time someone edits it.
Test, enable and know what the client script cannot guard
Test each script in the sandbox before you enable it. Try a clean number, a number with spaces, a lower-case prefix, a number with a digit missing and an empty field. Then enable the scripts and repeat the tests while signed in as an ordinary user without admin rights. That is how your sales team will meet them.
Clean your existing data before you switch on the onSave script. When Svennis adds format checks like these for clients, we export the current VAT and company numbers and correct them first. Otherwise the onSave script blocks staff the first time they edit an old account, and they blame the CRM rather than the data.
A client script guards the screen and nothing else. Zoho's documentation and the way the code runs leave these gaps:
- Quick Create: Zoho's FAQs say Client Script cannot currently run in the Quick Create page.
- Imports: records loaded from a file never pass through the Create page.
- The API and integrations: records written by another system skip the browser entirely.
- Web forms: a form submission creates the record without the page.
- Other layouts: a script runs only for the layout it was configured for.
Zoho also notes that Client Script works automatically in Zoho CRM portals, so portal users meet the same checks.
For records that arrive outside the page, a server-side check is the better tool. The later posts in this set cover a workflow function and a weekly Companies House check for exactly that.
What verified VAT and company numbers mean for a UK company
For a UK company, a clean VAT registration number and company number on each account save work downstream. Finance teams use the VAT number on invoices and VAT records. If it is wrong in the CRM, the error travels into billing, for example in Zoho Books. Our post on keeping VAT lines right in Zoho Books shows how much depends on those details being correct.
Northern Ireland trade needs particular care. GOV.UK says a business trading under the Protocol must use its XI number on all documentation with EU customers or suppliers, including invoices. It also warns that not using an XI number could mean paying or charging the wrong VAT on goods. Keeping the XI prefix on the account, as this script does, gives your finance team that signal.
Checks against false numbers still need a person or a later automation. HMRC's own manual says a VAT registration number on an invoice may be false. A format check will pass a well-shaped false number. For new suppliers or large customers, run the number through Check a UK VAT number and keep a record of when you checked.
The company number supports matching. Because a CRN never changes when a company renames or moves, it lets you match an account to Companies House records reliably. It also helps you spot duplicate accounts. Duplicates are a common result of a customer renaming itself.
Next steps for checking VAT and company numbers in Zoho CRM
Start with the smallest change that protects new records. A practical order is:
- Confirm your Zoho CRM edition is Professional, Enterprise or Ultimate, and that your profile has Developer Permissions.
- Create the two text fields on Accounts in a sandbox and note their API names.
- Export existing VAT and company numbers and fix the badly formatted ones.
- Add the two onChange scripts and the onSave script for each layout, on the Create and Edit pages.
- Test as a non-admin user, then enable in your live org.
- Decide who checks new VAT numbers on GOV.UK, and when.
If you are newer to the platform, the intermediate Zoho CRM guide covers the layouts and automation this post assumes. When your records also arrive through imports, integrations or web forms, a client script alone will not be enough. The later posts in this set cover the server-side checks.
If you would rather have the fields, scripts and data clean-up built and tested for you, see how we approach Zoho CRM implementation and consulting in the UK.
Sources
- Zoho CRM: Client Script - An Overview
- Zoho CRM: Client Script Events
- Zoho CRM: Client Script - FAQs
- HMRC: EM3058 Examining Accounts: False Invoices
- GOV.UK: Check a UK VAT number
- HMRC design patterns: VAT registration number
- GOV.UK: Register for VAT: Selling or moving goods between Northern Ireland and the EU
- HMRC: COM40011 Company registration numbers


