Artemis now offers Participate Energy Prepaid Lease.
Learn more →

Frustrated by slow quoting and endless manual tasks, we built a faster way to bring solar to market.

For years, installers dealt with clunky tools, long design turnaround times, and fragmented workflows. We believed the industry deserved better – tools that move at the speed homeowners expect and deliver the accuracy teams rely on.

Clean energy should feel simple, instant, and trustworthy — for both customers and installers.
Our team has spent years inside solar: designing systems, scaling installation operations, and building AI-first products. We’ve lived the bottlenecks firsthand. Artemis is the platform we wished existed.

So we merged world-class AI, embedded financing, and real-time quoting into one unified platform. Instant designs, customer-facing quoting, integrated financing, contract automation, and post-sale workflows — all in one place. What once required 5–7 separate tools now happens in seconds.

Today, fast-growing local installers and national leaders use Artemis to transform how they design, sell, and operate.

Whether you’re running a lean team or managing multiple markets, Artemis helps you design faster, sell smarter, and deliver projects with fewer errors and less overhead.
Behind Artemis is a team with deep roots in solar and AI — constantly improving the platform.

Built by experts from Tesla, Shell Ventures, the Canadian Space Agency, and leading AI research labs — and validated by DNV, NREL, and top lenders — Artemis is designed to support installers today and prepare them for the next decade of distributed energy.

If you're ready to accelerate sales, reduce software spend, and deliver a better customer experience, we’re here to help you scale.

We know solar and AI.

Our team combines decades of experience in solar energy and state-of-the-art AI research

Walid Halty

CEO

Scaled Tesla (previously SolarCity) to highest performing division during tenure. Co-founded Colossus.com (Acquired by PX)

Brittany Bartel

COS

10+ years of operations experience, previously at Sunpro (acquired by ADT)

Juan Carrillo

CTO

Prior AI researcher at University of Toronto, Waterloo, and Canadian Space Agency

Ethan Hackett

Head of Design

25+ years of marketing and application design – Rackspace & Clearbit

Jonathan Leung

CMO

Helped scale Momentum Solar to largest privately-held solar company

Jacob Rhyner

Vice President of Sales

Sales VP in residential solar sales since 2019. Scaled Monalee Solar across 18 states.

Alexander Urban

CFO

Deployed >$200m in energy startups over 8 years as an investor with Shell's VC group

Experience From

Our Team

10 PhD researchers

Specializing in AI, geographic information systems, photogrammetry, remote sensing, and geomatics

18+ engineers & designers

We’re backed by leading investors in Tech & Energy

Ready to get started?

Get a live demo
Have a question?
Contact sales
// Initialize Lenis const lenis = new Lenis({ lerp: 0.1, }); // Listen for the scroll event and log the event data lenis.on(‘scroll’, (e) => { console.log(e); }); // Use requestAnimationFrame to continuously update the scroll function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } requestAnimationFrame(raf); gsap.registerPlugin(ScrollTrigger); const splitTypes = document.querySelectorAll(‘.scroll-highlight’); splitTypes.forEach((char, i) => { const text = new SplitType(char, { types: [‘chars’, ‘words’] }); gsap.from(text.chars, { scrollTrigger: { trigger: char, start: ‘top 50%’, end: ‘top 10%’, scrub: 1, }, opacity: 0.2, stagger: 0.1, }); }); new WordPlay({ className: “h-2”, // the text element mode: “letter”, // choose between letter or word offset: 20, // offset if revealed by scroll speed: 0.7, delay: 0.015, // stagger delay }); .skip-link { position: absolute; top: -100px; left: 0; background: #000; color: white; padding: 10px 15px; z-index: 1000; text-decoration: none; } .skip-link:focus { top: 10px; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } document.addEventListener(“DOMContentLoaded”, function () { const page = document.querySelector(“.page-container”); if (!page) { console.log(“No .page-container found”); return; } document.addEventListener(“click”, function (event) { const t1 = event.target.closest(“.link-trigger-1”); const t2 = event.target.closest(“.link-trigger-2”); // Click inside link-trigger-1 if (t1) { console.log(“Clicked link-trigger-1 → overflow: clip”); page.style.overflow = “clip”; // if this does nothing in your browser, use “hidden” } // Click inside link-trigger-2 if (t2) { console.log(“Clicked link-trigger-2 → overflow: visible”); page.style.overflow = “visible”; // or “auto”/”hidden” depending on what you want } }); }); (function() { // Configuration var config = { autoplayDelay: 2300, // Time between auto-advances (ms) transitionSpeed: 600 // Slide transition duration (ms) }; // State var isTransitioning = false; var autoplayInterval = null; var track = null; var slides = []; var slideWidth = 0; var currentOffset = 0; var leftBuffer = 2; // Initialize function init() { track = document.getElementById(‘reviewBadgeTrack’); if (!track) return; track.style.visibility = ‘hidden’; slides = Array.from(track.querySelectorAll(‘.review-badge-carousel__slide’)); if (slides.length === 0) { track.style.visibility = ‘visible’; return; } calculateDimensions(); for (var i = 0; i < leftBuffer; i++) { var lastSlide = slides.pop(); slides.unshift(lastSlide); track.insertBefore(lastSlide, track.firstChild); } centerCurrentSlide(false); updateActiveStates(); requestAnimationFrame(function() { track.style.visibility = 'visible'; startAutoplay(); }); window.addEventListener('resize', handleResize); track.addEventListener('click', handleSlideClick); track.parentElement.addEventListener('mouseenter', stopAutoplay); track.parentElement.addEventListener('mouseleave', startAutoplay); } function calculateDimensions() { if (slides.length === 0) return; var firstSlide = slides[0]; var style = getComputedStyle(firstSlide); var width = firstSlide.offsetWidth; var marginLeft = parseFloat(style.marginLeft); var marginRight = parseFloat(style.marginRight); slideWidth = width + marginLeft + marginRight; } function centerCurrentSlide(animate) { var viewportCenter = window.innerWidth / 2; var slideCenter = slideWidth / 2; currentOffset = viewportCenter – slideCenter – (leftBuffer * slideWidth); if (animate) { isTransitioning = true; track.style.transition = 'transform ' + config.transitionSpeed + 'ms ease'; } else { track.style.transition = 'none'; track.offsetHeight; // Force reflow } track.style.transform = 'translateX(' + currentOffset + 'px)'; } function updateActiveStates() { slides.forEach(function(slide, i) { var isVisible = i <= (leftBuffer + 2); if (i === leftBuffer) { slide.classList.add('active'); } else { slide.classList.remove('active'); } slide.style.visibility = isVisible ? 'visible' : 'hidden'; }); } function nextSlide() { if (isTransitioning || slides.length === 0) return; isTransitioning = true; currentOffset -= slideWidth; track.style.transition = 'transform ' + config.transitionSpeed + 'ms ease'; track.style.transform = 'translateX(' + currentOffset + 'px)'; setTimeout(handleTransitionEnd, config.transitionSpeed); } function handleTransitionEnd() { var firstSlide = slides.shift(); slides.push(firstSlide); track.appendChild(firstSlide); currentOffset += slideWidth; track.style.transition = 'none'; track.offsetHeight; // Force reflow track.style.transform = 'translateX(' + currentOffset + 'px)'; updateActiveStates(); isTransitioning = false; } function prevSlide() { if (isTransitioning || slides.length === 0) return; isTransitioning = true; var lastSlide = slides.pop(); slides.unshift(lastSlide); track.insertBefore(lastSlide, track.firstChild); currentOffset -= slideWidth; track.style.transition = 'none'; track.offsetHeight; // Force reflow track.style.transform = 'translateX(' + currentOffset + 'px)'; updateActiveStates(); currentOffset += slideWidth; requestAnimationFrame(function() { track.style.transition = 'transform ' + config.transitionSpeed + 'ms ease'; track.style.transform = 'translateX(' + currentOffset + 'px)'; setTimeout(function() { isTransitioning = false; }, config.transitionSpeed); }); } function startAutoplay() { stopAutoplay(); autoplayInterval = setInterval(nextSlide, config.autoplayDelay); } function stopAutoplay() { if (autoplayInterval) { clearInterval(autoplayInterval); autoplayInterval = null; } } function handleSlideClick(e) { var slide = e.target.closest('.review-badge-carousel__slide'); if (!slide || isTransitioning) return; var clickedIndex = slides.indexOf(slide); if (clickedIndex === leftBuffer) return; if (clickedIndex === leftBuffer + 1) { nextSlide(); } else if (clickedIndex === leftBuffer – 1) { prevSlide(); } } var resizeTimeout; function handleResize() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(function() { calculateDimensions(); centerCurrentSlide(false); }, 100); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })(); function getUrlParams() { const params = new URLSearchParams(window.location.search); let utmParams = {}; const list = [‘utm_source’, ‘utm_medium’, ‘utm_campaign’, ‘utm_term’, ‘utm_content’]; list.forEach(param => { if (params.has(param)) { const val = params.get(param); utmParams[param] = val; document.cookie = `${param}=${val}; path=/;`; } }); return utmParams; } function getUtmFromCookies() { const cookies = document.cookie.split(‘; ‘).reduce((acc, cookie) => { const [key, value] = cookie.split(‘=’); acc[key] = value; return acc; }, {}); let utmParams = {}; const list = [‘utm_source’, ‘utm_medium’, ‘utm_campaign’, ‘utm_term’, ‘utm_content’]; list.forEach(param => { if (cookies[param]) { utmParams[param] = cookies[param]; } }); return utmParams; } function fillUtmFields() { let utmData = getUrlParams(); if (Object.keys(utmData).length === 0) { utmData = getUtmFromCookies(); } Object.keys(utmData).forEach(key => { const input = document.querySelector(`input[name=”${key}”]`); if (input) { input.value = utmData[key]; } }); } document.addEventListener(“DOMContentLoaded”, fillUtmFields);