Bulk Validation Methods

Both pages now use /hub/developer/salesforce/... links for everything in our docs. There are 34 links, and every target returned 200. The only external link left is the Salesforce OAuth guide on the REST page, which your existing REST pages also link to.

Every type now links to its own page: all input and output models, AddressOptions_v1, Address_v1, Advice_v1, Status_v1, the PhoneFormat_v1 and PhoneType_v1 enums, the single-item REST and Apex method pages, saveValidationResult and rv2SaveValidationResultInput_v1.

Written for: integrators reading the Plauti developer hub.

REST API page

The /v1/bulk/validate endpoint validates addresses, phone numbers and email addresses in a single request. Each item is validated the same way as with the address, phone and email validation endpoints, and every result is returned under the identifier you chose for it.

Key Points

  • Send any combination of addresses, phone numbers and email addresses in one request, for example two addresses, one phone number and three email addresses.
  • Every item is keyed by an identifier you choose, such as billing, mobile or a record ID. The response uses the same identifiers.
  • Each item uses the same input fields as the single endpoints and returns the same output as those endpoints, including validation advice (GREEN, AMBER or RED).
  • An address without a country is validated against your default country, like the address validation endpoint does.

Authentication

The validateBulk endpoint requires authentication via Salesforce OAuth 2.0. Requests must include a valid OAuth access token in the Authorization header.

For detailed authentication steps, refer to: Salesforce Authentication Guide.

Method Signature

HTTP
POST /services/apexrest/recordval/v1/bulk/validate

Parameters

Type Variable Description
BulkValidationInput_v1 bulkInput The structured input object containing the addresses, phone numbers and email addresses to validate.

Input

BulkValidationInput_v1

Field Type Required Description
addresses Map of String to AddressValidationInput_v1 No The addresses to validate, keyed by an identifier of your choice.
phones Map of String to PhoneValidationInput_v1 No The phone numbers to validate, keyed by an identifier of your choice.
emails Map of String to EmailValidationInput_v1 No The email addresses to validate, keyed by an identifier of your choice.
note String No A custom note for logging or reference purposes. Applies to the whole request. When left empty, api is used.

The request must contain at least one address, phone number or email address. Identifiers can not be empty.

Address item: AddressValidationInput_v1

Field Type Required Description
street String No The street address to be validated.
housenumber String No The primary house number of the address.
housenumberAddition String No Additional details for the house number (e.g., unit or suite).
postalCode String No The postal or ZIP code for the address.
city String No The city where the address is located.
state String No The state or region of the address.
country String No The country code or name for the address. When left empty, the default country is used.
latitude String No The latitude coordinate, used for geocoding if provided.
longitude String No The longitude coordinate, used for geocoding if provided.
addressOptions AddressOptions_v1 No Customization options for address parsing and validation. See below.

The fields note, convertToSuggestionStatus and addressOptions.includeMunicipalityFromAddresses are not supported per item in a bulk request and are ignored. Use the note on BulkValidationInput_v1 instead.

AddressOptions_v1

Field Type Required Description
housenumber Boolean No Return the house number as a separate field instead of as part of the street. Default: false.
housenumberAddition Boolean No Return the house number addition as a separate field. Default: false.
geocode Boolean No Return latitude and longitude for the address. Default: false.
addressSeparator String No The separator used between address lines in fullAddress. When left empty, the separator from your Verify settings is used.

Phone item: PhoneValidationInput_v1

Field Type Required Description
phoneNumber String Yes The phone number to be validated.
country String No The country associated with the phone number for validation.
format PhoneFormat_v1 No The format in which the validated phone number is returned: E164, INTERNATIONAL, NATIONAL or RFC3966. Default: E164.

Email item: EmailValidationInput_v1

Field Type Required Description
emailAddress String Yes The email address to be validated.

Example Request

JSON
{
  "note": "Validating a new Lead",
  "addresses": {
    "billing": {
      "street": "Stationsplein 1",
      "postalCode": "3511 ED",
      "city": "Utrecht",
      "country": "NL",
      "addressOptions": {
        "housenumber": true,
        "geocode": true
      }
    }
  },
  "phones": {
    "mobile": {
      "phoneNumber": "0612345678",
      "country": "NL",
      "format": "INTERNATIONAL"
    }
  },
  "emails": {
    "work": {
      "emailAddress": "[email protected]"
    }
  }
}

Output

Return Type: BulkValidationOutput_v1

Field Type Description
addresses Map of String to AddressValidationOutput_v1 The address results, keyed by the identifiers from the request.
phones Map of String to PhoneValidationOutput_v1 The phone results, keyed by the identifiers from the request.
emails Map of String to EmailValidationOutput_v1 The email results, keyed by the identifiers from the request.
status Status_v1 The status of the request as a whole. Code 850 means the request was processed. Each item carries its own status and advice.

Each item result is the same object the single validation endpoints return:

Example Response

JSON
{
  "status": {
    "message": "BulkItem Validation Succeeded.",
    "credit": false,
    "code": "850"
  },
  "addresses": {
    "billing": {
      "status": {
        "message": "Current address is verified up to Street. Suggestion contains an improved, verified address up to Street.",
        "credit": true,
        "code": "533"
      },
      "advice": "GREEN",
      "addresses": [
        {
          "street": "Stationsplein",
          "housenumber": "1",
          "housenumberAddition": null,
          "postalCode": "3511 ED",
          "city": "Utrecht",
          "state": "Utrecht",
          "stateCode": "Utrecht",
          "country": "Nederland",
          "countryCode": "NL",
          "fullAddress": "Stationsplein 1, 3511 ED  Utrecht",
          "latitude": "52.090268744737",
          "longitude": "5.11167580457016",
          "geoStatus": {
            "message": "Medium confidence match between the location and the geocode. The location is one of several possible geopoint matches, making the result ambiguous.",
            "credit": true,
            "code": "711"
          },
          "status": {
            "message": "Current address is verified up to Street. Suggestion contains an improved, verified address up to Street.",
            "credit": true,
            "code": "533"
          },
          "advice": "GREEN"
        }
      ]
    }
  },
  "phones": {
    "mobile": {
      "status": {
        "message": "Current phone number is correct. Suggestion contains an improved, standardised phone number.",
        "credit": true,
        "code": "102"
      },
      "phoneNumber": "+31 6 12345678",
      "phoneType": "MOBILE",
      "countryCode": "NL",
      "advice": "GREEN"
    }
  },
  "emails": {
    "work": {
      "status": {
        "message": "Email is correct, but can’t be associated with a particular person.",
        "credit": true,
        "code": "313"
      },
      "complete": "[email protected]",
      "addressee": "info",
      "domain": "plauti.com",
      "free": false,
      "disposable": false,
      "advice": "GREEN"
    }
  }
}

Error Responses

HTTP Status Body Cause
400 input must contain at least one address, phone or email. The request contains no items.
400 addresses identifiers can not be null or empty. (or phones / emails) An item has an empty identifier.
400 phoneNumber can not be null or empty. A phone item has no phone number.
400 emailAddress can not be null or empty. An email item has no email address.
500 The error message The validation service could not be reached or returned an error.
500 Internal server error The request body is missing or is not valid JSON for this endpoint.

Apex API page

The validateBulk method validates addresses, phone numbers and email addresses in Salesforce in a single call. Each item is validated the same way as with the validateAddress, validatePhone and validateEmail methods, and every result is returned under the identifier you chose for it.

This method works with the saveValidationResult method to store the validation outcome in Salesforce. The item results are the same output objects the single validation methods return, so each one can be saved to the field it belongs to.

Key Points

  • Accepts a BulkValidationInput_v1 object with maps of addresses, phone numbers and email addresses, each keyed by an identifier of your choice.
  • Makes one callout for all items, instead of one callout per item.
  • Returns a BulkValidationOutput_v1 object with the same identifiers, holding an AddressValidationOutput_v1, PhoneValidationOutput_v1 or EmailValidationOutput_v1 per item.
  • An address without a country is validated against your default country, like the validateAddress method does.

Method Signature

Method name: validateBulk

Apex
global recordval.BulkValidationOutput_v1 validateBulk(recordval.BulkValidationInput_v1 bulkInput)

Parameters

Type Variable Description
BulkValidationInput_v1 bulkInput The structured input object containing the addresses, phone numbers and email addresses to validate.

Input

BulkValidationInput_v1

The maps are created empty by the constructor, so items can be added with put directly.

Field Type Required Description
addresses Map<String, recordval.AddressValidationInput_v1> No The addresses to validate, keyed by an identifier of your choice. See AddressValidationInput_v1.
phones Map<String, recordval.PhoneValidationInput_v1> No The phone numbers to validate, keyed by an identifier of your choice. See PhoneValidationInput_v1.
emails Map<String, recordval.EmailValidationInput_v1> No The email addresses to validate, keyed by an identifier of your choice. See EmailValidationInput_v1.
note String No A custom note for logging or reference purposes. Applies to the whole call. When left empty, api is used.

The input must contain at least one address, phone number or email address. Identifiers can not be empty, and the maps can not contain null values.

Address item: AddressValidationInput_v1

Field Type Required Description
street String No The street address to be validated.
housenumber String No The primary house number of the address.
housenumberAddition String No Additional details for the house number (e.g., unit or suite).
postalCode String No The postal or ZIP code for the address.
city String No The city where the address is located.
state String No The state or region of the address.
country String No The country code or name for the address. When left empty, the default country is used.
latitude String No The latitude coordinate, used for geocoding if provided.
longitude String No The longitude coordinate, used for geocoding if provided.
addressOptions recordval.AddressOptions_v1 No Customization options for address parsing and validation: housenumber, housenumberAddition and geocode (Boolean, default false), and addressSeparator (String; default from your Verify settings).

The fields note, convertToSuggestionStatus and addressOptions.includeMunicipalityFromAddresses are not supported per item in a bulk call and are ignored. Use the note on BulkValidationInput_v1 instead.

Phone item: PhoneValidationInput_v1

Field Type Required Description
phoneNumber String Yes The phone number to be validated.
country String No The country associated with the phone number for validation.
format recordval.PhoneFormat_v1 No The format in which the validated phone number is returned: E164, INTERNATIONAL, NATIONAL or RFC3966. Default: E164.

Email item: EmailValidationInput_v1

Field Type Required Description
emailAddress String Yes The email address to be validated.

Output

Return Type: BulkValidationOutput_v1

Field Type Description
addresses Map<String, recordval.AddressValidationOutput_v1> The address results, keyed by the identifiers from the input. See AddressValidationOutput_v1.
phones Map<String, recordval.PhoneValidationOutput_v1> The phone results, keyed by the identifiers from the input. See PhoneValidationOutput_v1.
emails Map<String, recordval.EmailValidationOutput_v1> The email results, keyed by the identifiers from the input. See EmailValidationOutput_v1.
status recordval.Status_v1 The status of the call as a whole. Code 850 means the call was processed. Each item carries its own status and advice (Advice_v1).

Exceptions

Exception Cause
recordval.IllegalApiArgumentException The input is null or has no items, an identifier is empty, a map contains a null value, a phone item has no phoneNumber, or an email item has no emailAddress.
recordval.APICallException The validation service could not be reached or returned an error. The error is in the message field.

Save Validation Result

The saveValidationResult method saves the outcome of a validation (status, status message, advice) directly to a Salesforce record. Save each item result to the field it belongs to, the same way as with the single validation methods, using rv2SaveValidationResultInput_v1. For implementation details, see the saveValidationResult Class Reference.

Apex Example

This Apex code retrieves a Lead's email address and phone number, validates both in one call using validateBulk, logs the results, and saves the email validation outcome in Salesforce using saveValidationResult.

Apex
// Ask for a Lead ID
String leadId = '00QAa00000JinjeMAB'; // Replace with actual Lead ID

// Query the Lead's Email and Phone
Lead leadRecord = [SELECT Id, Email, Phone, Country FROM Lead WHERE Id = :leadId LIMIT 1];

// Initialize the Record Validation API
recordval.RecordValidationAPI_v1 api = new recordval.RecordValidationAPI_v1();

// Prepare the bulk validation input, one item per field
recordval.BulkValidationInput_v1 input = new recordval.BulkValidationInput_v1();
input.note = 'Validating Lead ID: ' + leadId;

if (String.isNotBlank(leadRecord.Email)) {
    recordval.EmailValidationInput_v1 email = new recordval.EmailValidationInput_v1();
    email.emailAddress = leadRecord.Email;
    input.emails.put('Email', email);
}

if (String.isNotBlank(leadRecord.Phone)) {
    recordval.PhoneValidationInput_v1 phone = new recordval.PhoneValidationInput_v1();
    phone.phoneNumber = leadRecord.Phone;
    phone.country = leadRecord.Country;
    phone.format = recordval.PhoneFormat_v1.INTERNATIONAL;
    input.phones.put('Phone', phone);
}

// Execute the bulk validation
recordval.BulkValidationOutput_v1 output;
try {
    output = api.validateBulk(input);
} catch (recordval.IllegalApiArgumentException e) {
    System.debug('Nothing to validate: ' + e.getMessage());
    return;
} catch (recordval.APICallException e) {
    System.debug('Bulk validation failed: ' + e.message);
    return;
}

// Log the results, per identifier
for (String fieldName : output.emails.keySet()) {
    recordval.EmailValidationOutput_v1 result = output.emails.get(fieldName);
    System.debug(fieldName + ': ' + result.getAdvice() + ' (' + result.status.code + ' ' + result.status.message + ')');
}
for (String fieldName : output.phones.keySet()) {
    recordval.PhoneValidationOutput_v1 result = output.phones.get(fieldName);
    System.debug(fieldName + ': ' + result.phoneNumber + ' ' + result.getPhoneType() + ' ' + result.getAdvice());
}

// Save the email validation result
if (output.emails.containsKey('Email')) {
    recordval.rv2SaveValidationResultInput_v1 saveRequest = new recordval.rv2SaveValidationResultInput_v1();
    saveRequest.setRecordId(leadId);
    saveRequest.setValidationResult('Email', output.emails.get('Email'));

    recordval.rv2SaveValidationResultOutput_v1 saveResult = api.saveValidationResult(saveRequest);
    System.debug('Validation result saved: ' + saveResult.success);
}