Salesforce VAT Validation

Salesforce has no standard VAT number field; teams store VAT numbers in custom text fields on Account records, and nothing validates them. Sales reps enter whatever they have, and the data goes unverified into invoices, opportunity records, and ERP syncs.

This guide shows how to validate VAT numbers inside Salesforce using Apex HTTP callouts, Named Credentials, and the Avatcado REST API. You will also learn how to write the validated company name back to Account records.

The integration pattern

Avatcado is a REST API that accepts a VAT number and returns the validation status, the registered company name, and the country code. In Salesforce, you call it via an Apex HTTP callout. You can trigger the callout from an Apex trigger, a Flow action, or a custom button on the Account page.

The flow is: Account record is created or updated with a VAT number → Apex callout to Avatcado → parse the response → update Account fields with the result.

Setting up a Named Credential

Named Credentials store the endpoint URL and authentication details so you do not hardcode API keys in Apex. Salesforce injects the credentials automatically when your code references the Named Credential.

To set up a Named Credential for Avatcado:

  • Go to Setup → Named Credentials → External Credentials. Create a new External Credential with the authentication protocol set to "Custom".
  • Add a Principal. In the principal's authentication parameters, store your API key as a parameter named ApiKey.
  • Create a Named Credential that references this External Credential. Set the base URL to https://api.avatcado.com.
  • On the Named Credential, add a Custom Header named Authorization with the formula {!'Bearer ' & $Credential.Avatcado.ApiKey}. Uncheck "Generate Authorization Header" and check "Allow Formulas in HTTP Header".
  • Create a Permission Set that grants access to the External Credential principal. Assign it to the users or integration user that will run the callout.

Apex callout example

The following Apex class makes a GET request to the Avatcado validate endpoint and returns a parsed result. It uses the Named Credential so the Authorization header is injected automatically.

public class VatValidationService {

    public class VatResult {
        public Boolean valid;
        public String companyName;
        public String countryCode;
    }

    public static VatResult validate(String vatNumber) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(
            'callout:Avatcado_API/v1/validate?vat_number='
            + EncodingUtil.urlEncode(vatNumber, 'UTF-8')
        );
        req.setMethod('GET');
        req.setHeader('Accept', 'application/json');

        Http http = new Http();
        HttpResponse res = http.send(req);

        VatResult result = new VatResult();

        if (res.getStatusCode() == 200) {
            Map<String, Object> body = (Map<String, Object>)
                JSON.deserializeUntyped(res.getBody());
            Map<String, Object> data = (Map<String, Object>)
                body.get('data');
            result.valid = (Boolean) data.get('valid');
            result.countryCode = (String) data.get('country_code');

            Map<String, Object> company = (Map<String, Object>)
                data.get('company');
            if (company != null) {
                result.companyName = (String) company.get('name');
            }
        } else {
            result.valid = false;
        }

        return result;
    }
}

Writing the result back to Account

Once you have the validation result, update the Account record with custom fields. A common pattern uses two fields: a checkbox VAT_Validated__c and a text field Registered_Company_Name__c.

You can call the VatValidationService.validate() method from:

  • An Apex trigger on Account (after insert or after update on the VAT number field). Be careful: Apex triggers cannot make synchronous callouts directly. Use a @future(callout=true) method or a Queueable to make the callout asynchronously.
  • A Flow action. Annotate a wrapper method with @InvocableMethod so Flow can call it. This lets admins add VAT validation to any Flow without writing additional Apex.
  • A custom button or Lightning action on the Account page, letting sales reps validate on demand.

Test mode

Avatcado has a test mode with magic VAT numbers so you can build and test in a Salesforce sandbox without hitting live government APIs. Use an API key prefixed with avat_test_ instead of avat_live_.

Magic numbers like DE111111111 always return valid, and DE000000000 always return invalid. No quota is consumed in test mode. See the documentation for the full list of test numbers.

Get started

Create a free Avatcado account →

Read the API documentation for the full endpoint reference. For a broader overview of CRM integration patterns, see the CRM validation guide.

Frequently asked questions

Does Salesforce validate VAT numbers natively?

No. Salesforce does not even have a standard VAT number field: teams store VAT numbers in custom text fields on Account records, and nothing in the platform validates what goes into them against VIES, HMRC, or any other government database. Sales reps enter whatever they have, and the unverified value flows into invoices, opportunity records, and ERP syncs. Validation requires a callout to an external API, and Salesforce gives you several places to hang it: an Apex trigger on Account (using a @future(callout=true) method or a Queueable, since triggers cannot make synchronous callouts directly), a Flow action backed by an @InvocableMethod so admins can wire validation into any Flow, or a custom button or Lightning action so reps can validate on demand. A common field pattern is a VAT_Validated__c checkbox plus a Registered_Company_Name__c text field, populated from the Avatcado response so the account carries both the verdict and the registry's official company name.

Do I need to be a Salesforce developer to set this up?

The Apex callout approach requires Salesforce development experience: you write an Apex class that calls the Avatcado endpoint, configure a Named Credential (an External Credential, a principal holding the API key, a custom Authorization header formula, and a Permission Set granting access), and handle the trigger context restrictions around callouts. Once a developer has done that groundwork, though, day-to-day use can be admin-friendly: exposing the callout through an @InvocableMethod lets admins add VAT validation to any Flow without touching Apex again, and a custom button puts on-demand validation in reps' hands. If your org has no developer capacity at all, skip Apex entirely: Zapier or Make can call the Avatcado REST API through their HTTP modules and write results back to Salesforce records with no code, triggered by new or updated records. The trade-off is that the no-code route runs outside Salesforce, on the automation tool's schedule, rather than inside your org's own automation.

Can I test this in a Salesforce sandbox?

Yes, and you should build it there first. Avatcado's test mode is designed for exactly this: use an API key prefixed avat_test_ instead of avat_live_ in your sandbox's Named Credential, and magic VAT numbers return deterministic results without hitting live government APIs. DE111111111 always returns valid and DE000000000 always returns invalid, so you can assert both branches of your Apex logic, the Account field updates on success and the handling of an invalid number, in repeatable tests. No quota is consumed in test mode, so sandbox runs never eat into your monthly validations. The response shape is identical to live mode, which means the JSON parsing in your Apex service class works unchanged when you promote to production; the deployment delta is just swapping the test key for a live key in the production Named Credential. The full list of magic numbers and simulated error scenarios is documented at docs.avatcado.com.

Sources

Related guides