diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java b/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java
index 449c5ec3a3dce6c42291dc8f652ba32d9e2839ec..acf6f397be7c46698dcf77398973498104b931bb 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java
@@ -166,6 +166,7 @@ public class ServletUtil {
     var svcResponse = ResponseBody.error()
         .name(name)
         .url(url)
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .request(url)
         .response(msg)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java
index a4e527bf761e48133bd97b69362b0d5b5591f4c9..8a41630eafe3eb942596e0562f42a12ce8026f0a 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java
@@ -28,7 +28,9 @@ import gov.usgs.earthquake.nshmp.calc.Site;
 import gov.usgs.earthquake.nshmp.geo.Location;
 import gov.usgs.earthquake.nshmp.gmm.Imt;
 import gov.usgs.earthquake.nshmp.model.HazardModel;
+import gov.usgs.earthquake.nshmp.www.HazVersion;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
+import gov.usgs.earthquake.nshmp.www.ResponseMetadata;
 import gov.usgs.earthquake.nshmp.www.ServletUtil;
 import gov.usgs.earthquake.nshmp.www.hazard.HazardService.Metadata;
 import gov.usgs.earthquake.nshmp.www.meta.Parameter;
@@ -73,6 +75,7 @@ public final class DisaggService {
     var response = ResponseBody.usage()
         .name(NAME)
         .url(url)
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .request(url)
         .response(usage)
         .build();
@@ -93,6 +96,7 @@ public final class DisaggService {
     var body = ResponseBody.success()
         .name(NAME)
         .url(request.http.getUri().toString())
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .request(request)
         .response(response)
         .build();
@@ -113,6 +117,7 @@ public final class DisaggService {
     var body = ResponseBody.success()
         .name(NAME)
         .url(request.http.getUri().toString())
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .request(request)
         .response(response)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java
index e87db5fef77f5f75b96880e89d03e3b3d49ab003..c324da5cf9afb08e4d3199e09f7b265a23480fa4 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java
@@ -34,7 +34,9 @@ import gov.usgs.earthquake.nshmp.geo.Location;
 import gov.usgs.earthquake.nshmp.gmm.Imt;
 import gov.usgs.earthquake.nshmp.model.HazardModel;
 import gov.usgs.earthquake.nshmp.model.SourceType;
+import gov.usgs.earthquake.nshmp.www.HazVersion;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
+import gov.usgs.earthquake.nshmp.www.ResponseMetadata;
 import gov.usgs.earthquake.nshmp.www.ServletUtil;
 import gov.usgs.earthquake.nshmp.www.meta.DoubleParameter;
 import gov.usgs.earthquake.nshmp.www.meta.Parameter;
@@ -92,6 +94,7 @@ public final class HazardService {
     var body = ResponseBody.usage()
         .name(NAME)
         .url(url)
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .request(url)
         .response(usage)
         .build();
@@ -112,6 +115,7 @@ public final class HazardService {
     var body = ResponseBody.success()
         .name(NAME)
         .url(request.http.getUri().toString())
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .request(request)
         .response(response)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/services/RateService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/services/RateService.java
index c0bcb47fd4159c8b8171dabbff526ef1f4c37d7b..b4ce06c52b3314701941246fa723215577df9967 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/services/RateService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/services/RateService.java
@@ -18,8 +18,10 @@ import gov.usgs.earthquake.nshmp.calc.EqRate;
 import gov.usgs.earthquake.nshmp.calc.Site;
 import gov.usgs.earthquake.nshmp.geo.Location;
 import gov.usgs.earthquake.nshmp.model.HazardModel;
+import gov.usgs.earthquake.nshmp.www.HazVersion;
 import gov.usgs.earthquake.nshmp.www.RateController;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
+import gov.usgs.earthquake.nshmp.www.ResponseMetadata;
 import gov.usgs.earthquake.nshmp.www.ServicesUtil.Key;
 import gov.usgs.earthquake.nshmp.www.ServicesUtil.ServiceQueryData;
 import gov.usgs.earthquake.nshmp.www.ServicesUtil.ServiceRequestData;
@@ -107,6 +109,7 @@ public final class RateService {
     return ResponseBody.<String, Usage> usage()
         .name(service.name)
         .url(url)
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .request(url)
         .response(usage)
         .build();
@@ -118,10 +121,11 @@ public final class RateService {
       RequestData data) throws InterruptedException, ExecutionException {
     var timer = Stopwatch.createStarted();
     var rates = calc(service, data);
-    var responseData = new ResponseData(new ResponseMetadata(service, data), rates, timer);
+    var responseData = new ResponseData(new ServiceResponseMetadata(service, data), rates, timer);
     return ResponseBody.<RequestData, ResponseData> success()
         .name(service.name)
         .request(data)
+        .metadata(new ResponseMetadata(HazVersion.appVersions()))
         .response(responseData)
         .url(request.getUri().getPath())
         .build();
@@ -249,7 +253,7 @@ public final class RateService {
     }
   }
 
-  private static final class ResponseMetadata {
+  private static final class ServiceResponseMetadata {
     final double latitude;
     final double longitude;
     final double distance;
@@ -258,7 +262,7 @@ public final class RateService {
     final String xlabel = "Magnitude (Mw)";
     final String ylabel;
 
-    ResponseMetadata(Service service, RequestData request) {
+    ServiceResponseMetadata(Service service, RequestData request) {
       var isProbability = service == Service.PROBABILITY;
       this.longitude = request.longitude;
       this.latitude = request.latitude;
@@ -270,10 +274,10 @@ public final class RateService {
 
   private static final class ResponseData {
     final Object server;
-    final ResponseMetadata metadata;
+    final ServiceResponseMetadata metadata;
     final List<Sequence> data;
 
-    ResponseData(ResponseMetadata metadata, EqRate rates, Stopwatch timer) {
+    ResponseData(ServiceResponseMetadata metadata, EqRate rates, Stopwatch timer) {
       server = ServletUtil.serverData(ServletUtil.THREAD_COUNT, timer);
       this.metadata = metadata;
       this.data = buildSequence(rates);
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceLogicTreesService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceLogicTreesService.java
index 01e2d4c2186ce6f09a74094576a6b9f489a34e11..5525e39647022f1523a0969ba0201a94de5fd8bd 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceLogicTreesService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceLogicTreesService.java
@@ -4,7 +4,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import gov.usgs.earthquake.nshmp.model.Models;
+import gov.usgs.earthquake.nshmp.www.HazVersion;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
+import gov.usgs.earthquake.nshmp.www.ResponseMetadata;
 import gov.usgs.earthquake.nshmp.www.ServletUtil;
 import gov.usgs.earthquake.nshmp.www.SourceLogicTreesController;
 
@@ -33,6 +35,7 @@ public class SourceLogicTreesService {
       var response = ResponseBody.success()
           .name(NAME)
           .url(url)
+          .metadata(new ResponseMetadata(HazVersion.appVersions()))
           .request(url)
           .response(trees)
           .build();
@@ -52,6 +55,7 @@ public class SourceLogicTreesService {
       var response = ResponseBody.success()
           .name(NAME)
           .url(url)
+          .metadata(new ResponseMetadata(HazVersion.appVersions()))
           .request(requestData)
           .response(tree)
           .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceServices.java b/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceServices.java
index 03704247e5c02916c38503d6303c4516a67b2c63..f72a1546e820b09e6283116236b4f415edef8823 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceServices.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceServices.java
@@ -17,7 +17,9 @@ import gov.usgs.earthquake.nshmp.gmm.Gmm;
 import gov.usgs.earthquake.nshmp.gmm.Imt;
 import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass;
 import gov.usgs.earthquake.nshmp.model.HazardModel;
+import gov.usgs.earthquake.nshmp.www.HazVersion;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
+import gov.usgs.earthquake.nshmp.www.ResponseMetadata;
 import gov.usgs.earthquake.nshmp.www.ServletUtil;
 import gov.usgs.earthquake.nshmp.www.WsUtils;
 import gov.usgs.earthquake.nshmp.www.meta.Parameter;
@@ -59,6 +61,7 @@ public class SourceServices {
       var response = ResponseBody.usage()
           .name(NAME)
           .url(url)
+          .metadata(new ResponseMetadata(HazVersion.appVersions()))
           .request(url)
           .response(new ResponseData())
           .build();