Field-tested tools for naturalist photographers.

Built by a naturalist with 2,000+ species in the life list and a decade behind the lens. inat-tools makes software that connects your fieldwork to your workflow.

Add hero photo or product screenshot in the page Featured Image or custom fields.

Our Tools

Available Now — Founding User Price: $4.99

Your Lightroom catalog finally speaks iNaturalist.

iNat Publish Pro is a Lightroom Classic plugin that syncs your iNaturalist observations directly into your photo catalog. Species names, full taxonomic hierarchies, GPS data, research-grade status — all matched to the right photos automatically.

Learn more

More tools on the way.

We're building a suite of tools for people who take their fieldwork seriously. Join the list to get early access as new tools ship.

Join the list to get early access

Stay in the field loop.

New tools, updates, and the occasional dispatch from the field. No spam — just the stuff that matters if you're a naturalist who uses a camera.

Newsletter signup

Just simple MailerLite form!

Please wait...

Thank you for sign up!

var selectedLanguage = ""; var validationMessages = messages["en"]; if(selectedLanguage) { validationMessages = messages[selectedLanguage]; } window.addEventListener("load", function () { var form_container = document.querySelector(`#mailerlite-form_2[data-temp-id="69b7a7914a8fd"] form`); let submitButton = form_container.querySelector('.mailerlite-subscribe-submit'); submitButton.disabled = true; fetch('https://inat-tools.com/wp-admin/admin-ajax.php', { method: 'POST', headers:{ 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ "action" : "ml_create_nonce", "ml_nonce" : form_container.querySelector("input[name='ml_nonce']").value }) }) .then((response) => response.json()) .then((json) => { if(json.success) { form_container.querySelector("input[name='ml_nonce']").value = json.data.ml_nonce; submitButton.disabled = false; } }) .catch((error) => { console.error('Error:', error); }); form_container.addEventListener('submit', (e) => { e.preventDefault(); let data = new URLSearchParams(new FormData(form_container)).toString(); let validationError = false; document.querySelectorAll('.mailerlite-form-error').forEach(el => el.remove()); Array.from(form_container.elements).forEach((input) => { if(input.type !== 'hidden') { if(input.required) { if(input.value == '') { validationError = true; let error = document.createElement("span"); error.className = 'mailerlite-form-error'; error.textContent = validationMessages.required; input.after(error); return false; } } if((input.type == "email") && (!validateEmail(input.value))) { validationError = true; let error = document.createElement("span"); error.className = 'mailerlite-form-error'; error.textContent = validationMessages.email; input.after(error); return false; } } }); if(validationError) { return false; } fade.out(form_container.querySelector('.mailerlite-subscribe-button-container'), () => { fade.in(form_container.querySelector('.mailerlite-form-loader')); }); fetch('https://inat-tools.com/wp-admin/admin-ajax.php', { method: 'POST', headers:{ 'Content-Type': 'application/x-www-form-urlencoded', }, body: data }) .then((response) => { fade.out(form_container.querySelector('.mailerlite-form-inputs'), () => { fade.in(form_container.querySelector('.mailerlite-form-response')); }); }) .catch((error) => { console.error('Error:', error); }); }); }, false); var fade = { out: function(el, fn = false) { var fadeOutEffect = setInterval(function () { if (!el.style.opacity) { el.style.opacity = 1; } if (el.style.opacity > 0) { el.style.opacity -= 0.1; } else { el.style.display = 'none'; clearInterval(fadeOutEffect); } }, 50); if( typeof (fn) == 'function') { fn(); } }, in: function(el) { var fadeInEffect = setInterval(function () { if (!el.style.opacity) { el.style.opacity = 0; } if (el.style.opacity < 1) { el.style.opacity = Number(el.style.opacity) + 0.1; } else { el.style.display = 'block'; clearInterval(fadeInEffect); } }, 50); } }; function validateEmail(email){ if(email.match( /^(([^()[\]\\.,;:\s@\"]+(\.[^()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ )) { return true; } return false; }

We'll never share your email. Unsubscribe anytime.