Key concepts, design considerations, how to configure, and best practices

RapidPro is the open-source platform that powers TextIt, developed by UNICEF and Nyaruka. RapidPro allows you to visually build messaging workflows for mobile-based services. Review RapidPro’s documentation to familiarize yourself with various components that include the API. Before you embark on designing an integrated RapidPro/CHT workflow, you should start by understanding the needs of your users, identifying a problem to solve, and establishing goals. While an integrated RapidPro/CHT workflow can open up many powerful and personalized messaging capabilities, introducing an additional technology solution does come with complexities and cost. A good way to mitigate some of the complexities of setting up and hosting RapidPro yourself is to utilize a SaaS solution such as TextIt. TextIt offers transparent per message pricing and free credits to start off.

Coming up with a design to accommodate user needs requires a detailed understanding of the capabilities of both systems and conceptually where it makes sense to introduce interactions between them. Below we introduce some of the key concepts in RapidPro, but to learn more you can take one of their online courses, watch some of their videos, and check out their deployment toolkit.

RapidPro Concepts

Before designing your integrated RapidPro/CHT workflow, it’s important to understand a couple key functional concepts in RapidPro: Flows, Campaigns, and Triggers.


Flows are a series of steps you link together visually to define the interactions users will have. At any point in the flow, you can trigger actions such as sending an SMS, email, or calling external APIs. Flows are the base for RapidPro’s other features.

Use Case Example: Send an SMS to a patient asking if they are experiencing any new symptoms today. If so, let the patient know that a CHW will contact them. If not, let the patient know that they will receive another check-in message in three days and to contact their CHW if any new symptoms develop before then.

Additional Resources: Mastering Flows and How to Build a RapidPro Flow.


Campaigns allow you to schedule messages and flows around a date unique to each contact in a group, like a delivery date or registration date. You can add any number of Events to the Campaign.

Use Case Example: Send a daily check-in message to quarantined patients for 14 days to see if they have developed any symptoms.

Additional Resources: Creating a Campaign


Triggers allow you to control how or when a Flow begins. A Trigger can be a keyword received in a text, a point in time, a missed call, or even a follow to a Twitter handle.

Use Case Example: Start a health assessment Flow whenever a person sends the text assessment to a specific short code.

Additional Resources: Creating a Keyword Trigger that starts a Flow

Workflow Design

Designing an integrated workflow between mutliple systems is more of an art than a science. Drafting a sequence diagram (below) is a good first step. When drafting your sequence diagram, it is useful to consider a few key integration touchpoints that are common across many integrated workflows.

  1. One system initiates or triggers an action in the other system
  2. One system needs to get information from the other system
  3. One system wants to store or update data in the other system

Sequence Diagrams

A sequence diagram will help you identify the various actors in a given workflow and what the flow of data will look like. Below is an overview and example diagram for a patient initiated triage and feedback workflow.

  1. Patient triggers a RapidPro flow by sending a message to a short code
  2. Using the phone number of the patient, RapidPro requests information from the CHT
  3. The CHT responds with the patient’s name and other details
  4. RapidPro sends personalized messages to conduct triage for the patient
  5. RapidPro determines the outcome
  6. RapidPro sends the outcome to the patient via SMS and posts the results to the CHT
  7. If the patient needs to be followed-up with, the CHT creates a task for the appropriate CHW
  8. Once the CHW completes that task, the CHT initiates the Feedback Flow in RapidPro
  9. RapidPro logic records feedback via SMS from the patient
  10. The results of the feedback flow are saved in the CHT



The information below focuses on specific interactions between RapidPro and the CHT, it does not cover RapidPro specific configuration, consult RapidPro documentation and resources for that. Also, the examples and code snippets below are using TextIt, the hosted RapidPro service mentioned above.

Create RapidPro user in CHT

For RapidPro to communicate with the CHT, you need to create a User in the CHT that will be used by RapidPro when calling the CHT’s APIs. This can be done from the App Management page in the CHT. When adding the user in the CHT, be sure to select the Gateway - Limited access user for Medic Gateway Role.


Globals are shared values that can be referenced in flows, as well as broadcasts and campaigns, within your account referenced by @globals.value_name. They allow you to create a value once and use it repeatedly without having to reenter the value. Likewise, globals make updating a shared value much easier. Rather than manually changing a value everywhere it’s used in your account, simply update the value found in your Globals page.


Once you have configured a Global value, you can easily use it in your flows like this:


Start RapidPro Flow from CHT

One of the most common activities you’ll want to do is trigger a Flow in RapidPro based on something that occurred in the CHT. For example… whenever a specific form is submitted in the CHT with some conditional value, start a flow in RapidPro. To do this, you will use the Outbound feature in the CHT, invoking the Flow Starts Endpoint in RapidPro.

Below is an example outbound config in the CHT called textit-self-quarantine that will trigger a flow in RapidPro whenever a covid_trace_follow_up form is submitted in the CHT where symptom = no. It will also pass an extra date value for self_quarantine_enrollment.

  "textit-self-quarantine": {
    "relevant_to": "doc.type === 'data_record' && doc.form === 'covid_trace_follow_up' && doc.fields.trace.symptom === 'no'",
    "destination": {
      "base_url": "https://textit.in",
      "auth": {
        "type": "header",
        "name": "Authorization",
        "value_key": "textit.in"
      "path": "/api/v2/flow_starts.json"
    "mapping": {
      "flow": {
        "expr": "<UUID of Flow in RapidPro>'"
      "urns": {
        "expr": "[ 'tel:' + doc.fields.inputs.contact.phone ]",
        "optional": false
      "extra.self_quarantine_enrollment": {
        "expr": "new Date(doc.reported_date).getDate()+'-'+ (new Date(doc.reported_date).getMonth()+1) +'-' + new Date(doc.reported_date).getFullYear()+ ' ' + new Date(doc.reported_date).getHours() + ':' +  new Date(doc.reported_date).getMinutes()",
        "optional": false
      "extra.name": "doc.fields.inputs.contact.surname"

Save flow data to the CHT

Once a user has completed a Flow in RapidPro, it is likely you will want to record some of the information collected in the RapidPro flow back in the CHT. This can be achieved by utilizing the Call Webhook action in RapidPro.

StepApplicationConfig step
1CHTConfigure a JSON Form that includes the fields from RapidPro you want to send to the CHT.
2RapidProAdd a Call a Webhook node.
3RapidProPOST to the records endpoint in the CHT. If you used the Global value mentioned above, the POST will look something like @globals.api/v2/records.
4RapidProSet a Result Name
5RapidProConfigure HTTP Headers to be Content-Type -> application/json
6RapidProConfigure the POST Body (see example below)

Look up CHT data from RapidPro

Another common action you will likely need to perform in RapidPro is getting information from the CHT about a user or patient based on their phone number. You can use the contacts-by-phone API to get fully hydrated contacts associated to that phone number.

Best Practices


  1. If language options are included allow users to select their preference before beginning the flow
  2. Make sure the language and terminology of your messages are appropriate for the audience
  3. Use a personalized welcome message before asking users to take actions
  4. Keep content brief and relevant to the topic as to not overload the user
  5. Make your response requests and calls-to-action clear
  6. Be cognizant of form collisions during assessments (ex. “0=no, 1=yes” if those numbers may also reference workflow codes, or “N=no” if “N” is the code to create a new person)
  7. Use standards in logic where possible (ex. The non-zero value is true; 0=false, 1=true, 0=no, 1=yes)
  8. Sign the first message with the partner’s name, or MOH for visibility
  9. Consider providing an option to revisit information again (ex. Text 123 to this number to receive these messages again)


A workspace contains models for a set of RapidPro users, and it also identifies a company or project. Set up staging and production workspaces so that builds, tests and updates can proceed safely before and after deployment.

SMS Messaging Channels

RapidPro supports both Android channels and SMS aggregators.

Ensure that you install the maximum number of SMS packs (available in the RapidPro SMS Channel Android app) and follow these best practices when using Android channels:

  1. Prevent the Android channel from going to sleep. Some steps to achieve this are available on dontkillmyapp:

    • Do not optimize battery usage.
    • Make sure that the app is on the list of Apps that will not be put to sleep.
    • Set Background Limit to Standard Limit and confirm that the RapidPro app has the toggle enabled in “Background Check” and all of the apps have “App Standby state: ACTIVE” in Standby apps.
    • Keep the phone plugged into a power source.
  2. Automatically wake up the phone.

    • The RapidPro system uses Google Cloud Messaging which wakes up the phone whenever a message is sent. Install an APK that makes the channel relay messages as soon as RapidPro emits.
  3. Alerts for when things go wrong.

    • Send monitoring emails and alert various parties when the Android Channel goes to sleep or becomes unavailable. This can be done from the channel’s management page under Alert Email

Android channels can be used with a bulk sender to get past the 330 outgoing messages per hour.

Medic recommends that you use shared or dedicated shortcodes for SMS messaging. Dedicated shortcodes are preferred because recipients do not have to include the keyword with each response submitted. Shortcode procurement can be a lengthy process, so make arrangements for the shortcode in advance. It is possible but inconvenient to migrate to a shortcode after deployment.

Medic recommends that SMS costs be zero-rated so that respondents do not incur charges. This motivates them to respond.

Flow design

Tips and best practices are listed below:

  • If possible, have less than 10 questions. Long surveys may either lead to low completion rates or rushed responses that affects the data quality.
  • Close ended questions are better and easier to respond and handle in RapidPro since respondents only have to send a number or letter such as 1 for “Yes”, 2 for “No”.
  • Avoid sensitive questions since privacy cannot be guaranteed over SMS and where it is common to share phones.
  • Include intro and outro messages. Intro messages serve the purpose of giving the survey details such as the background of the survey, the number of questions, data protection, whether there shall be follow up, SMS billing, etc. Outro messages are helpful to notify respondents that they survey is over and commonly include thank you notes.
  • Include questions that give the respondent an opportunity to opt-in or out of the survey. If they opt out, do not send a follow-up text.
  • Keep it short, to the size of one SMS (160 characters). Longer messages will be split and may not display well on the recipients’ devices since Mobile Network Operators (MNOs) cannot guarantee that the multi-parts shall be delivered in the desired order. Medic recommends that you retain the same message length as you localize to multiple languages. Truncate appropriately if long contact names included in the message push the length beyond the limit.

Flow programming

  • Use skip logic to ask relevant questions only. For example, number of children only if they have children.
  • Automate error messages to validate responses. For example, You submitted an invalid response. Reply 1 for “Yes”, 2 for “No”. These can be customized.
  • Reduce unnecessary messaging by using reminders and follow-up messages selectively on respondents by first differentiating those that completed a flow versus those that did not.
  • Customize messages as much as possible by pre-populating information already known such as name, to target respondents, especially when phones are shared among clients.
  • Translate all messages, especially when deploying in a multi-lingual environment. This ensures that respondents fully understand the survey in their language.
  • Beware of the timing of the surveys that directly affects response rates. From experience, sending questions when respondents are busy with their errands during the day ultimately leads to low response rates as opposed to evenings when they are done for the day.
  • Make sure you handle unsolicited responses by redirecting such to, for example, a flow that eventually alerts concerned individuals such as reports of an outbreak.
  • Medic recommends that you use timeouts or pauses to send automatic messages after a period of inactivity during a survey. This helps nudge the respondents to complete their flows.


  • Persist a unique identifier for each respondent entering the flows. This identifier shall be used to link flow runs to the recipients to make data analysis smooth.
  • Use consistent language and message design patterns to maintain a consistent experience and conversation. For example, if including a contact name at the beginning of a message, keep it that way for all messages including the localized messages.
  • Be mindful of when you save data back to the CHT. This should happen at major milestones in a flow, for example, end of a flow or before sending a payload to an API endpoint.
  • Use globals, shared values that can be referenced inflows, as well as broadcasts and campaigns, within your account referenced by @globals.value_name. This prevents re-entry of values in various components and allows flows to be shared easily in staging and production environments.
  • Beware of concurrency that is not supported in RapidPro. Concurrency refers to a situation whereby one contact participates in more than one flow at the same time. Whenever this happens, the former flow shall be interrupted in favor of the latter. This can result in respondents exiting flows before completion, which is a confusing user experience and results in poor survey data. A main flow that spins up individual flows may be useful to consider.


Testing includes manual and scripted.

Manual testing

  • Telegram is an effective, free, convenient tool for testing that is great for developers and quick testing.
  • Prior to release, it is crucial that you test the workflow as close to production as possible. Medic recommends that you use the production messaging channels, to especially check messaging fidelity.
  • Medic recommends that you run a pilot prior to scaling a deployment. Remember, this shall expose the flows to real respondents and be helpful towards uncovering details such as text display among others.
  • In order to prevent breakages in flows, run full end-to-end tests as edits/changes can have unpredictable impacts. Check that the entire flow is not impacted by the change prior to releasing in production.

Scripted testing

These tests cover the parts that are inaccessible via manual tests. They include units that test individual components and end-to-end tests that test a flow from start to end. As a best practice, the following test pattern using the cht-conf-test-harness is recommended:

  • Create contact doc via cht-conf-test-harness
  • PUT docs into localhost API
  • Trigger RapidPro flow
  • Wait for a RapidPro flow to complete
  • Fetch state of contact in RapidPro
  • Wait for document to be created in API
  • Inject document into cht-conf-test-harness
  • Mock passage of time to test task behavior
  • One e2e test per production scenario


  • Make sure all your flows are in source control. For every change, no matter how small (fixing a typo, etc), at the very least, document and commit the JSON for the flows to Github. This makes flows restorable, auditable, and releasable across environments
  • Medic recommends that you use an automated deployment process when pushing changes to an instance - either staging or production. A CI/CD reduces manual errors and ensures your production state is tested and reproducible.
  • Remember to set up the rapidpro2pg service to get your RapidPro workspace data over to the Postgres database.


  • Make sure you are monitoring workflows. Are they finishing as expected? Are some workflows not being used? A useful feature is the “send email” action whenever an unexpected event occurs while the flow is in progress, for example, failure calling an API endpoint.
    • Include relevant parties in the monitoring notifications. For starters, a mailing group that includes all parties will do it without re-entry of each address of relevant recipients.
    • Include notifications to respondents too, appropriate to the messaging method.
  • Check that your workspace has enough credits and ensure RapidPro email credit alerts are configured so that credits top ups are done promptly.

CHT Applications > Features > Integrations > RapidPro

Integrate interactive messaging conversations into your workflows