diff --git a/apps/steward-app/src/main/scala/net/shrine/steward/Boot.scala b/apps/steward-app/src/main/scala/net/shrine/steward/Boot.scala
index 503a09a0c..a83397ed6 100644
--- a/apps/steward-app/src/main/scala/net/shrine/steward/Boot.scala
+++ b/apps/steward-app/src/main/scala/net/shrine/steward/Boot.scala
@@ -1,71 +1,83 @@
 package net.shrine.steward
 
 import akka.actor.{ActorSystem, Props}
 import net.shrine.config.{ConfigExtensions, DurationConfigParser}
 import net.shrine.log.Loggable
 import net.shrine.problem.{AbstractProblem, ProblemSources}
 import net.shrine.steward.db.StewardDatabase
 import net.shrine.steward.email.{AuditEmailer, AuditEmailerActor}
 import spray.servlet.WebBoot
 
 import scala.concurrent.ExecutionContext.Implicits.global
 import scala.concurrent.duration._
 import scala.language.postfixOps
 import scala.util.control.NonFatal
 
 // this class is instantiated by the servlet initializer
 // it needs to have a default constructor and implement
 // the spray.servlet.WebBoot trait
 class Boot extends WebBoot with Loggable {
 
   info(s"StewardActors akka daemonic config is ${StewardConfigSource.config.getString("akka.daemonic")}")
 
   val warmUp:Unit = StewardDatabase.warmUp()
 
   // we need an ActorSystem to host our application in
   val system = ActorSystem("StewardActors",StewardConfigSource.config)
 
   // the service actor replies to incoming HttpRequests
   val serviceActor = system.actorOf(Props[StewardServiceActor])
 
   // if sending email alerts is on start a periodic polling of the database at a fixed time every day.
   // if either the volume or time conditions are met, send an email to the data steward asking for an audit
   val config = StewardConfigSource.config
 
   val emailConfig = config.getConfig("shrine.steward.emailDataSteward")
 
   if(emailConfig.getBoolean("sendAuditEmails") && AuditEmailer.configCheck(config)) {
 
     try {
-      system.scheduler.schedule(initialDelay = 0 milliseconds, //todo figure out how to handle the initial delay
-        interval = emailConfig.get("interval", DurationConfigParser.parseDuration),
+      val interval = emailConfig.get("interval", DurationConfigParser.parseDuration)
+
+      system.scheduler.schedule(initialDelay = initialDelayToSendEmail(emailConfig.get("timeAfterMidnight",DurationConfigParser.parseDuration),interval),
+        interval = interval,
         receiver = system.actorOf(Props[AuditEmailerActor]),
         "tick")
     }
     catch {
       case NonFatal(x)  => CannotStartAuditEmailActor(x)
       case x:ExceptionInInitializerError => CannotStartAuditEmailActor(x)
     }
   }
 
-  //todo use this to figure out what if any initial delay should be. Maybe if the interval is >= 1 day then the delay will send the email so many hours passed either the previous or the next midnight
-  def previousMidnight: Long = {
-    import java.util.Calendar
-    val c = Calendar.getInstance()
-    val now = c.getTimeInMillis()
-    c.set(Calendar.HOUR_OF_DAY, 0)
-    c.set(Calendar.MINUTE, 0)
-    c.set(Calendar.SECOND, 0)
-    c.set(Calendar.MILLISECOND, 0)
-    c.getTimeInMillis
+  def initialDelayToSendEmail(timeFromMidnight:Duration,interval:Duration): FiniteDuration = {
+    if(interval >= (1 day)) {
+
+      import java.util.Calendar
+      val c = Calendar.getInstance()
+      val now = c.getTimeInMillis
+
+      val previousMidnight = {
+        c.set(Calendar.HOUR_OF_DAY, 0)
+        c.set(Calendar.MINUTE, 0)
+        c.set(Calendar.SECOND, 0)
+        c.set(Calendar.MILLISECOND, 0)
+        c.getTimeInMillis
+      }
+      val timeToSendToday = previousMidnight + timeFromMidnight.toMillis
+
+      if (timeToSendToday > now) timeToSendToday milliseconds
+      else timeToSendToday + (1 day).toMillis milliseconds
+    }
+    else 0 milliseconds //if we're testing then don't delay that first send
   }
 }
 
 case class CannotStartAuditEmailActor(ex:Throwable) extends AbstractProblem(ProblemSources.Dsa) {
   override def summary: String = "The DSA could not start an Actor to email audit requests due to an exception."
 
   override def description: String = s"The DSA will not email audit requests due to ${throwable.get}"
 
   override def throwable = Some(ex)
 }
 
diff --git a/apps/steward-app/src/main/scala/net/shrine/steward/email/AuditEmailer.scala b/apps/steward-app/src/main/scala/net/shrine/steward/email/AuditEmailer.scala
index 8b4e80492..6ab186eaa 100644
--- a/apps/steward-app/src/main/scala/net/shrine/steward/email/AuditEmailer.scala
+++ b/apps/steward-app/src/main/scala/net/shrine/steward/email/AuditEmailer.scala
@@ -1,144 +1,144 @@
 package net.shrine.steward.email
 
 import java.util.Date
 import javax.mail.internet.InternetAddress
 
 import akka.actor.Actor
 import com.typesafe.config.Config
 import courier.{Envelope, Mailer, Text}
 import net.shrine.authorization.steward.ResearcherToAudit
 import net.shrine.config.{ConfigExtensions, DurationConfigParser}
 import net.shrine.email.ConfiguredMailer
 import net.shrine.log.Log
 import net.shrine.problem.{AbstractProblem, ProblemSources}
 import net.shrine.steward.StewardConfigSource
 import net.shrine.steward.db.StewardDatabase
 
 import scala.concurrent.Await
 import scala.concurrent.ExecutionContext.Implicits.global
 import scala.concurrent.blocking
 import scala.concurrent.duration.FiniteDuration
 import scala.concurrent.duration._
 import scala.util.control.NonFatal
 import scala.xml.NodeSeq
 
 /**
   * @author david 
   * @since 1.22
   */
 case class AuditEmailer(maxQueryCountBetweenAudits:Int,
                         minTimeBetweenAudits:FiniteDuration,
                         researcherLineTemplate:String,
                         emailTemplate:String,
                         emailSubject:String,
                         from:InternetAddress,
                         to:InternetAddress,
-                        stewardBaseUrl:Option[String],
+                        stewardBaseUrl:Option[String], //todo not an option
                         mailer:Mailer
                        ) {
   def audit() = {
     //gather a list of users to audit
     val now = System.currentTimeMillis()
     val researchersToAudit: Seq[ResearcherToAudit] = StewardDatabase.db.selectResearchersToAudit(maxQueryCountBetweenAudits,
       minTimeBetweenAudits,
       now)
     if (researchersToAudit.nonEmpty){
 
       val auditLines = researchersToAudit.sortBy(_.count).reverse.map { researcher =>
         researcherLineTemplate.replaceAll("FULLNAME",researcher.researcher.fullName)
           .replaceAll("USERNAME",researcher.researcher.userName)
           .replaceAll("COUNT",researcher.count.toString)
           .replaceAll("LAST_AUDIT_DATE",new Date(researcher.leastRecentQueryDate).toString)
       }.mkString("\n")
 
       //build up the email body
       val withLines = emailTemplate.replaceAll("AUDIT_LINES",auditLines)
       val withBaseUrl = stewardBaseUrl.fold(withLines)(withLines.replaceAll("STEWARD_BASE_URL",_))
       val emailBody = Text(withBaseUrl)
 
       val envelope:Envelope = Envelope.from(from).to(to).subject(emailSubject).content(emailBody)
 
       Log.debug(s"About to send $envelope .")
 
       //send the email
       val future = mailer(envelope)
 
       try {
         blocking {
           Await.result(future, 60.seconds)
         }
         StewardDatabase.db.logAuditRequests(researchersToAudit, now)
         Log.info(s"Sent and logged $envelope .")
       } catch {
         case NonFatal(x) => CouldNotSendAuditEmail(envelope,x)
       }
     }
   }
 }
 
 object AuditEmailer {
 
   /**
     *
     * @param config All of shrine.conf
     */
   def apply(config:Config):AuditEmailer = {
     val config = StewardConfigSource.config
     val emailConfig = config.getConfig("shrine.steward.emailDataSteward")
 
     AuditEmailer(
       maxQueryCountBetweenAudits = emailConfig.getInt("maxQueryCountBetweenAudits"),
       minTimeBetweenAudits = emailConfig.get("minTimeBetweenAudits", DurationConfigParser.parseDuration),
       researcherLineTemplate = emailConfig.getString("researcherLine"),
       emailTemplate = emailConfig.getString("emailBody"),
       emailSubject = emailConfig.getString("subject"),
       from = emailConfig.get("from", new InternetAddress(_)),
       to = emailConfig.get("to", new InternetAddress(_)),
-      stewardBaseUrl = config.getOption("stewardBaseUrl", _.getString),
+      stewardBaseUrl = config.getOption("shrine.queryEntryPoint.shrineSteward.stewardBaseUrl", _.getString),
       mailer = ConfiguredMailer.createMailerFromConfig(config.getConfig("shrine.email")))
   }
 
   /**
     * Check the emailer's config, log any problems
     *
     * @param config All of shrine.conf
     */
   def configCheck(config:Config):Boolean = try {
     val autoEmailer = apply(config)
     Log.info(s"DSA will request audits from ${autoEmailer.to}")
     true
   } catch {
     case NonFatal(x) =>
       CannotConfigureAuditEmailer(x)
       false
   }
 }
 
 class AuditEmailerActor extends Actor {
 
   override def receive: Receive = {case _ =>
     val config = StewardConfigSource.config
     AuditEmailer(config).audit()
   }
 }
 
 case class CannotConfigureAuditEmailer(ex:Throwable) extends AbstractProblem(ProblemSources.Dsa) {
   override def summary: String = "The DSA will not email audit requests due to a misconfiguration."
 
   override def description: String = s"The DSA will not email audit requests due to ${throwable.get}"
 
   override def throwable = Some(ex)
 }
 
 case class CouldNotSendAuditEmail(envelope:Envelope,ex:Throwable) extends AbstractProblem(ProblemSources.Dsa) {
   override def summary: String = "The DSA was not able to send an audit email."
 
   override def description: String = s"The DSA was not able to send an audit request to ${envelope.to} due to ${throwable.get}"
 
   override def throwable = Some(ex)
 
   override def detailsXml:NodeSeq = <details>
     {s"Could not send $envelope"}
     {throwableDetail}
   </details>
 }
\ No newline at end of file
diff --git a/apps/steward-war/src/main/resources/reference.conf b/apps/steward-war/src/main/resources/reference.conf
index 98f5c269e..a98b35283 100644
--- a/apps/steward-war/src/main/resources/reference.conf
+++ b/apps/steward-war/src/main/resources/reference.conf
@@ -1,108 +1,109 @@
 shrine {
   steward {
 
     createTopicsMode = Pending  //Can be Pending, Approved, or TopcisIgnoredJustLog
                                 //Pending - new topics start in the Pending state; researchers must wait for the Steward to approve them
                                 //Approved - new topics start in the Approved state; researchers can use them immediately
                                 //TopicsIgnoredJustLog - all queries are logged and approved; researchers don't need to create topics
 
     emailDataSteward {
       sendAuditEmails = true
       interval = "1 day" //Audit researchers daily
+      timeAfterMidnight = "6 hours" //Audit researchers at 6 am. If the interval is less than 1 day then this delay is ignored.
       maxQueryCountBetweenAudits = 30 //If a researcher runs more than this many queries since the last audit audit her
       minTimeBetweenAudits = "30 days" //If a researcher runs at least one query, audit those queries if this much time has passed
 
       //provide the email address of the shrine node system admin, to handle bounces and invalid addresses
       //from = "shrine-admin@example.com"
       //provide the email address of the shrine node system admin, to handle bounces and invalid addresses
       //to = "shrine-steward@example.com"
 
       subject = "Audit SHRINE researchers"
       //The baseUrl for the data steward to be substituted in to email text. Must be supplied if it is used in the email text.
       //stewardBaseUrl = "https://example.com:8443/steward/"
 
       //Text to use for the email audit.
       // AUDIT_LINES will be replaced by a researcherLine for each researcher to audit.
       // STEWARD_BASE_URL will be replaced by the value in stewardBaseUrl if available.
       emailBody = """Please audit the following users at STEWARD_BASE_URL at your earliest convinience:
       
 AUDIT_LINES"""
 
       //Text to use per researcher to audit.
       //FULLNAME, USERNAME, COUNT and LAST_AUDIT_DATE will be replaced with appropriate text.
       researcherLine = "FULLNAME (USERNAME) has run COUNT queries since LAST_AUDIT_DATE."
     }
 
     database {
       dataSourceFrom = "JNDI" //Can be JNDI or testDataSource . Use testDataSource for tests, JNDI everywhere else
       jndiDataSourceName = "java:comp/env/jdbc/stewardDB" //or leave out for tests
       slickProfileClassName = "slick.driver.MySQLDriver$" // Can be
       //        slick.driver.H2Driver$
       //        slick.driver.MySQLDriver$
       //        slick.driver.PostgresDriver$
       //        slick.driver.SQLServerDriver$
       //        slick.driver.JdbcDriver$
       //        freeslick.OracleProfile$
       //        freeslick.MSSQLServerProfile$
       //
       //        (Yes, with the $ on the end)
 
 // For testing without JNDI
 //      testDataSource {
 
         //typical test settings for unit tests
         //driverClassName = "org.h2.Driver"
 
         //url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" //H2 embedded in-memory for unit tests
         //url = "jdbc:h2:~/stewardTest.h2" //H2 embedded on disk at ~/test
 //      }
       createTablesOnStart = false //for testing with H2 in memory, when not running unit tests. Set to false normally
     }
 
     gruntWatch = false //false for production, true for mvn tomcat7:run . Allows the client javascript and html files to be loaded via gruntWatch .
 
   }
 
   pmEndpoint {
     url = "http://changeme.com/i2b2/services/PMService/getServices" //"http://services.i2b2.org/i2b2/services/PMService/getServices"
     acceptAllCerts = true
     timeout {
       seconds = 10
     }
   }
 
   authenticate {
     realm = "SHRINE Steward API"
     usersource
       {
         type = "PmUserSource" //Must be ConfigUserSource (for isolated testing) or PmUserSource (for everything else)
         domain = "set shrine.authenticate.usersource.domain to the PM authentication domain in steward.conf" //"i2b2demo"
       }
   }
 
   // If the pmEndpoint acceptAllCerts = false then you need to supply a keystore
 //  keystore {
 //    file = "shrine.keystore"
 //    password = "chiptesting"
 //    privateKeyAlias = "test-cert"
 //    keyStoreType = "JKS"
 //    caCertAliases = [carra ca]
 //  }
 }
 
 //todo typesafe config precedence seems to do the right thing, but I haven't found the rules that say this reference.conf should override others
 akka {
   loglevel = INFO
 
   //  log-config-on-start = on
   loggers = ["akka.event.slf4j.Slf4jLogger"]
   // logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
   // Toggles whether the threads created by this ActorSystem should be daemons or not
   daemonic = on
 }
 
 spray.servlet {
   boot-class = "net.shrine.steward.Boot"
   request-timeout = 30s
 }