diff --git a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java
index 69f25638e1f10a0db3dda70d2e0b9d8ebb6af596..c523b196646fed349955246185fc054469038574 100644
--- a/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java
+++ b/src/aashto/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java
@@ -4,9 +4,8 @@ import java.nio.file.Path;
 
 import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass;
 import gov.usgs.earthquake.nshmp.netcdf.NetcdfGroundMotions;
-import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfService.RequestDataSiteClass;
-import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfService.ResponseData;
-import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfService.ServiceResponseMetadata;
+import gov.usgs.earthquake.nshmp.netcdf.www.Metadata.ServiceResponseMetadata;
+import gov.usgs.earthquake.nshmp.netcdf.www.Request.RequestDataSiteClass;
 import gov.usgs.earthquake.nshmp.www.NshmpMicronautServlet;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
 
@@ -64,6 +63,7 @@ public class NetcdfController {
    * @param longitude Longitude of site, in decimal degrees
    * @param latitude Latitude of site, in decimal degrees
    * @param siteClass Site class
+   * @param format Optional - Response return type: CSV or JSON. Default: JSON
    */
   @Operation(
       summary = "Returns risk-targeted design response spectra from a slash based call",
@@ -72,28 +72,56 @@ public class NetcdfController {
 
           "Enter the latitude and longitude select the site class, and press `Execute`.\n" +
 
-          "### Service call pattern\n" +
+          "### Service Call Pattern\n" +
           "This service call is slashed delimited with pattern: " +
           "`/spectra/{longitude}/{latitude}/{siteClass}`\n" +
           "<br><br>" +
-          "Example: `/spectra/-118/34/A`",
+          "Example: `/spectra/-118/34/A`\n",
       operationId = "aashto-slash")
   @ApiResponse(
       description = "Spatially interpolates data from https://doi.org/10.5066/P9Z206HY",
       responseCode = "200",
-      content = @Content(
-          mediaType = MediaType.APPLICATION_JSON,
-          schema = @Schema(implementation = Response.class)))
-  @Get(uri = "/{longitude}/{latitude}/{siteClass}", produces = MediaType.APPLICATION_JSON)
-  public HttpResponse<String> doGetSlashBySite(
+      content = {
+          @Content(
+              mediaType = MediaType.APPLICATION_JSON,
+              schema = @Schema(implementation = Response.class)),
+          @Content(
+              mediaType = MediaType.TEXT_CSV)
+      })
+  @Get(uri = "/{longitude}/{latitude}/{siteClass}{?format}",
+      produces = { MediaType.APPLICATION_JSON, MediaType.TEXT_CSV })
+  public HttpResponse<String> doGetSlashBySiteFormat(
       HttpRequest<?> request,
-      @Schema(required = true) @PathVariable @Nullable Double latitude,
-      @Schema(required = true) @PathVariable @Nullable Double longitude,
-      @Schema(required = true) @PathVariable @Nullable NehrpSiteClass siteClass) {
-    var query = new Query(longitude, latitude, siteClass);
+      @Schema(required = true) @PathVariable Double latitude,
+      @Schema(required = true) @PathVariable Double longitude,
+      @Schema(required = true,
+          implementation = NehrpSiteClass.class) @PathVariable NehrpSiteClass siteClass,
+      @Schema(required = false,
+          defaultValue = "JSON") @QueryValue @Nullable ResponseFormat format) {
+    var query = new Query(longitude, latitude, siteClass, format);
     return service.handleServiceCall(request, query);
   }
 
+  /**
+   * GET method to return hazard curves using slash delimited.
+   *
+   * @param request The HTTP request
+   * @param longitude The longitude of the site
+   * @param latitude Latitude of the site
+   * @param format Optional - Response return type: CSV or JSON. Default: JSON
+   */
+  @Hidden
+  @Get(uri = "/{longitude}/{latitude}{?format}",
+      produces = { MediaType.APPLICATION_JSON, MediaType.TEXT_CSV })
+  public HttpResponse<String> doGetSlashFormat(
+      HttpRequest<?> request,
+      @Schema(required = true) @PathVariable Double longitude,
+      @Schema(required = true) @PathVariable Double latitude,
+      @Schema(required = false,
+          defaultValue = "JSON") @QueryValue @Nullable ResponseFormat format) {
+    return doGetSlashBySiteFormat(request, latitude, longitude, null, format);
+  }
+
   /**
    * GET method to return a static curve using URL query.
    *
@@ -101,6 +129,7 @@ public class NetcdfController {
    * @param longitude The longitude of the site
    * @param latitude Latitude of the site
    * @param siteClass The site class (optional)
+   * @param format Optional - Response return type: CSV or JSON. Default: JSON
    */
   @Hidden
   @Operation(
@@ -122,30 +151,15 @@ public class NetcdfController {
       content = @Content(
           mediaType = MediaType.APPLICATION_JSON,
           schema = @Schema(implementation = Response.class)))
-  @Get(uri = "{?longitude,latitude,siteClass}", produces = MediaType.APPLICATION_JSON)
+  @Get(uri = "{?longitude,latitude,siteClass,format}",
+      produces = { MediaType.APPLICATION_JSON, MediaType.TEXT_CSV })
   public HttpResponse<String> doGet(
       HttpRequest<?> request,
       @Schema(required = true) @QueryValue @Nullable Double latitude,
       @Schema(required = true) @QueryValue @Nullable Double longitude,
-      @QueryValue @Nullable NehrpSiteClass siteClass) {
-    var query = new Query(longitude, latitude, siteClass);
-    return service.handleServiceCall(request, query);
-  }
-
-  /**
-   * GET method to return hazard curves using slash delimited.
-   *
-   * @param request The HTTP request
-   * @param longitude The longitude of the site
-   * @param latitude Latitude of the site
-   */
-  @Hidden
-  @Get(uri = "/{longitude}/{latitude}", produces = MediaType.APPLICATION_JSON)
-  public HttpResponse<String> doGetSlash(
-      HttpRequest<?> request,
-      @Schema(required = true) @PathVariable @Nullable Double longitude,
-      @Schema(required = true) @PathVariable @Nullable Double latitude) {
-    var query = new Query(longitude, latitude, null);
+      @QueryValue @Nullable NehrpSiteClass siteClass,
+      @Schema(defaultValue = "JSON") @QueryValue @Nullable ResponseFormat format) {
+    var query = new Query(longitude, latitude, siteClass, format);
     return service.handleServiceCall(request, query);
   }
 
diff --git a/src/hazard/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java b/src/hazard/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java
index ea2eea3699c4ae06360ca804487ce0628ab0d26f..adf101692b164a5f03761284e367b21018a30935 100644
--- a/src/hazard/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java
+++ b/src/hazard/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/NetcdfController.java
@@ -6,10 +6,9 @@ import java.util.List;
 import gov.usgs.earthquake.nshmp.gmm.Imt;
 import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass;
 import gov.usgs.earthquake.nshmp.netcdf.NetcdfHazardCurves;
-import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfService.RequestDataImt;
-import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfService.RequestDataSiteClass;
-import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfService.ResponseData;
-import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfServiceHazardCurves.HazardResponseMetadata;
+import gov.usgs.earthquake.nshmp.netcdf.www.Metadata.HazardResponseMetadata;
+import gov.usgs.earthquake.nshmp.netcdf.www.Request.RequestDataImt;
+import gov.usgs.earthquake.nshmp.netcdf.www.Request.RequestDataSiteClass;
 import gov.usgs.earthquake.nshmp.www.NshmpMicronautServlet;
 import gov.usgs.earthquake.nshmp.www.ResponseBody;
 
@@ -86,14 +85,17 @@ public class NetcdfController {
       responseCode = "200",
       content = @Content(
           schema = @Schema(implementation = ResponseByImt.class)))
-  @Get(uri = "/{longitude}/{latitude}/{siteClass}/{imt}", produces = MediaType.APPLICATION_JSON)
+  @Get(uri = "/{longitude}/{latitude}/{siteClass}/{imt}{?format}",
+      produces = MediaType.APPLICATION_JSON)
   public HttpResponse<String> doGetSlashByImt(
       HttpRequest<?> request,
-      @Schema(required = true) @PathVariable @Nullable Double latitude,
-      @Schema(required = true) @PathVariable @Nullable Double longitude,
-      @Schema(required = true) @PathVariable @Nullable NehrpSiteClass siteClass,
-      @Schema(required = true) @PathVariable @Nullable Imt imt) {
-    return doGet(request, longitude, latitude, siteClass, imt);
+      @Schema(required = true) @PathVariable Double latitude,
+      @Schema(required = true) @PathVariable Double longitude,
+      @Schema(required = true) @PathVariable NehrpSiteClass siteClass,
+      @Schema(required = true) @PathVariable Imt imt,
+      @Schema(required = false, defaultValue = "JSON",
+          implementation = ResponseFormat.class) @QueryValue @Nullable ResponseFormat format) {
+    return doGet(request, longitude, latitude, siteClass, imt, format);
   }
 
   /**
@@ -122,13 +124,15 @@ public class NetcdfController {
       responseCode = "200",
       content = @Content(
           schema = @Schema(implementation = ResponseBySiteClass.class)))
-  @Get(uri = "/{longitude}/{latitude}/{siteClass}", produces = MediaType.APPLICATION_JSON)
+  @Get(uri = "/{longitude}/{latitude}/{siteClass}{?format}", produces = MediaType.APPLICATION_JSON)
   public HttpResponse<String> doGetSlashBySite(
       HttpRequest<?> request,
-      @Schema(required = true) @PathVariable @Nullable Double latitude,
-      @Schema(required = true) @PathVariable @Nullable Double longitude,
-      @Schema(required = true) @PathVariable @Nullable NehrpSiteClass siteClass) {
-    return doGet(request, longitude, latitude, siteClass, null);
+      @Schema(required = true) @PathVariable Double latitude,
+      @Schema(required = true) @PathVariable Double longitude,
+      @Schema(required = true) @PathVariable NehrpSiteClass siteClass,
+      @Schema(required = false, defaultValue = "JSON",
+          implementation = ResponseFormat.class) @QueryValue @Nullable ResponseFormat format) {
+    return doGet(request, longitude, latitude, siteClass, null, format);
   }
 
   /**
@@ -156,12 +160,14 @@ public class NetcdfController {
       responseCode = "200",
       content = @Content(
           schema = @Schema(implementation = Response.class)))
-  @Get(uri = "/{longitude}/{latitude}", produces = MediaType.APPLICATION_JSON)
+  @Get(uri = "/{longitude}/{latitude}{?format}", produces = MediaType.APPLICATION_JSON)
   public HttpResponse<String> doGetSlash(
       HttpRequest<?> request,
-      @Schema(required = true) @PathVariable @Nullable Double longitude,
-      @Schema(required = true) @PathVariable @Nullable Double latitude) {
-    return doGet(request, longitude, latitude, null, null);
+      @Schema(required = true) @PathVariable Double longitude,
+      @Schema(required = true) @PathVariable Double latitude,
+      @Schema(required = false, defaultValue = "JSON",
+          implementation = ResponseFormat.class) @QueryValue @Nullable ResponseFormat format) {
+    return doGet(request, longitude, latitude, null, null, format);
   }
 
   /**
@@ -191,14 +197,16 @@ public class NetcdfController {
       responseCode = "200",
       content = @Content(
           schema = @Schema(implementation = ResponseByImt.class)))
-  @Get(uri = "{?longitude,latitude,siteClass,imt}", produces = MediaType.APPLICATION_JSON)
+  @Get(uri = "{?longitude,latitude,siteClass,imt,format}", produces = MediaType.APPLICATION_JSON)
   public HttpResponse<String> doGet(
       HttpRequest<?> request,
       @Schema(required = true) @QueryValue @Nullable Double longitude,
       @Schema(required = true) @QueryValue @Nullable Double latitude,
       @QueryValue @Nullable NehrpSiteClass siteClass,
-      @QueryValue @Nullable Imt imt) {
-    var query = new HazardQuery(longitude, latitude, siteClass, imt);
+      @QueryValue @Nullable Imt imt,
+      @Schema(required = false, defaultValue = "JSON",
+          implementation = ResponseFormat.class) @QueryValue @Nullable ResponseFormat format) {
+    var query = new HazardQuery(longitude, latitude, siteClass, imt, format);
     return service.handleServiceCall(request, query);
   }
 
diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/ResponseFormat.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/ResponseFormat.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1ca6ea50ab4380a905d5675006afab64ce08422
--- /dev/null
+++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/ResponseFormat.java
@@ -0,0 +1,11 @@
+package gov.usgs.earthquake.nshmp.netcdf.www;
+
+/**
+ * Web service return format.
+ *
+ * @author U.S. Geological Survey
+ */
+public enum ResponseFormat {
+  JSON,
+  CSV;
+}