diff --git a/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Request.java b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Request.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb193cbb2c40d17be105336c9a1f8610b185b5cc
--- /dev/null
+++ b/src/lib/src/main/java/gov/usgs/earthquake/nshmp/netcdf/www/Request.java
@@ -0,0 +1,85 @@
+package gov.usgs.earthquake.nshmp.netcdf.www;
+
+import java.util.List;
+
+import gov.usgs.earthquake.nshmp.Text;
+import gov.usgs.earthquake.nshmp.Text.Delimiter;
+import gov.usgs.earthquake.nshmp.geo.Location;
+import gov.usgs.earthquake.nshmp.gmm.Imt;
+import gov.usgs.earthquake.nshmp.gmm.NehrpSiteClass;
+import gov.usgs.earthquake.nshmp.netcdf.www.NetcdfWsUtils.Key;
+
+/**
+ * Web service request data.
+ *
+ * @author U.S. Geological Survey
+ */
+public class Request {
+
+  interface RequestDataToCsv {
+    /**
+     * Convert the request data into a CSV line.
+     */
+    String toCsv();
+  }
+
+  /**
+   * Basic request data with latitude, longitude, and format.
+   */
+  static class RequestData implements RequestDataToCsv {
+    public Double latitude;
+    public Double longitude;
+    public ResponseFormat format;
+    public transient Location site;
+
+    RequestData(Location site, ResponseFormat format) {
+      latitude = site.latitude;
+      longitude = site.longitude;
+      this.format = format;
+      this.site = site;
+    }
+
+    public String toCsv() {
+      return Text.join(
+          List.of(Key.LONGITUDE.toString(), longitude, Key.LATITUDE.toString(), latitude),
+          Delimiter.COMMA);
+    }
+  }
+
+  /**
+   * Request data with site class and imt
+   */
+  static class RequestDataImt extends RequestDataSiteClass {
+    public Imt imt;
+
+    RequestDataImt(Location site, NehrpSiteClass siteClass, Imt imt, ResponseFormat format) {
+      super(site, siteClass, format);
+      this.imt = imt;
+    }
+
+    @Override
+    public String toCsv() {
+      return String.format("%s,%s",
+          super.toCsv(), Text.join(List.of(Key.IMT.toString(), imt.name()), Delimiter.COMMA));
+    }
+  }
+
+  /**
+   * Request data with site class
+   */
+  static class RequestDataSiteClass extends RequestData {
+    public NehrpSiteClass siteClass;
+
+    RequestDataSiteClass(Location site, NehrpSiteClass siteClass, ResponseFormat format) {
+      super(site, format);
+      this.siteClass = siteClass;
+    }
+
+    @Override
+    public String toCsv() {
+      return String.format("%s,%s",
+          super.toCsv(), Text.join(List.of(Key.SITE_CLASS.toString(), siteClass), Delimiter.COMMA));
+    }
+  }
+
+}