diff --git a/app/schemas/models/course.schema.coffee b/app/schemas/models/course.schema.coffee
index a4c6d1249..773fc5509 100644
--- a/app/schemas/models/course.schema.coffee
+++ b/app/schemas/models/course.schema.coffee
@@ -11,6 +11,7 @@ _.extend CourseSchema.properties,
   pricePerSeat: {type: 'number', description: 'Price per seat in USD cents.'} # deprecated
   free: { type: 'boolean' }
   screenshot: c.url {title: 'URL', description: 'Link to course screenshot.'}
+  adminOnly: {type: 'boolean', description: 'Whether the course is in admin-only testing mode still and will not show up for normal users.'}
 
 c.extendBasicProperties CourseSchema, 'Course'
 
diff --git a/server/middleware/classrooms.coffee b/server/middleware/classrooms.coffee
index dec4ea591..4ef0abfb8 100644
--- a/server/middleware/classrooms.coffee
+++ b/server/middleware/classrooms.coffee
@@ -140,9 +140,11 @@ module.exports =
     classroom.set 'ownerID', req.user._id
     classroom.set 'members', []
     database.assignBody(req, classroom)
-    
+
     # Copy over data from how courses are right now
-    courses = yield Course.find()
+    query = {}
+    query = {adminOnly: {$ne: true}} unless req.user?.isAdmin()
+    courses = yield Course.find(query)
     campaigns = yield Campaign.find({_id: {$in: (course.get('campaignID') for course in courses)}})
     campaignMap = {}
     campaignMap[campaign.id] = campaign for campaign in campaigns
diff --git a/server/middleware/courses.coffee b/server/middleware/courses.coffee
index 85b0a1240..22cd0a48d 100644
--- a/server/middleware/courses.coffee
+++ b/server/middleware/courses.coffee
@@ -34,18 +34,27 @@ module.exports =
         foundLevelOriginal = true
         nextLevelOriginal = levels[index+1]?.original
         break
-    
+
     if not foundLevelOriginal
       throw new errors.NotFound('Level original ObjectId not found in that course')
-    
+
     if not nextLevelOriginal
       return res.status(200).send({})
-      
+
     dbq = Level.findOne({original: mongoose.Types.ObjectId(nextLevelOriginal)})
-    
-    
+
+
     dbq.sort({ 'version.major': -1, 'version.minor': -1 })
     dbq.select(parse.getProjectFromReq(req))
     level = yield dbq
     level = level.toObject({req: req})
     res.status(200).send(level)
+
+  get: (Model, options={}) -> wrap (req, res) ->
+    # Don't use standard rest middleware get, because we want to filter out adminOnly courses for non-admins
+    query = {}
+    query = {adminOnly: {$ne: true}} unless req.user?.isAdmin()
+    dbq = Model.find(query)
+    dbq.select(parse.getProjectFromReq(req))
+    results = yield database.viewSearch(dbq, req)
+    res.send(results)
diff --git a/server/routes/index.coffee b/server/routes/index.coffee
index 9ee612b4e..ecca4a2c9 100644
--- a/server/routes/index.coffee
+++ b/server/routes/index.coffee
@@ -79,7 +79,7 @@ module.exports.setup = (app) ->
   app.get('/db/codelogs', mw.auth.checkHasPermission(['admin']), mw.rest.get(CodeLog))
 
   Course = require '../models/Course'
-  app.get('/db/course', mw.rest.get(Course))
+  app.get('/db/course', mw.courses.get(Course))
   app.get('/db/course/:handle', mw.rest.getByHandle(Course))
   app.get('/db/course/:handle/levels/:levelOriginal/next', mw.courses.fetchNextLevel)