SRP Field Surveys
Offline-first data collection with PIN-authenticated field reps
01 What Are Field Surveys?
Field surveys are SRP surveys designed to run on Syrup Field Client, a progressive web app (PWA) from SRP Surveys made specifically to host SRP Surveys when there is no wifi. Field reps use it to collect data in the real world — household surveys, community assessments, structured interviews conducted door to door — often with no internet access at all.
Three things make field surveys different from a standard web survey:
- Offline-first. The survey loads from local cache. Field reps can collect responses with no signal at all. Data is stored in the browser until connectivity returns.
- PIN authentication. Each field rep logs in with a 6-digit PIN issued by an admin — no email, no password, no account creation. The PIN ties responses to a specific rep without friction.
- Background sync. When the device comes back online, queued responses are automatically posted to the server. The field rep doesn't need to do anything.
02 The Language
Good news: there is no special field survey syntax. You write the same SRP DSL you already know. Pages, questions, skip logic, required fields — all identical. The only difference is a validation step that runs at publish time to confirm your survey only uses features Syrup Field Client can handle.
If your survey passes that check, it can be published as a field survey. If it doesn't, you'll see a clear error message pointing to the offending question type or feature. Nothing is silently dropped.
If you're new to the language, the Intro to SRP guide covers the fundamentals in about five minutes. Come back here once you've written your first survey.
03 Supported Question Types
Syrup Field Client supports 16 question types. They cover the full range of typical field data collection — from simple radio buttons to ranked lists and grid matrices.
Selection
SingleSelect "housing_type" do
text "What type of dwelling does the household live in?"
required
option "Permanent structure"
option "Semi-permanent structure"
option "Temporary/makeshift"
option "Other"
end
Dropdown "district" do
text "Select the respondent's district"
required
option "Kampala"
option "Wakiso"
option "Mukono"
option "Jinja"
# ... as many options as needed
end
Text
OpenEnded "household_id" do
text "Enter the household ID from the listing form"
required
placeholder "e.g. KLA-2024-0042"
end
Discussion "enumerator_notes" do
text "Additional observations (optional)"
placeholder "Note anything unusual about this interview"
end
Numeric & Date
Number "household_size" do
text "How many people live in this household?"
required
min 1
max 30
end
Number "monthly_income" do
text "Approximate monthly household income (UGX)"
unit "UGX"
allow_decimal false
end
Age "respondent_age" do
text "Date of birth of the primary respondent"
required
end
DatePicker "interview_date" do
text "Date of interview"
required
end
Scales
Rating "service_quality" do
text "How would you rate the quality of health services in this area?"
required
scale 5
low_label "Very poor"
high_label "Excellent"
end
NPS "recommend" do
text "How likely are you to recommend this program to a neighbor?"
low_label "Not at all likely"
high_label "Extremely likely"
end
Advanced
Ranking "priority_needs" do
text "Rank these community needs from most to least urgent"
required
item "Clean water access"
item "Healthcare services"
item "School facilities"
item "Road infrastructure"
item "Electricity"
end
SingleSelectMatrix "service_frequency" do
text "How often does your household use each service?"
row "Health clinic"
row "Primary school"
row "Market"
column "Never"
column "Monthly"
column "Weekly"
column "Daily"
end
Display
Notification "consent_notice" do
text "This survey is voluntary and confidential. Your responses will only be used for program planning purposes. You may stop at any time."
end
04 What to Skip
Syrup Field Client is purpose-built for structured interviews in constrained environments. It doesn't support visual question types (heat maps, card sorts), media capture, or advanced research paradigms. Using any of the following will produce an error at publish time — the survey cannot be published as a field survey until the offending types are removed.
Unsupported question types
These types require visual interaction, media hardware, or browser capabilities that aren't reliable in offline mobile contexts. If you're unsure whether a type is supported, check Section 3 — only those 16 types are on the allow list.
Unsupported dynamic features
Two features that work in web surveys are blocked in field surveys because they require live server data at render time:
options_from— populating choice options from another question or data sourcerows_from/columns_from— populating matrix rows or columns dynamically
All options, rows, and columns must be defined statically in the DSL. The survey content is baked in at publish time and cached offline.
Ignored page-level features
These features will not cause a publish error — they produce a warning instead — but their behavior is silently dropped in Syrup Field Client:
| Feature | In web surveys | In field surveys |
|---|---|---|
randomized |
Questions shown in random order | Fixed order (ignored) |
min_seconds |
Minimum time before advancing | No minimum enforced (ignored) |
max_seconds |
Auto-advance after timeout | No time limit (ignored) |
show_timer |
Countdown visible to respondent | Not shown (ignored) |
Text piping caveat
Text piping — inserting a previous answer into a later question using
{{question_name}} syntax — is technically present in Syrup Field Client but
may not render correctly in all offline scenarios. You'll see a warning at publish time
if piping is detected. Use it carefully, and always test on a real device before deployment.
Question type 'CardSort' is not supported in field surveys
Fix the error (remove or replace the question type), save, and try publishing again. The survey is otherwise unaffected — it can still be published as a standard web survey.
05 A Complete Field Survey
The survey below is a condensed household assessment. It spans three pages, uses skip logic to branch based on answers, and demonstrates a realistic mix of question types. Every type used here is on the supported list.
survey "household_assessment" do
title "Household Assessment"
# ── PAGE 1: Identification ─────────────────────────────────────
page "identification" do
title "Household Identification"
Notification "instructions" do
text "Complete one form per household. Record the household ID exactly as it appears on the listing sheet."
end
OpenEnded "household_id" do
text "Household ID"
required
placeholder "e.g. KLA-2024-0042"
end
SingleSelect "zone" do
text "Zone"
required
option "Zone A"
option "Zone B"
option "Zone C"
option "Zone D"
end
DatePicker "interview_date" do
text "Date of interview"
required
end
action :next
end
# ── PAGE 2: Household composition ─────────────────────────────
page "composition" do
title "Household Composition"
Number "household_size" do
text "Total number of people in the household"
required
min 1
max 30
end
Age "respondent_dob" do
text "Date of birth of the person answering (primary respondent)"
required
end
SingleSelect "respondent_gender" do
text "Gender of primary respondent"
required
option "Female"
option "Male"
option "Prefer not to say"
end
SingleSelect "dwelling_type" do
text "Type of dwelling"
required
option "Permanent structure"
option "Semi-permanent structure"
option "Temporary / makeshift"
end
SingleSelect "water_source" do
text "Primary source of drinking water"
required
option "Piped into dwelling"
option "Public standpipe"
option "Borehole / protected well"
option "Unprotected well or spring"
option "Surface water (river, lake)"
option "Rainwater collection"
option "Vendor / tanker truck"
end
action :next
end
# ── PAGE 3: Services & priorities ─────────────────────────────
page "services" do
title "Services & Community Needs"
SingleSelectMatrix "service_access" do
text "How easy is it for your household to access each of the following services?"
row "Primary health care"
row "Primary school"
row "Secondary school"
row "Market / food supply"
row "Financial services"
column "Very difficult"
column "Difficult"
column "Manageable"
column "Easy"
column "N/A"
end
Ranking "priority_needs" do
text "Rank these needs from most to least urgent for your community"
required
item "Clean water"
item "Healthcare"
item "Education"
item "Roads & transport"
item "Electricity"
item "Income & livelihoods"
end
Rating "program_satisfaction" do
text "Overall, how satisfied is your household with the current program support in your area?"
scale 5
low_label "Very dissatisfied"
high_label "Very satisfied"
end
Discussion "additional_comments" do
text "Any other comments or concerns? (optional)"
end
action :complete
end
end
action :go_to, "page_name"
with a when condition. For example, to skip the services page for
households in Zone D:
SingleSelect "zone" do
text "Zone"
required
option "Zone A"
option "Zone B"
option "Zone C"
option "Zone D"
end
action :go_to, "completion" do
when zone == "Zone D"
end
action :next
The full DSL reference documents all action types, condition operators, and segmentation options.
06 Publishing & Collecting
Once your survey is authored and validated, getting it into the hands of field reps involves three steps: publishing a snapshot, issuing PINs, and loading the survey onto devices. Data flows back automatically when reps reconnect.
Publishing
Publishing a field survey creates a rendered snapshot — the HTML and JavaScript needed to run the survey are generated once and stored. This snapshot is what gets cached on the field device; the original DSL is not involved after publish.
Before the snapshot is created, the system runs the field compatibility validator described in Section 4. Any errors block the publish. Warnings are recorded but don't block it.
A survey cannot be edited after publishing. To make changes, you'll need to create a new published version (or a new survey). Responses already collected against the old version are preserved.
PIN Lifecycle
Field reps authenticate with a 6-digit PIN. PINs are managed by admins through the platform dashboard. Here's the lifecycle:
-
Generate
Admin generates one or more PINs in bulk. The raw 6-digit value is shown once and then stored only as a hash — it cannot be retrieved later. Write it down or distribute immediately.
-
Distribute
Each PIN is assigned to one field rep. Optional label and identifier fields (e.g., enumerator name, assigned area) can be set for tracking.
-
Activate
The field rep enters their PIN on the Syrup Field Client login screen. First-time activation may prompt for a name or other identifying information. Subsequent logins are one-step.
-
Collect
The rep loads the survey URL via the app's Manage panel. The survey is cached locally. Responses are recorded against this PIN, linking data to the rep.
-
Revoke (when done)
When data collection ends, PINs can be revoked to prevent further submissions. Collected data is retained.
Offline Sync
Every completed response is saved to localStorage on the device
immediately — no network required. When the device comes back online, the Service Worker
processes the sync queue and posts responses to the Rails backend in the background.
Each response includes the survey version hash recorded at publish time, so the server knows exactly which version of the survey generated each response. Version mismatches are flagged rather than silently accepted.
Synced responses appear in the admin dashboard under the survey's response view, tagged with the field rep's PIN identifier. From there they can be exported or reviewed in real time as data comes in from the field.