Access Enketo API functionality through KoboToolbox

Hi,

Does anyone have experience with using KoboToolbox to access the Enketo API functionality?

For example, KoboToolbox has a very useful edit button, to edit a form that has been submitted. For that purpose KoboToolbox is using the Enketo API functionality. I would like to be able to access those functions as well. In particular the function to load an instance for editing, as described in the Enketo documentation: https://apidocs.enketo.org/v2#/post-instance

Hi @bert12
Normally a systems limit can best be tested through various experimental approaches. My suggestion would be you try out a few of the options you are mentioning and indicate which ones work for you or not. We can also have other users contribute to what may have worked for them. Looking forward to more discussions

Regards
Stephane

1 Like

Hi @stephanealoo Stephane,

Thank you for your reply! Here is what I tried:
To attempt access to the Enketo API with the final aim to edit submitted forms, I made this KoBoToolbox test form: https://ee.kobotoolbox.org/x/#6K8reKvt.

I submitted a few forms, to have a couple of examples to test on. One of the submitted forms has this instance ID: instance_id=008704fc-7cd1-4f29-901c-1882d0583ef0, and ID: id=38037350

I am using Postman to try and access the Enketo API functions.

From the examples on the Enketo API docs I derived that I should access this endpoint:
https://ee.kobotoolbox.org/api/v2/instance

But the server response I get so far is: 401, Not Allowed. Invalid API key.

For authentication, I have tried my usual KoboToolbox authentication, both the API token, and the basic authentication which works well in the KoboToolbox API, both the kc as the kpi API’s.
I assume I can also use it to access the Enketo API, on https://ee.kobotoolbox.org/… urls, but is that correct?

1 Like

Hi @bert12,

In this case you’d need a different API key - the one that was configured in Enketo (in config.json) and provides the authentication between the apps. Just curious, are you doing this because you are working on your own data/form server replacement?

Cheers,
Martijn

1 Like

Hi @martijnr Martijn,

Thank you! My use case is to enable coordinators to edit the forms that have been submitted by the people in the field. We do have the form input requirements and hints in place, but the input still sometimes needs correction before it can be automatically processed further. The coordinators don’t have an account at KoboToolbox to edit the form submissions, because they should not be able to edit the submissions of the field people of whom they are not the coordinator and also we don’t want to make their task complex by asking of them to login.

So I would like to send a coordinator the edit url so they can repair the form and submit it again.
I currently only have an account at KoboToolbox and not at Enketo, thinking I could access the Enketo API at https://ee.kobotoolbox.org. I am not working on a local installation, I only use my account at KoBoToolbox, so I guess the config.json is out of my reach. Perhaps I need a subscription of Enketo to access the …/api/v2/instance of my Kobo form?

Many thanks for your input!!

Hi @bert12,

A subscription to Enketo’s paid service would not help in this case.

Unfortunately, there is an issue with this plan (even if you hosted your own Enketo server). Those edit URLs only stay active for a very short period (by default 30 seconds - configurable in Enketo’s configuration - but not recommended to make much longer anyway).

A real solution here would be more finely grained permissions on the KoBo side, but that seems pretty complex. It really has to be managed on the side where the data is stored as it requires managing records (once a record is edited, it gets a new instanceID, so it needs to be effectively locked during editing). Sorry, I don’t have any better ideas to meet your requirements quickly.

1 Like

This isn’t particularly easy, but possibly you could write a tiny web application that accepts requests containing a submission UUID and then:

  1. Gets the ID for that UUID by making an API request to KPI, using token or HTTP basic authentication. A sample URL would be https://kf.kobotoolbox.org/api/v2/assets/aLQD8NJG6HCNZQw5TZdyZX/data/?q={"_uuid":"952d24f5-26d0-4cc1-9c30-09b997e9703e"}&fields=["_id"]&format=json;
  2. Parses the output; you might have multiple IDs per UUID if a data-collection client behaves badly, e.g. {"count":2,"next":null,"previous":null,"results":[{"_id":38149357},{"_id":38149366}]}. Hopefully that never happens under normal circumstances!
  3. Takes the ID and requests an Enketo edit URL from KPI (authentication still required at this point), e.g. https://kf.kobotoolbox.org/api/v2/assets/aLQD8NJG6HCNZQw5TZdyZX/data/38149366/edit/?return_url=false&format=json;
  4. Parses the output, e.g. {"url":"https://ee.kobotoolbox.org/edit/::iinbheUI?instance_id=952d24f5-26d0-4cc1-9c30-09b997e9703e&returnUrl=false"}, and redirects the requesting user to the edit URL. These edit URLs do not need any authentication.

Maybe you could simplify this by referencing submissions by ID instead of UUID when you correspond with your coordinators. You’d probably still need steps 3 and 4 to happen in an automated way somehow, since as Martijn mentioned the edit URLs expire very quickly.

3 Likes

Thank you John @jnm ,

That is a great solution! Your step 3 is what I have been searching for and didn’t find until now.

In the meantime I have been using a workaround in which I use the KoBo API to fetch the content of a submitted form, split out each field and pass that data as xml in the url of an empty form to get a copy of the original submission, like this:
https://ee.kobotoolbox.org/x/?d[%2FaYY7X8SYjTRw7QNN29tAQ6%2FEntry1]=25&d[%2FaYY7X8SYjTRw7QNN29tAQ6%2FEntry2]=3521&d[%2FaYY7X8SYjTRw7QNN29tAQ6%2Fref]=This_form_overwrites_form:38302492#6K8reKvt

I am adding an extra variable to store the ID of the original report that is replaced by this report, using the KoBo API to delete the original form once the new one arrives.

A limitation of this method is that some browsers have a limit on the length of the url of around 2000 characters, so the data to be passed is limited in length. Also media cannot be sent this way.
It works nicely for me though, as our form has only around 30 fields, text only.

But your solution is much better, requires less code to be written and has less limitations.

Where did you find the format of the endpoint in your step 3: https://kf.kobotoolbox.org/api/v2/assets/aLQD8NJG6HCNZQw5TZdyZX/data/38149366/edit/?return_url=false&format=json

Can you point me to where that is documented ?

Thanks again!

1 Like