Skip to main content
Top down view of a medical research scientist in blue rubber gloves using a microscope next to a tablet with virus data displayed

Chemical Data Management

Identify and mitigate risks in a changing regulatory and compliance landscape with ease by combining supply chain and chemical data management software and tailored testing services.

Contact us

 

Maintain chemical compliance and achieve supply chain transparency

Warehouse manager using a laptop inside a warehouse

 

 

 

Chemical compliance is not just a manufacturer’s responsibility; it’s the duty of every link of the chemical supply chain — and the right services can help you identify and mitigate risks in a changing regulatory and compliance landscape.   

Assess your supply chain more effectively. Test your products more scientifically. UL Solutions helps you do both.

 

8,000+

lists of global regulations and substance data

600,000+

chemical substances included

27

customized SDS and labeling templates

50+

global regulatory experts

1.7

million UPCs supported

 

We help manufacturers and supply chain partners manage chemical compliance

A smart chemical compliance strategy should start with supply chain and chemical data management software that helps you proactively tackle the complex requirements of regulators, retailers and consumers.

When it comes time to take finished goods to market, our testing services — based on the latest safety science — helps you provide reassurance about overall chemical compliance.

 

 

Passing inspection report icon

Chemical compliance and data management

Our software and advisory services help you meet regulatory compliance obligations and manage product-related data.

 

 

icon connectivity

Supply chain assessment

Our software helps you find innovative new raw materials, screen potential partners and collect critical compliance information thoroughly, quickly and securely.

 

 

Document icon with a checkmark

Trusted, independent testing

Our global network of laboratories tests your products so you can provide reassurance to regulators and buyers.

 

 

WERCSmart Powers Kroger’s Product Compliance Program

We’re here for manufacturers, retailers and consumers in search of more sustainable products. Right now, Kroger is using UL Solutions software to evaluate product assortments against internal chemical policies and restricted substance lists. We’re proud that our software helps this major retailer select products for their sustainable product curation program.

 

“Since using WERCSmart, ItemSync and ItemScan as product onboarding and auditing tools, we now can quickly identify compliance gaps in our selling channels.”

Peg Chandler, senior manager, Enterprise Environmental Compliance, Kroger

Kroger logo
Read the case study

Judith Haber

Chemical expert and technical manager  

Judith Haber is recognized as a global leader in technical chemistry, with more than 30 years in safety science. At UL Solutions, she has developed and validated many test methods used within our organization and by our customers worldwide. Haber is responsible for understanding the implications of emerging regulations and how test methods must align to support evolving chemical compliance needs. She presents frequently on established and emerging chemical issues, including chemicals of concern. 

Regulatory Roundup Newsletter

Stay up to date on chemical regulatory news

Subscribe to our monthly Regulatory Roundup Newsletter and stay up to date on current and upcoming regulations and all the latest chemical industry news. 

Subscribe now

 

Frequently asked questions

How can better supply chain assessment help mitigate chemical compliance risks?

Supply chains have never been so complex. But the right supply chain transparency software can help quickly uncover risks from all your current and potential supply chain partners. Learn how Supply Chain Network collects and protects critical product data and helps uncover chemical risks.

Does UL Solutions perform testing for chemicals of concern, such as PFAS, PFOA and phthalates?

Yes, UL Solutions supports manufacturers who need to comply with evolving regulations around chemicals of concern through comprehensive testing services in locations worldwide. We can help you tailor a testing strategy specific for your portfolio.

In addition, we offer software, like PurView®, which performs data analysis regarding chemicals of concern that can help you anticipate and mitigate risk.

Can UL Solutions help us demonstrate compliance with regulations such as REACH or RoHS, identify SVHCs or meet PFAS requirements?

Absolutely. We help manufacturers tackle regulatory issues through chemical regulatory advisory services and training, including market readiness reports, label reviews, chemical policy development and management, and Restricted Substances List support.

Does UL Solutions have software for managing chemical regulatory data?

WERCS Studio, our industry-leading software, is powered by ChemADVISOR® regulatory data and makes it easy to automate and centralize compliance data.

How can we improve product development through better chemical data management?

For manufacturers looking to develop safer, more sustainable products, UL Solutions provides material and ingredient discovery tools like UL Prospector® that scans 260,000+ materials across 10 industries to help you find the products you need to create and enhance products.

X

Get in touch

Have questions, need specifics? Let's get this conversation started.

Please wait…
'; let submitButton = $('form.mktoForm .mktoButtonWrap .mktoButton'); submitButton.prop("disabled", true); submitButton.append(loadingHTML); // Ocp-Apim-Subscription-Key: '***'. var $ocpKey = drupalSettings.ul_marketo_validate_key; var $ocpUrl = drupalSettings.ul_marketo_validate_url; var $ocpEnv = drupalSettings.ul_marketo_validate_env; if (submitCount > 1 || isResponseSuccess == true) { isResponseHandled = true; form.submittable(true); if (paramsDebug.debug == 1) { console.log("NO.10 submitCount > 1: form.submit() "); } submitButton.click(); } else { var email = form.vals().Email; var phone = (form.vals().Phone) ? (form.vals().Phone) : '18472728800'; var country = (form.vals().Country) ? (form.vals().Country) : 'United States'; var countryCode = (phone == '18472728800') ? 'US' : getCountryCode(country); var $emailMsg = drupalSettings.ul_marketo_validate.email; var $phoneMsg = drupalSettings.ul_marketo_validate.phone; if (paramsDebug.debug == 1) { console.log("paramsDebug:"); console.log(paramsDebug); } sendingData = JSON.stringify({ 'Input_Email': email, 'Input_Phone': phone, 'Input_ISO2_Country_Code': countryCode }); if (paramsDebug.debug == 1) { console.log('URL, debug missing button:'); console.log($ocpUrl); console.log("Sending Data to API service (ajax):"); console.log(sendingData); } // API call for validate email/phone/country. var sendDate = (new Date()).getTime(); var responseTimeMs = sendDate; // Start a timer to handle a 3-second response timeout setTimeout(function() { if (!isResponseHandled) { isResponseHandled = true; // Handle the assumed "success" due to timeout here if (paramsDebug.debug == 1) { console.log('No response within timeout, proceeding with default validation success.'); } $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); // set form to be submittable here $('#valSpinner').remove(); submitButton.prop("disabled", false); // Setup status as Timeout instead of Unknown. emailAddressStatus = "Timeout"; phoneNumberStatus = "Timeout"; phoneNumberValidated = "Timeout"; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); form.submittable(true); isResponseSuccess = true; if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("setTimeout: " + responseTimeMs + " seconds."); } submitButton.click(); } }, paramsDebug.timeout * 1000); //END setTimeout $.ajax({ url: $ocpUrl, type: 'POST', data: sendingData, headers: { 'Content-Type': 'application/json', 'Ocp-Apim-Subscription-Key': $ocpKey, }, success: function (response) { $('#valSpinner').remove(); submitButton.prop("disabled", false); phoneNumberValidated = response.Validated_Phone_Number; if (!isResponseHandled) { isResponseHandled = true; // **** Handle the validation response if (paramsDebug.debug == 1) { console.log("API Response Data: "); console.log(response); } var emailCode = response.Email_Validation_Status_Number; var phoneCode = response.Phone_Validation_Status_Number; // Add values into two status fields. if (emailValidCode.hasOwnProperty(emailCode)) { emailAddressStatus = emailValidCode[emailCode]; } else { // API error code doesn't exist, set defaul. emailAddressStatus = emailValidCode['300']; } if (phoneValidCode.hasOwnProperty(phoneCode)) { phoneNumberStatus = phoneValidCode[phoneCode]; } else { // API error code doesn't exist, set defaul. phoneNumberStatus = phoneValidCode['301']; } if (emailAddressStatus.indexOf("email_not") != -1) { emailAddressStatus = 'Invalid'; } else if(emailAddressStatus == 'valid') { emailAddressStatus = 'Valid'; } if (phoneNumberStatus.indexOf('invalid_') != -1) { phoneNumberStatus = 'Invalid'; } else if(phoneNumberStatus == 'valid') { phoneNumberStatus = 'Valid'; } if (paramsDebug.debug == 1) { console.log('form.emailAddressStatus ' + emailAddressStatus); console.log('form.phoneNumberStatus ' + phoneNumberStatus); console.log('form.phoneNumberValidated ' + phoneNumberValidated); } if (validEmailCode.includes(emailCode) && validPhoneCode.includes(phoneCode)) { // Remove the loading spinner. $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); $('#valSpinner').remove(); submitButton.prop("disabled", false); if (paramsDebug.debug == 1) { console.log("NO.1.1 VALID OK submitCount = " + submitCount); } isResponseSuccess = true; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); form.submittable(true); submitButton.click(); } // API valid code is not "valid". else { form.submittable(false); if (paramsDebug.debug == 1) { console.log("NO.1.2 Submittable false : count= " + submitCount + " validateOrigin " + validateOrigin + " isResponseSuccess " + isResponseSuccess ); } // Set the invalid message in language translation. var msgEmailStatus = ""; if (!validEmailCode.includes(emailCode)) { if (emailCode == '300' || emailCode == '400') { msgEmailStatus = $emailMsg.email_not_valid; } else if (emailCode == '310' || emailCode == '500' ) { msgEmailStatus = $emailMsg.email_not_accept; } else { msgEmailStatus = "Unknown"; } if (paramsDebug.debug == 1) { console.log("NOT validEmailCode: " + msgEmailStatus); } errEmail = ''; $('#Email').after(errEmail); form.submittable(false); } // Set the invalid message in language translation. var msgPhoneStatus = "" if (!validPhoneCode.includes(phoneCode)) { msgPhoneStatus = $phoneMsg[phoneValidCode[phoneCode]]; if (paramsDebug.debug == 1) { console.log("NOT validPhoneCode: " + msgPhoneStatus); } errPhone = ''; $('#Phone').after(errPhone); form.submittable(false); } if (paramsDebug.debug == 1) { console.log(msgEmailStatus); console.log(msgPhoneStatus); } // Remove the loading spinner. $('#valSpinner').remove(); submitButton.prop("disabled", false); if (paramsDebug.debug == 1) { console.log("NO.1.6 Submittable false, count= " + submitCount); } form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); // 2nd API call and subit form. if (submitCount >= 1) { $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); isResponseSuccess = true; form.submittable(true); if (paramsDebug.debug == 1) { console.log("NO.1.8 : 2nd Submit:: submittable=true && count=1 : " + submitCount); } if (submitCount==1) { submitButton.click(); } } } //END if{} else{}. }//END if (!isResponseHandled) // Calculate the time comsumed for the API call. if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("NO.1.9 : AJAX success: Time for API call: " + responseTimeMs + " seconds."); } submitCount++; }, //END success: function(); // API call error response. error: function (error) { $('#valSpinner').remove(); submitButton.prop("disabled", false); if (!isResponseHandled) { isResponseHandled = true; $('#valSpinner').remove(); submitButton.prop("disabled", false); // 2nd API call and subit form. if ( submitCount >= 1 ) { $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); form.submittable(true); isResponseSuccess = true; if ( submitCount == 1 ) { form.submittable(true); } } // Handle AJAX error if (paramsDebug.debug == 1) { console.log('**** 2 ajax error. submitCount = ' + submitCount); console.log(error); } // Calculate the time comsumed for the API call. if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("NO.2.3 AJAX error: Time for API call: " + responseTimeMs + " seconds."); } } submitCount++; // Error status 500, then submit the form. submitButton.click(); } //END error: function(); }); //END $.ajax; if (isResponseSuccess) { if (paramsDebug.debug == 1) { console.log("NO.8.0 submittable(true)"); } form.submittable(true); } } //END: if (submitCount > 1) else // Setup the form.vals and form.submittable; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); } //END: if (validateOrigin && (marketoBundle)) else { // For Event form and Newsletter form. if (validateOrigin === true){ form.submittable(true); } } }); //END form.onValidate() // Success callback() form.onSuccess(function(values, followUpUrl){ // Debug Phone/Email validation. if (paramsDebug.debug == 1) { console.log("NO.9.1 onSuccess: submittable = " + form.submittable()); console.log(form.getValues()); } // Track analytics. if (typeof dataLayer !== 'undefined'){ dataLayer.push({ event: drplMkto.dataLayerEvent, mktoFormId: form.getId(), 'FormValues': cleanFormVals(form.getValues()), 'FormFields': form.allFieldsFilled(), 'Submittable': form.submittable() }); } // If function exists, delete UTM cookie: if(typeof _deleteUtmCookie === "function"){ _deleteUtmCookie(); } // Marketo Modal "Thank You" message: if(use_post_submit_mssg){ $('html, body').animate({ scrollTop: 0 }, 'slow'); $('.mkto-presubmit').addClass('hidden'); $('.mktoModalContent').addClass('mkto_thnx_center'); $('.mktoModalMask').addClass('not_clicable'); $('.mkto-postsubmit').removeClass('hidden'); $('.mktoButton').removeAttr('disabled').text(drupalSettings.marketo.button_text); $('.mktoForm')[0].reset(); grecaptcha.reset(); } // Else, redirect user: else { window.location.href = drplMkto.success_url; } // IMPORTANT: Return false to prevent further code execution. return false; }); //END form.onSuccess. }); })(jQuery, drupalSettings.marketo);