diff --git a/build.gradle b/build.gradle
index ec3573df40a56479ac853add71a98f0f9ab1e4bf..151061f9f18e18d49cc615f1b555ae0bc42c2f77 100644
--- a/build.gradle
+++ b/build.gradle
@@ -366,6 +366,7 @@ dependencies {
     compile "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${vJackson}"
     compile "com.fasterxml.jackson.datatype:jackson-datatype-hibernate4:${vJackson}"
     compile "org.json:json:20151123"
+    compile "com.thoughtworks.xstream:xstream:1.4.9"
     compile "xerces:xercesImpl:2.11.0"
 
     compile "commons-beanutils:commons-beanutils:1.9.2"
diff --git a/src/main/java/org/nrg/xapi/rest/schemas/SchemaApi.java b/src/main/java/org/nrg/xapi/rest/schemas/SchemaApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d7500b8f841362978161aec0015d63201b41c86
--- /dev/null
+++ b/src/main/java/org/nrg/xapi/rest/schemas/SchemaApi.java
@@ -0,0 +1,78 @@
+package org.nrg.xapi.rest.schemas;
+
+import com.google.common.base.Joiner;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.commons.io.FilenameUtils;
+import org.nrg.framework.annotations.XapiRestController;
+import org.nrg.framework.utilities.BasicXnatResourceLocator;
+import org.nrg.xdat.rest.AbstractXapiRestController;
+import org.nrg.xdat.security.services.RoleHolder;
+import org.nrg.xdat.security.services.UserManagementServiceI;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+
+@Api(description = "XNAT Data Type Schemas API")
+@XapiRestController
+@RequestMapping(value = "/schemas")
+public class SchemaApi extends AbstractXapiRestController {
+    @Autowired
+    public SchemaApi(final UserManagementServiceI userManagementService, final RoleHolder roleHolder) {
+        super(userManagementService, roleHolder);
+    }
+
+    @ApiOperation(value = "Returns a list of all of the installed XNAT data-type schemas.", notes = "The strings returned from this function tell you the name of the schema and can be used with other methods on this API to retrieve the full schema document. This tells you nothing about whether the data types defined in the schemas are active or configured.", response = String.class, responseContainer = "List")
+    @ApiResponses({@ApiResponse(code = 200, message = "XNAT data-type schemas successfully retrieved."),
+                   @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."),
+                   @ApiResponse(code = 500, message = "Unexpected error")})
+    @RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET})
+    public ResponseEntity<List<String>> getAllDataTypeSchemas() throws IOException {
+        final List<String> schemas = new ArrayList<>();
+        for (final Resource resource : BasicXnatResourceLocator.getResources("classpath*:schemas/*/*.xsd")) {
+            final Set<String> schemaPath = new HashSet<>(Arrays.asList(FilenameUtils.removeExtension(resource.getURI().toString().replaceAll("^.*/schemas/", "")).split("/")));
+            schemas.add(Joiner.on("/").join(schemaPath));
+        }
+        return new ResponseEntity<>(schemas, HttpStatus.OK);
+    }
+
+    @ApiOperation(value = "Returns the requested XNAT data-type schema.", notes = "XNAT data-type schemas are most often stored on the classpath in the folder schemas/SCHEMA/SCHEMA.xsd. This function returns the schema named SCHEMA.xsd in the folder named SCHEMA. You can use the function that allows you to specify the namespace as well if the folder name differs from the schema name. This tells you nothing about whether the data types defined in the schemas are active or configured.", response = String.class)
+    @ApiResponses({@ApiResponse(code = 200, message = "XNAT data-type schemas successfully retrieved."),
+                   @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."),
+                   @ApiResponse(code = 404, message = "The requested resource wasn't found."),
+                   @ApiResponse(code = 500, message = "Unexpected error")})
+    @RequestMapping(value = "{schema}", produces = {MediaType.APPLICATION_XML_VALUE}, method = {RequestMethod.GET})
+    public ResponseEntity<String> getRequestedDataTypeSchema(@PathVariable("schema") final String schema) throws IOException, ParserConfigurationException, SAXException {
+        return getRequestedDataTypeSchema(schema, schema);
+    }
+
+    @ApiOperation(value = "Returns the requested XNAT data-type schema.", notes = "XNAT data-type schemas are most often stored on the classpath in the folder schemas/SCHEMA/SCHEMA.xsd, but sometimes the folder name differs from the schema name. This function returns the schema named SCHEMA.xsd in the folder named NAMESPACE. This tells you nothing about whether the data types defined in the schemas are active or configured.", response = String.class)
+    @ApiResponses({@ApiResponse(code = 200, message = "XNAT data-type schemas successfully retrieved."),
+                   @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."),
+                   @ApiResponse(code = 404, message = "The requested resource wasn't found."),
+                   @ApiResponse(code = 500, message = "Unexpected error")})
+    @RequestMapping(value = "{namespace}/{schema}", produces = {MediaType.APPLICATION_XML_VALUE}, method = {RequestMethod.GET})
+    // TODO: Eventually these should return XML Document objects that are appropriately converted. Spring doesn't have a converter for that by default.
+    public ResponseEntity<String> getRequestedDataTypeSchema(@PathVariable("namespace") final String namespace, @PathVariable("schema") final String schema) throws IOException, ParserConfigurationException, SAXException {
+        final Resource resource = BasicXnatResourceLocator.getResource("classpath:schemas/" + namespace + "/" + schema + ".xsd");
+        if (resource == null) {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+        }
+        try (final InputStream input = resource.getInputStream()) {
+            return new ResponseEntity<>(new Scanner(input, "UTF-8").useDelimiter("\\A").next(), HttpStatus.OK);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/nrg/xnat/initialization/RootConfig.java b/src/main/java/org/nrg/xnat/initialization/RootConfig.java
index 87bb0676675ed8b2548f452898e193ee5d626723..a7c98198b99892456e73f75711901fdf58f1c4fa 100644
--- a/src/main/java/org/nrg/xnat/initialization/RootConfig.java
+++ b/src/main/java/org/nrg/xnat/initialization/RootConfig.java
@@ -24,6 +24,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
 import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.oxm.jaxb.Jaxb2Marshaller;
+import org.springframework.oxm.xstream.XStreamMarshaller;
 
 import javax.servlet.ServletContext;
 import javax.xml.bind.Marshaller;