A friendly introduction to writing SRP surveys for export to XForm/ODK — no prior experience required.

01What Is SRP?

The Problem

You want to collect data in the field using ODK Collect, KoboToolbox, or another ODK-compatible tool. Those tools read XForm XML files — a format that is powerful but tedious to write by hand and nearly impossible to read or review at a glance.

SRP is a small, purpose-built language for writing surveys. Think of it the way you might think of Markdown for documents — a readable, text-based syntax that describes exactly what you want, without ceremony. You write an .srp file, and SRP exports it to a valid XForm XML file ready to load into ODK Collect, KoboToolbox, or any other tool in the ODK ecosystem.

Here is what you can express in SRP without any programming background:

  • Pages of questions with titles and introductory text
  • 20 XForm-compatible question types — multiple choice, open-ended, matrix grids, ratings, sliders, media upload, and more
  • Skip logic — send respondents to different questions based on their answers
  • Conditional content — show or hide questions based on previous answers
  • Screener logic — disqualify respondents mid-survey

The .srp file is your source of truth. The XForm XML is the output — generated, not maintained. If your survey changes, you edit the .srp file and re-export.

It's Just a Text File

An SRP file is a plain text file with a .srp extension. You can open it in any text editor — Notepad, VS Code, TextEdit, Vim, anything. There is nothing to install to write one.

Because it is plain text, you get a lot for free:

  • Share it — email it, paste it into a chat message, put it in a shared folder
  • Version it — store it in Git, see exactly what changed between drafts, collaborate with pull requests
  • Copy-paste blocks — reuse a page or question block from a previous instrument in seconds
  • Review it — a colleague can read the file and understand the entire survey logic at a glance, no special software needed

Convention: Files use the .srp extension by convention, but they are ordinary UTF-8 text. Any editor that can save a plain text file will work.

Try It in Your Browser

The fastest way to get started is the SRP Playground. It has a built-in editor on the left and a live survey preview on the right. Every example in this guide can be pasted directly into the playground and previewed immediately — no account required.

Tip: As you read through this guide, open the playground in a second tab and paste in the examples. Seeing them render in real time is the fastest way to build intuition for the language before you export to XForm.

02Your First Survey

Anatomy of a Survey

Here is the smallest useful survey you can write — one page, one question, done:

srp
page "feedback" do
  title "Quick Feedback"

  SingleSelect "experience" do
    text "How was your experience today?"

    option "Great"
    option "It was okay"
    option "Not good"
  end

  action :complete
end

Let's walk through each part:

  • page "feedback" do … end — declares a page. The name in quotes ("feedback") is a unique internal identifier. It never appears on screen; it is used when you need to refer to this page in skip logic.
  • title "Quick Feedback" — the heading displayed to the respondent at the top of the page. Every page must have a title.
  • SingleSelect "experience" do … end — a question block. SingleSelect is the question type (radio-button style). "experience" is the unique name for this question — used to identify it in results and in logic.
  • text "…" — the question text shown to the respondent.
  • option "…" — one answer choice.
  • action :complete — when the respondent submits this page, mark the survey as complete. Without this, the survey would look for a next page to show.

Question names must be unique across the entire survey. They are how SRP identifies responses and connects logic. Short, lowercase, underscore-separated names work well: "brand_awareness", "age_range", "q3_satisfaction".

Adding More Questions

A page can hold as many questions as you like — just add them one after another inside the page block. Respondents see all questions on the page before clicking Next.

srp
page "about_you" do
  title "A Bit About You"

  SingleSelect "age_range" do
    text "What is your age range?"

    option "Under 25"
    option "25–34"
    option "35–44"
    option "45–54"
    option "55 or older"
  end

  MultiSelect "interests" do
    text "Which topics interest you? Select all that apply."
    min_selections 1
    max_selections 3

    option "Technology"
    option "Health & Wellness"
    option "Finance"
    option "Travel"
    option "Food & Cooking"
  end

  OpenEnded "role" do
    text "What is your current job role?"
  end

  action :complete
end

Notice a few new things here:

  • MultiSelect — lets respondents pick more than one option (checkboxes).
  • min_selections 1 — require at least one choice.
  • max_selections 3 — cap it at three choices.
  • OpenEnded — a single-line free-text input.

The required keyword makes any question mandatory — just add it inside the question block on its own line:

srp
OpenEnded "role" do
  text "What is your current job role?"
  required
end

03Pages

Structure

A survey is a sequence of pages. By default, respondents move through them in the order they appear in the file. Each page is a page "name" do … end block with a title and any number of questions.

Rules to keep in mind:

  • Page names must be unique within a survey.
  • Every page must have a title.
  • Pages can contain zero or more questions.
  • A page with action :complete ends the survey successfully.
  • A page with action :terminate ends the survey and marks the respondent as disqualified.
  • Pages without an action simply advance to the next page in the file.

Multiple Pages

Here is a two-page survey with a welcome screen and a question page:

srp
page "welcome" do
  title "Welcome!"

  Notification "intro" do
    text "This short survey takes about 2 minutes. Thanks for your time."
  end
end

page "questions" do
  title "Your Opinion"

  SingleSelect "satisfaction" do
    text "How satisfied are you with our product overall?"
    required

    option "Very satisfied"
    option "Satisfied"
    option "Neutral"
    option "Dissatisfied"
    option "Very dissatisfied"
  end

  Discussion "feedback" do
    text "Is there anything specific you would like us to improve?"
  end

  action :complete
end

Notification is a display-only block — it shows text to the respondent but collects no answer. It is perfect for introductions, instructions, or transition messages between sections.

Discussion is a multi-line text area, great for open-ended feedback where you expect longer responses.

04XForm-Supported Question Types

SRP has over 20 field question types, and 20 of them export to XForm. A small number of highly visual or specialized types (HeatMap, CardSort, ConjointChoice, etc.) have no XForm equivalent — they are available when running surveys on the SRP field surveys platform. The XForm Export Reference has the full compatibility table.

Text Responses

OpenEnded — single-line text → XForm string

srp
OpenEnded "city" do
  text "What city do you live in?"
  required
end

Discussion — multi-line text → XForm string with appearance="multiline"

srp
Discussion "suggestions" do
  text "What improvements would you most like to see?"
end

Number — numeric input → XForm int or decimal

Use min_value / max_value to emit XForm constraints automatically.

srp
Number "household_size" do
  text "How many people live in your household?"
  min_value 1
  max_value 20
  allow_decimals false
  required
end

Selection Questions

SingleSelect — pick one → XForm select1

srp
SingleSelect "household_water_source" do
  text "What is your household's primary source of drinking water?"
  required

  option "Piped into home"
  option "Communal standpipe"
  option "Borehole or well"
  option "Surface water (river, lake)"
  option "Rainwater collection"
  option "Tanker truck"
  option "Other"
end

MultiSelect — pick many → XForm select

srp
MultiSelect "health_conditions" do
  text "Has anyone in your household been diagnosed with any of the following? Select all that apply."

  option "Hypertension"
  option "Diabetes"
  option "Malaria"
  option "Tuberculosis"
  option "None of the above"
end

Ranking — drag-to-order → XForm odk:rank

srp
Ranking "priorities" do
  text "Rank these community needs from most to least urgent."

  item "Clean water access"
  item "Healthcare facility"
  item "School or education"
  item "Road infrastructure"
  item "Electricity"
end

Rating & Scale Questions

Rating — star or numeric scale → XForm select1

srp
Rating "service_quality" do
  text "How would you rate the quality of service at this clinic?"
  number_of_ranks 5
  required
end

NPS — 0–10 fixed scale → XForm integer

srp
NPS "recommend" do
  text "How likely are you to recommend this health centre to a neighbour?"
  min_label "Not at all likely"
  max_label "Extremely likely"
  required
end

Slider — range input → XForm range

srp
Slider "confidence_level" do
  text "How confident are you in the information you received today?"
  min_value 0
  max_value 100
  step 5
  min_label "Not at all confident"
  max_label "Completely confident"
end

Matrix Questions

Matrix questions are flattened during XForm export — each row becomes its own independent select1 or select question. The question names in the XForm are derived from the matrix name and the row label, so keep row labels concise.

SingleSelectMatrix — one selection per row → one select1 per row

srp
SingleSelectMatrix "service_ratings" do
  text "Please rate each aspect of the clinic visit."
  required

  row "Waiting time"
  row "Staff friendliness"
  row "Cleanliness"
  row "Treatment received"

  column "Excellent"
  column "Good"
  column "Fair"
  column "Poor"
end

MultiSelectMatrix — multiple selections per row → one select per row

srp
MultiSelectMatrix "barriers" do
  text "What barriers did you face when accessing each service?"

  row "Antenatal care"
  row "Child immunisation"
  row "Family planning"

  column "Distance"
  column "Cost"
  column "Long wait times"
  column "Lack of supplies"
end

Other Supported Types

DatePicker → XForm date

srp
DatePicker "visit_date" do
  text "What was the date of your most recent clinic visit?"
  required
end

Age → XForm integer

srp
Age "respondent_age" do
  text "How old are you?"
  required
end

PhoneNumber → XForm string

srp
PhoneNumber "contact_number" do
  text "What is the best phone number to reach you on?"
end

Notification — display text, no input → XForm read-only note

Use Notification to show instructions or transition copy between sections.

srp
Notification "section_intro" do
  text "The next section asks about your household's access to health services. Please answer for the past 12 months."
end

Additional Supported Types

ButtonRating — button-based scale → XForm select1 (likert)

Each button becomes a <select1> item. Behaves like a Rating but with custom button labels instead of a numeric scale.

srp
ButtonRating "ease_of_use" do
  text "How easy was the registration process?"
  button "Very Easy"
  button "Easy"
  button "Neither"
  button "Difficult"
  button "Very Difficult"
  required
end

ButtonCheckbox — button-based multi-select → XForm select

Like MultiSelect but with a button UI. Each button maps to a <select> item.

srp
ButtonCheckbox "services_used" do
  text "Which services did you use during your visit?"
  button "Outpatient"
  button "Pharmacy"
  button "Laboratory"
  button "Maternal health"
end

ThisOrThat — binary choice → XForm select1

Presents exactly two options. Maps to a two-item <select1>.

srp
ThisOrThat "contact_preference" do
  text "How would you prefer to be contacted?"
  this "By phone"
  that "By text message"
end

FillInTheBlank — sentence completion → XForm string

The blank markers (___) appear as literal text in the XForm label. ODK Collect shows a text input below the full sentence.

srp
FillInTheBlank "wait_time" do
  text "I waited approximately ___ minutes before being seen."
end

MediaUpload — file capture → XForm upload

Maps to the XForm <upload> element. Use the accept attribute to specify the media type: image, audio, or video.

srp
MediaUpload "facility_photo" do
  text "Take a photo of the facility entrance sign."
  accept "image"
  required
end

05Skip Logic

Surveys rarely need to show everyone every question. SRP lets you route respondents to different pages based on their answers — this is called skip logic.

Skipping Pages

Add an action inside an option block to send the respondent to a specific page when they choose that option:

srp
page "purchase_check" do
  title "About Your Purchase"

  SingleSelect "made_purchase" do
    text "Have you made a purchase with us in the last 90 days?"
    required

    option "Yes" do
      action :skip_to, "purchase_details"
    end

    option "No" do
      action :skip_to, "general_feedback"
    end
  end
end

page "purchase_details" do
  title "Your Purchase"

  Rating "purchase_satisfaction" do
    text "How satisfied were you with your most recent purchase?"
    number_of_ranks 5
    required
  end

  action :complete
end

page "general_feedback" do
  title "General Feedback"

  Discussion "general_thoughts" do
    text "What would encourage you to make a purchase?"
  end

  action :complete
end

When the respondent picks "Yes", they jump directly to the "purchase_details" page. "No" takes them to "general_feedback". Pages that are skipped are simply not shown.

Note: The page name in action :skip_to, "page_name" must match the internal name of an existing page exactly, including capitalization.

Screening Out

Use action :terminate inside an option block to end the survey and mark the respondent as disqualified. This is the standard pattern for screener surveys:

srp
page "screener" do
  title "Eligibility Check"

  SingleSelect "owns_car" do
    text "Do you currently own or lease a car?"
    required

    option "Yes"

    option "No" do
      action :terminate
    end
  end
end

page "main_survey" do
  title "About Your Vehicle"

  SingleSelect "car_type" do
    text "What type of vehicle do you drive?"
    required

    option "Sedan"
    option "SUV or crossover"
    option "Truck"
    option "Electric or hybrid"
    option "Other"
  end

  action :complete
end

Respondents who choose "No" are terminated immediately. Everyone else continues to the main survey.

06Segments & Conditions

Skip logic is great for simple branching, but sometimes you need more nuance — show a follow-up question only to people who rated you poorly, or ask about a feature only to people who said they use it. That is where segments come in.

What Is a Segment?

A segment is a named group that a respondent is placed into based on their answer. You define it inside an option block using the segment keyword. Think of it as tagging a respondent: "this person is a dissatisfied_user."

A respondent can belong to multiple segments. Segments accumulate as they move through the survey — an answer on page 2 can add them to a segment that was also used on page 1.

show_only_if

Once you have a segment, you can use show_only_if on a page or question to display it only when the respondent is in that segment.

Passing multiple segment names to show_only_if uses OR logic — the page or question appears if the respondent is in any of the listed segments.

A Full Example

Here is a satisfaction survey that shows a follow-up page only to dissatisfied respondents:

srp
page "satisfaction" do
  title "Overall Satisfaction"

  SingleSelect "overall_sat" do
    text "How satisfied are you with our service overall?"
    required

    option "Very satisfied"
    option "Satisfied"
    option "Neutral"

    option "Dissatisfied" do
      segment "unhappy"
    end

    option "Very dissatisfied" do
      segment "unhappy"
    end
  end
end

# This page only appears for respondents in the "unhappy" segment
page "follow_up" do
  title "Help Us Improve"
  show_only_if "unhappy"

  MultiSelect "pain_points" do
    text "What areas fell short of your expectations? Select all that apply."
    required

    option "Response time"
    option "Quality of support"
    option "Value for money"
    option "Ease of use"
    option "Something else"
  end

  Discussion "improvement_details" do
    text "Tell us more about what we could do better."
  end
end

page "thanks" do
  title "Thank You"

  Notification "closing" do
    text "Thank you for your feedback. We read every response and use it to improve our service."
  end

  action :complete
end

Satisfied and neutral respondents go straight from "satisfaction" to "thanks". Dissatisfied respondents are placed in the "unhappy" segment and see the "follow_up" page first.

You can also use show_only_if on individual questions within a page — not just on entire pages. This lets you keep related questions together while still tailoring the experience:

srp
page "feedback" do
  title "Your Feedback"

  SingleSelect "would_recommend" do
    text "Would you recommend us to a friend?"
    required

    option "Yes, definitely" do
      segment "promoter"
    end

    option "Probably yes" do
      segment "promoter"
    end

    option "Not sure"

    option "Probably not" do
      segment "detractor"
    end

    option "Definitely not" do
      segment "detractor"
    end
  end

  # Only promoters see this question
  OpenEnded "referral_reason" do
    text "What would you tell a friend about us?"
    show_only_if "promoter"
  end

  # Only detractors see this question
  OpenEnded "detractor_reason" do
    text "What would need to change for you to recommend us?"
    show_only_if "detractor"
  end

  action :complete
end

07Next Steps

You now know enough to author an XForm-ready survey in SRP. Here is a quick recap:

  • A survey is a sequence of page blocks, each with a title and questions.
  • Questions have types (SingleSelect, MultiSelect, OpenEnded, etc.), a unique name, and text.
  • action :skip_to, "page" inside an option routes the respondent to a different page.
  • action :terminate disqualifies; action :complete ends successfully.
  • segment "name" tags a respondent; show_only_if "name" conditionally shows content.
  • SRP files are plain text — write them anywhere, share them, version them with git.

Optional: Submission URL

When you export from the ODK Export page, you can enter an optional Submission URL. This adds a <submission action="..."> element to the XForm, which tells ODK Collect where to send collected responses. Leave it blank if you will configure the submission URL directly in your ODK server or tool.

Reference docs

SRP is much more than XForm

XForm export covers 20 of SRP's field question types — the subset with clean ODK equivalents. The SRP language itself, and the srpsurveys.com platform built on it, go significantly further.

Syrup Field Surveys is an offline-first survey collection platform designed for research anywhere — clinics, rural communities, events, anywhere signal is unreliable. It is built around offline from the start, not as an add-on:

  • Load a survey URL once. From that point on, the survey runs entirely on-device — no connectivity needed.
  • Responses queue locally and sync automatically when connectivity returns. Nothing is lost.
  • Clean, structured, validated data every time — no paper fallback, no manual entry.

On the full SRP platform you also get access to the complete question vocabulary — types that go well beyond what XForm can represent:

HeatMap

Click-coordinate capture on an image — mark locations, zones, or reactions

CardSort

Drag cards into categories — ideal for mental model and taxonomy research

MaxDiff

Best/worst scaling — find which items respondents value most and least

ConjointChoice

Discrete choice experiments — profile-based trade-off analysis

ConstantSum

Allocate a fixed number of points across options — measure relative importance

TextHighlighter

Respondents highlight passages in a text — capture attention and sentiment

EmotionSelector

Emoji-based emotion capture — quick, culturally flexible sentiment questions

StickyNote

Place sticky notes on an image — spatial feedback on concepts or layouts

The platform also supports text piping ({{question_name}} substitution), dynamic option lists populated from previous answers, and advanced skip logic. All of it is authored in the same readable .srp format — the same language you have been learning here.

Start small. Paste the five-line example from Section 2 into the playground, add one question at a time, and preview as you go. Most people are writing real surveys within the first half hour — and exporting to XForm shortly after.