ODK API with SurveyCTO


We use SurveyCTO (built on top of ODK) at Laterite for data collection and have started using their API to sync data. The SurveyCTO API is just for collected data. I'm looking for an API to download the list of blank forms and the xml form definitions and attachments. SurveyCTO pointed me to the ODK API (https://docs.opendatakit.org/openrosa-form-list/) which has this functionality but I can't figure out the syntax to query it. Is there an example of querying the ODK form list API using curl or requests?




It isn't entirely clear what you are attempting specifically, since normally it is not required to manually download forms for tools that support the openrosa APIs. However, you can download forms fairly simply using curl. The only trick is that you need to include a magic header.

batkinson@BNAMCDTPAD ~$ curl -H "X-OpenRosa-Version: 1.0" https://opendatakit.appspot.com/formList
<xforms xmlns="http://openrosa.org/xforms/xformsList">
<name>Collect v1.23 Beta: Background Geopoint Test</name>
<name>All widgets</name>

batkinson@BNAMCDTPAD ~$ curl -H "X-OpenRosa-Version: 1.0" https://opendatakit.appspot.com/formXml?formId=background-geopoint-beta
<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:odk="http://www.opendatakit.org/xforms" xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <h:head><!-- ODK Aggregate upload time: 2019-07-17T22:38:09.063+0000 on https://opendatakit.appspot.com -->
    <h:title>Collect v1.23 Beta: Background Geopoint Test</h:title>
        <background-geopoint-beta id="background-geopoint-beta" version="2019071701">
      <bind nodeset="/background-geopoint-beta/open_location" type="geopoint"/>
      <odk:setgeopoint ref="/background-geopoint-beta/open_location" event="odk-instance-first-load"/>
      <bind nodeset="/background-geopoint-beta/welcome_group/welcome_note" readonly="true()" type="string"/>
      <bind nodeset="/background-geopoint-beta/welcome_group/learn_more" type="string"/>
      <bind nodeset="/background-geopoint-beta/welcome_group/consent" required="true()"/>
      <bind constraint="not(contains(., 'none')) or count-selected(.) = 1" nodeset="/background-geopoint-beta/data_repeat/characteristics" required="true()" type="select"/>
      <bind nodeset="/background-geopoint-beta/data_repeat/repeat_location" type="geopoint"/>
      <bind nodeset="/background-geopoint-beta/comments" type="string"/>
      <bind jr:preload="uid" nodeset="/background-geopoint-beta/meta/instanceID" readonly="true()" type="string"/>
    <group appearance="field-list" ref="/background-geopoint-beta/welcome_group">
      <input ref="/background-geopoint-beta/welcome_group/welcome_note">
        <label>This form demonstrates the background geopoint feature added to ODK Collect v1.23.0-beta.1. You must have that beta or a later version to try it.&lt;br/&gt;&lt;br/&gt;This form records location once at form open and every time the question about your location is asked. If you choose to submit the data you collect, the developers will use it to improve the feature. Thanks for trying it out!&lt;br/&gt;&lt;br/&gt;The functionality is not yet available in XLSForm but will be soon.</label>
      <input appearance="url" ref="/background-geopoint-beta/welcome_group/learn_more">
        <label>Learn more about this feature and Collect v1.23.0-beta.1</label>
      <trigger ref="/background-geopoint-beta/welcome_group/consent">
        <label>I understand that this form records my location. I understand that if I choose to submit it to the ODK test server, anyone will be able to see the locations I have captured.</label>
    <group ref="/background-geopoint-beta/data_repeat">
      <repeat nodeset="/background-geopoint-beta/data_repeat">
        <select ref="/background-geopoint-beta/data_repeat/characteristics">
          <label>Please walk for a little bit and then answer the question below and swipe right. &lt;br/&gt;&lt;br/&gt;If you would like to continue testing the feature, please tap "Add group". When you are done trying out the background geopoint feature, please tap "Do not add." &lt;br/&gt;&lt;br/&gt; Which of these is true about your current location? Please check all that apply.</label>
            <label>It is inside of a building</label>
            <label>There is Wi-Fi</label>
            <label>It is outside of a building and there is a clear view of the sky</label>
            <label>There is at least one building that is two stories or taller</label>
            <label>There is poor cell connection (&lt;2 bars)</label>
            <label>There is dense forest above me</label>
            <label>None of the above</label>
          <odk:setgeopoint ref="/background-geopoint-beta/data_repeat/repeat_location" event="xforms-value-changed"/>
    <input ref="/background-geopoint-beta/comments">
      <label>Comments (please do not share identifying information such as names, phone numbers, etc)</label>

Thanks Batkinson,

That's really helpful. I've adapted the first curl and it works on SurveyCTO for the form list.
curl --digest -u ":" -H "X-OpenRosa-Version: 1.0" https://.surveycto.com/formList

It doesn't work for the xml forms so I'll check back with SurveyCTO for the url.

I'm looking at this to help automate our data downloads and archiving. We'll use the form list to check what is on the server and make sure we are downloading data each night for everything that's not a test form. We'll also automatically save every version of the form used for data collection for archives and change logs.

Thanks again,


The url for the xml form was in the formList results, and just a slightly different url for SurveyCTO.
In case anyone else has the same question on SurveyCTO's ODK API. The code for accessing the ODK API in SurveyCTO is below (capitals for things to specify):

curl --digest -u "USERNAME:PASSWORD" -H "X-OpenRosa-Version: 1.0" https://SERVERNAME.surveycto.com/formList

curl --digest -u "USERNAME:PASSWORD" -H "X-OpenRosa-Version: 1.0" https://SERVERNAME.surveycto.com/forms/FORMID/xml

Hello, I need help also with the Api url for aggregate server we are in need of it, we are working on our university project (building a mobile app with backend of aggregate server), we facing difficult on geting the api url for getforms/ send /and save forms