EMA: Random Schedule (Flexible)
Overview
Problem: You need flexible EMA sampling where schedules are generated externally, can be adjusted after enrollment, and you want tight control over timing constraints without creating dozens of events or Automated Survey Invitations (ASIs).
Solution: Use a longitudinal project with repeating events, store delivery schedules in one instrument, collect responses in another, import schedules via the Data Import Tool or API, and send surveys using Alerts with [current-instance] piping.
Prerequisites
- A longitudinal REDCap project
- An email field for participants (or phone number for SMS)
- Ability to generate schedules (R, Python, Excel, or similar)
- Data Import Tool access OR API access
- Project Setup and Design rights
- Alerts & Notifications rights
When to Use This Approach
This approach works well when:
- You need random or semi-random sampling with custom constraints
- You want to adjust schedules after participant enrollment
- You can generate schedules using external tools
- You want fine control over sampling rules (minimum spacing, time-of-day constraints, etc.)
- You want both fixed and random schedules to work the same way
- You need to track which scheduled surveys were answered
See the EMA overview for other approaches.
Trade-offs
Advantages:
- Maximum flexibility in scheduling logic
- Can adjust schedules after enrollment (just re-import)
- Easy to implement complex spacing rules
- No need for many events or ASIs
- Instance numbers link schedules to responses, making analysis straightforward
Drawbacks:
- Requires external tools to generate schedules
- Must manually implement reminders and expiration
- Requires Data Import Tool or API access
Steps
Create the Project Structure
- Create a longitudinal project with two events:
main: For enrollment and baseline dataema: For the scheduled surveys
- In the
mainevent, add an instrument to collect the participant’s email address (or phone number for SMS):- Field Type: Text Box
- Validation: Email (or Phone)
- Variable Name:
email
- In Project Setup > Designate an email field for communications, select
email
Create the Schedule Instrument
- Create a new instrument called
schedulewith at least two fields:deliver_at:- Field Type: Text Box
- Validation: Datetime (Y-M-D H:M)
- Variable Name:
deliver_at
expires_at:- Field Type: Text Box
- Validation: Datetime (Y-M-D H:M)
- Variable Name:
expires_at
- These fields will be populated by data import or API, not by users
If you have multiple data collection periods (e.g., pre- and post-intervention), it’s probably easiest to add an ema_period field to the schedule form and fill that in with your schedule generation script. The exception would be if you need the Alert text to be different, or if you’re collecting different data in your different EMA periods.
Create the EMA Survey Instrument
- Create a new instrument called
emawith your data collection fields - Add a
started_atfield to track when participants begin the survey:- Field Type: Text Box
- Validation: Datetime (Y-M-D H:M)
- Variable Name:
started_at - Action Tags:
@HIDDEN @NOW
- Enable the instrument as a survey
- Configure survey settings as desired
Configure the EMA Event as Repeating
- Go to Project Setup > Repeating instruments and events
- Click Enable
- For the
emaevent, select Treat the entire event as repeating - Ensure both the
scheduleandemainstruments are designated for theemaevent
Instance numbers will now be synchronized across both instruments. Instance 1 of schedule corresponds to instance 1 of ema, and so on. This makes it easy to see which surveys were completed.
Generate and Import Schedules
- Generate your schedules externally using R, Python, Excel, or similar tools. Each row should include:
record_idredcap_event_name(theemaevent’s unique name, typicallyema_arm_1)redcap_repeat_instance(1, 2, 3, …)deliver_at(format:YYYY-MM-DD HH:MM)expires_at(format:YYYY-MM-DD HH:MM)
- Import the schedules using Data Import Tool or the API
Schedule generation is left as an exercise for now.
Create the Alert to Send Surveys
- Go to Alerts & Notifications
- Click Add New Alert
- Configure the Alert:
- Alert title: Something like “Send EMA Survey”
- Trigger alert when:
(datediff("now", [ema_arm_1][expires_at][current-instance], "s", true) > 0)- The
[current-instance]piping is critical — without it, the Alert will evaluate against all instances and send far too many notifications - The logic checks if “now” is before
expires_at. If the alert is delayed for any reason (REDCap scheduler down, blank email field, bug in logic), expired surveys won’t be sent when the problem is fixed.
- The
- Ensure logic is still true before sending: Check this box
- When to send the alert: At the time specified by a date/time field
- Field:
deliver_at
- Field:
- How often to send: Only once per event-instance in a record
- Email To:
[email] - Email Subject: Your survey invitation subject
- Alert message: Include the survey link:
[ema_arm_1][survey-url:ema][current-instance]
The [current-instance] piping is essential in both the trigger logic and the survey URL. Without it, the Alert will not work correctly.
(Optional) Add Reminders
If you want to send reminder notifications for incomplete surveys:
- Modify the Alert trigger logic to include a check for whether the survey was started:
(datediff("now", [ema_arm_1][expires_at][current-instance], "s", true) > 0) and ([ema_arm_1][started_at][current-instance] = "")
- This ensures reminders are only sent if the survey hasn’t been started yet
(Optional) Implement Survey Expiration
To hide survey questions after the expiration time:
- On the
emainstrument, add a calculated field to check if the survey has expired:- Field Type: Calculated Field
- Variable Name:
is_expired - Calculation:
datediff([started_at], [expires_at], "s", true) > 0
- Use branching logic on your data collection fields to hide them when
[is_expired] = 1 - Add a Descriptive Text field (or use a section header) with branching logic
[is_expired] = 1that displays an expiration message
Multi-page surveys and section headings work well for creating a clean expiration experience.
Notes
- Timing precision: How often REDCap checks scheduled Alerts depends on your server settings. Our server checks every 5 minutes. Send immediately Alerts are generally not subject to this delay.
- Scheduled Alerts are sometimes absent: Between the time an Alert is scheduled and when it’s actually sent, it will not appear in the Alerts Log in either the past or future alerts.
- Checking message delivery: The only way to check whether messages have been delivered is to use the Notification Log in Alerts & Notifications.
- Rescheduling: You can regenerate schedules and re-import them to adjust survey times. A future recipe will cover rescheduling in detail.
- Email and SMS: This approach works identically for both email and SMS (via Twilio, Mosio, or similar providers).
- Stopping messages: To stop surveys for participants who withdraw, see Stopping Alerts and ASIs
- Time zones: Time zones will
The only way you can make sure your Alerts are being delivered is to download the Notification Log. Don’t forget to do this on a regular basis (and reconcile against what you think you are delivering) or you may realize you haven’t been collecting the data you think you have.
Traps
Changing the deliver_at times will not reschedule already-scheduled Alerts!
To reschedule, you need to toggle the Alert logic to temporarily be false, and then make it true again. One way to do this is to add a needs_rescheduling Yes/No field to the schedule form, import a 1, then import 0, and include and [ema_arm_1][needs_rescheduling][current-instance] <> 1 in the Alert logic.
This really deserves its own recipe.
Once an Alert has been sent, changing its schedule to the future will not re-schedule it. You’ll need to add a new instance.
Troubleshooting
Alerts aren’t sending
- Verify the Alert is enabled and saved
- Check that the trigger logic evaluates to true for the records you expect
- Remember the 5-minute (or whatever your server uses) delay for scheduled Alerts
- Check Alerts & Notifications > View Alerts Log to see what’s been sent
Too many Alerts are sending
- Verify you’re using
[current-instance]in the trigger logic
It can be helpful to schedule your alert timings at the same granularity as the server’s scheduler.
Alerts are sometimes missing from the logs
During the time between when an Alert’s scheduled time has passed and when it is sent, it will not appear in the Notification Log at all.
Survey links aren’t working
- Verify you’re using
[ema_arm_1][survey-url:ema][current-instance](adjust the event name for your project) - Check that the
emainstrument is enabled as a survey
Import fails
- Verify your event name matches REDCap’s unique event name (e.g.,
ema_arm_1) - Check that you’ve selected Allow creation of new records? in the Data Import Tool