Skip to content

HTTP Requests and Responses (Submission and Syncs)

ctsims edited this page Feb 28, 2020 · 6 revisions

CommCare relies on a number of HTTP API's for server communication. The core OpenRosa Form Submission API standard for submitting Form Data to servers, the CommCare Sync API for syncing data from the server, and a few others.

This page outlines some of the details of the HTTP request and response formats for those processes, and how special cases are expected to be handled.

Form Submission Headers

CommCare submissions should contain additional headers with requests

Header Value Details
X-OpenRosa-Version 3.0
X-CommCareHQ-LastSyncToken Last Successful Sync Outlined Here
x-openrosa-deviceid current device id Unique identifier for the physical device underneath the runtime

Semantic Response Codes

CommCare servers will issue special response codes to indicate action should be taken on the client. This table outlines expected response codes and how the client should manage the response.

Code API Meaning / Details
202 Sync A Sync response is being calculated, and the request should be retried after a delay
412 Sync An incremental sync is not possible. The client should perform a non-incremental sync and clear the local state before applying the payload.
422 Form Submission The submitted form payload is invalid and cannot be processed by the server. The client should not attempt to send this form again. An OpenRosaResponse message with the nature processing_failure will describe the issue.
429 Multiple Rate Limiting: The server is not currently accepting this type of request from this specific client or user
503 Multiple Rate Limiting: The server is over capacity and not currently accepting this type of request
406 Multiple The server cannot complete the request issued, and the user needs to take a direct action based on a message provided

Asynchronous Restore

When the server provides a 202 response to a sync request, it is signaling that the sync payload is being processed, and that the request should be retried later to retrieve the full response or measure progress on its generation.

Async 202 restore responses should contain an HTTP Header Retry-After with an integer value describing amount of time (in seconds) that the client should wait before re-submitting the request. This time internal doesn't signal when the server anticipates a response being available, but simply when the client should next poll.

If a 202 response includes a body, it should contain an OpenRosaResponse. That response should be parsed for a transaction to signal progress in preparing the sync data

<?xml version="1.0" encoding="UTF-8"?> 
<OpenRosaResponse xmlns="http://openrosa.org/http/response"> 
     <message nature="ota_restore_pending">Optional restore message</message>
     <Sync xmlns="http://commcarehq.org/sync">
           <progress done="55" total="10000"/>
     </Sync>
</OpenRosaResponse>

Rate Limiting

Under periods of high load, or due to abnormal volumes of traffic from individual users or IP Addresses, CommCare servers may respond with a 429 or 503 response code. Upon receiving one of these response codes, the CommCare app should immediately cease any attempts to retry the request. If the request was user triggered, the app should ideally enter a short cool-down period disallowing the user from retrying the request. If the action was automated, the app can continue attempting the action with an exponential back-off in delay between attempts.

User Actionable Errors

Some requests may be unavailable due to actions that need to be taken by a user before they can succeed. If, for example, a user's project space is inactive when a sync request is received, that request cannot be processed until the space is reactivated on the server. In these cases, the server can respond with a 406 response code to signal that the user should explicitly be given a message.

The body of the HTTP response must contain a JSON document with two elements

{
    "error":"locale.translation.key",
    "default_response":"Human readable error message"
}

Upon receiving a 406 response, the app should first attempt to retrieve a message from the localization engine matching the translation key provided from error and present that message in the appropriate locale. If no such translation exists, the app should present the raw default_response to the user.