OData Endpoints#
OData is an emerging standard for the formal description and transfer of data between web services. In its most ambitious form, it aims to be the standard way for any REST or REST-like API to enable interoperability with other services, not unlike the API Blueprint format this document is written in. However, in practical usage today it is primarily a way for data-centric web services to describe and transfer their data to various clients for deeper analysis or presentation.
ODK Central implements the 4.0 Minimal Conformance level of the specification. Our goal is to enable data analysis and reporting through powerful third-party tools, sending them the data over OData, rather than attempt to create our own analysis tools. Today, our implementation primarily targets Microsoft Power BI and Tableau, two tools with reasonably robust free offerings that provide versatile analysis and visualization of data.
While OData itself supports data of any sort of structure, Power BI and Tableau both think in terms of relational tables. This presents an interesting challenge for representing ODK's group
and repeat
structures in OData. Our current solution is to treat every repeat
in the Form
definition as its own relational table, and we invent stable join IDs to relate the tables together.
In general, the OData standard protocol consists of three API endpoints:
The Service Document describes the available resources in the service. We provide one of these for every
Form
in the system. As of version 2023.2, we also provide one for everyDataset
.The Metadata Document is a formal XML-based EDMX schema description of every data object we might return. It is linked in every OData response.
The actual data documents, linked from the Service Document, are a simple JSON representation of the submission data or entity, conforming to the schema we describe in our Metadata Document.
As our focus is on the bulk-export of data from ODK Central so that more advanced analysis tools can handle the data themselves, we do not support most of the features at the Intermediate and above conformance levels, like $sort
or $filter
.
OData Form Service#
ODK Central presents one OData service for every Form
it knows about. To access the OData service, simply add .svc
to the resource URL for the given Form.
Service Document#
GET /v1/projects/{projectId}/forms/{xmlFormId}.svc
The Service Document is essentially the index of all available documents. From this document, you will find links to all other available information in this OData service. In particular, you will find the Metadata Document, as well as a data document for each table defined by the Form
.
You will always find a link to the /Submissions
subpath, which is the data document that represents the "root" table, the data from each Submission
that is not nested within any repeat
s.
This document is available only in JSON format.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
xmlFormId |
The Example: |
Response
HTTP Status: 200
Content Type: application/json; charset=utf-8; odata.metadata=minimal
{
"@odata.context": "https://your.odk.server/v1/projects/7/forms/sample.svc/$metadata",
"value": [
{
"kind": "EntitySet",
"name": "Submissions",
"url": "Submissions"
},
{
"kind": "EntitySet",
"name": "Submissions.children.child",
"url": "Submissions.children.child"
}
]
}
object
|
HTTP Status: 200
Content Type: application/json
{
"@odata.context": "https://your.odk.server/v1/projects/7/forms/sample.svc/$metadata",
"value": [
{
"kind": "EntitySet",
"name": "Submissions",
"url": "Submissions"
},
{
"kind": "EntitySet",
"name": "Submissions.children.child",
"url": "Submissions.children.child"
}
]
}
object
|
HTTP Status: 403
Content Type: application/json; charset=utf-8; odata.metadata=minimal
{
"code": "pencil",
"message": "pencil"
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/json; charset=utf-8; odata.metadata=minimal
{
"code": "pencil",
"message": "pencil"
}
object
|
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
Metadata Document#
GET /v1/projects/{projectId}/forms/{xmlFormId}.svc/$metadata
The Metadata Document describes, in EDMX CSDL, the schema of all the data you can retrieve from the OData Form Service in question (essentially, this is the XForms form schema translated into the OData format). EDMX/CSDL is very similar in concept to UML: there are objects, they have properties, and some of those properties are relationships to other objects.
If you are writing a tool to analyze your own data, whose schema you already know and understand, there is very little reason to touch this endpoint at all. You can likely skip ahead to the data documents themselves and work directly with the simple JSON output returned by those endpoints. This endpoint is more useful for authors of tools which seek to generically work with arbitrary data whose schemas they cannot know in advance.
In general, the way we model the XForms schema in OData terms is to represent group
s as ComplexType
s, and repeat
s as EntityType
s. In the world of OData, the primary difference between these two types is that Entity Types require Primary Keys, while Complex Types do not. This fits well with the way XForms surveys tend to be structured.
Most other types map to String
. The exceptions are numbers, which map either to Int64
or Decimal
as appropriate, datetime fields which are always DateTimeOffset
, date fields which become Date
, and geography points which will appear as GeographyPoint
, GeographyLineString
, or GeographyPolygon
given a geopoint
, geotrace
, or geoshape
.
We also advertise the relationships between tables (the point at which a repeat
connects the parent data to the repeated subtable) using the NavigationProperty
. This should allow clients to present the data in an interconnected way, without the user having to specify how the tables connect to each other.
This implementation of the OData standard includes a set of Annotations describing the supported features of the service in the form of the Capabilities Vocabulary. In general, however, you can assume that the server supports the Minimal Conformance level and nothing beyond.
While the latest 4.01 OData specification adds a new JSON EDMX CSDL format, most servers and clients do not yet support that format, and so for this release of ODK Central only the older XML EDMX CSDL format is available.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
xmlFormId |
The Example: |
Response
HTTP Status: 200
Content Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="org.opendatakit.user.simple">
<EntityType Name="Submissions">
<Key><PropertyRef Name="__id"/></Key>
<Property Name="__id" Type="Edm.String"/>
<Property Name="meta" Type="org.opendatakit.user.simple.meta"/>
<Property Name="name" Type="Edm.String"/>
<Property Name="age" Type="Edm.Int64"/>
</EntityType>
<ComplexType Name="meta">
<Property Name="instanceID" Type="Edm.String"/>
</ComplexType>
<EntityContainer Name="simple">
<EntitySet Name="Submissions" EntityType="org.opendatakit.user.simple.Submissions">
<Annotation Term="Org.OData.Capabilities.V1.ConformanceLevel" EnumMember="Org.OData.Capabilities.V1.ConformanceLevelType/Minimal"/>
<Annotation Term="Org.OData.Capabilities.V1.BatchSupported" Bool="false"/>
<Annotation Term="Org.OData.Capabilities.V1.CountRestrictions">
<Record><PropertyValue Property="Countable" Bool="true"/></Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Record>
<PropertyValue Property="NonCountableProperties">
<Collection>
<String>eq</String>
</Collection>
</PropertyValue>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Record>
<PropertyValue Property="Filterable" Bool="true"/>
<PropertyValue Property="RequiresFilter" Bool="false"/>
<PropertyValue Property="NonFilterableProperties">
<Collection>
<PropertyPath>meta</PropertyPath>
<PropertyPath>name</PropertyPath>
<PropertyPath>age</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.SortRestrictions">
<Record><PropertyValue Property="Sortable" Bool="false"/></Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.ExpandRestrictions">
<Record><PropertyValue Property="Expandable" Bool="false"/></Record>
</Annotation>
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
string |
HTTP Status: 403
Content Type: application/xml
No Example
string |
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/xml
No Example
string |
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
Data Document#
GET /v1/projects/{projectId}/forms/{xmlFormId}.svc/{table}
The data documents are the straightforward JSON representation of each table of Submission
data. They follow the corresponding specification, but apart from the representation of geospatial data as GeoJSON rather than the ODK proprietary format, the output here should not be at all surprising. If you are looking for JSON output of Submission data, this is the best place to look.
The $top
and $skip
querystring parameters, specified by OData, apply limit
and offset
operations to the data, respectively. The $count
parameter, also an OData standard, will annotate the response data with the total row count, regardless of the scoping requested by $top
and $skip
. If $top
parameter is provided in the request then the response will include @odata.nextLink
that you can use as is to fetch the next set of data. While paging is possible through these parameters, it will not greatly improve the performance of exporting data. ODK Central prefers to bulk-export all of its data at once if possible.
As of ODK Central v1.1, the $filter
querystring parameter is partially supported. In OData, you can use $filter
to filter by any data field in the schema. The operators lt
, le
, eq
, ne
, ge
, gt
, not
, and
, and or
are supported. The built-in functions now
, year
, month
, day
, hour
, minute
, second
are supported. These supported elements may be combined in any way, but all other $filter
features will cause an error.
The fields you can query against are as follows:
Submission Metadata | REST API Name | OData Field Name |
---|---|---|
Submitter Actor ID | submitterId | __system/submitterId |
Submission Timestamp | createdAt | __system/submissionDate |
Submission Update Timestamp | updatedAt | __system/updatedAt |
Review State | reviewState | __system/reviewState |
You can use $root
expression to filter subtables (repeats) by Submission Metadata, you'll have to prefix above fields by $root/Submissions/
in the filter criteria. For example, to filter a repeat table by Submission Timestamp you can pass $filter=$root/Submissions/__system/submissionDate gt 2020-01-31T23:59:59.999Z
in the query parameter.
Note that the submissionDate
has a time component. This means that any comparisons you make need to account for the full time of the submission. It might seem like $filter=__system/submissionDate le 2020-01-31
would return all results on or before 31 Jan 2020, but in fact only submissions made before midnight of that day would be accepted. To include all of the month of January, you need to filter by either $filter=__system/submissionDate le 2020-01-31T23:59:59.999Z
or $filter=__system/submissionDate lt 2020-02-01
. Remember also that you can query by a specific timezone.
Please see the OData documentation on $filter
operations and functions for more information.
As of ODK Central v1.2, you can use %24expand=*
to expand all repeat repetitions. This is helpful if you'd rather get one nested JSON data payload of all hierarchical data, rather than retrieve each of repeat as a separate flat table with references.
The nonstandard $wkt
querystring parameter may be set to true
to request that geospatial data is returned as a Well-Known Text (WKT) string rather than a GeoJSON structure. This exists primarily to support Tableau, which cannot yet read GeoJSON, but you may find it useful as well depending on your mapping software. Please note that both GeoJSON and WKT follow a (lon, lat, alt)
coördinate ordering rather than the ODK-proprietary lat lon alt
. This is so that the values map neatly to (x, y, z)
. GPS accuracy information is not a part of either standards specification, and so is presently omitted from OData output entirely. GeoJSON support may come in a future version.
As of ODK Central v2022.3, the $select
query parameter is supported with some limitations:
$select
and$expand
can't be used together.Child properties of repeats can't be requested using
$select
As the vast majority of clients only support the JSON OData format, that is the only format ODK Central offers.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
xmlFormId |
The Example: |
table |
The name of the table to be returned. These names can be found in the output of the Service Document. Example: |
%24skip (query) |
If supplied, the first Example: |
%24top (query) |
If supplied, only up to Example: |
%24count (query) |
If set to Example: |
%24wkt (query) |
If set to Example: |
%24filter (query) |
If provided, will filter responses to those matching the query. Only certain fields are available to reference. The operators Example: |
%24expand (query) |
Repetitions, which should get expanded. Currently, only Example: |
%24select (query) |
If provided, will return only the selected fields. Example: |
Response
HTTP Status: 200
Content Type: application/json
{
"@odata.context": "https://your.odk.server/v1/projects/7/forms/simple.svc/$metadata#Submissions",
"value": [
{
"__id": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"age": 25,
"meta": {
"instanceID": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44"
},
"name": "Bob"
},
{
"__id": "uuid:297000fd-8eb2-4232-8863-d25f82521b87",
"age": 30,
"meta": {
"instanceID": "uuid:297000fd-8eb2-4232-8863-d25f82521b87"
},
"name": "Alice"
}
]
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
HTTP Status: 501
Content Type: application/json
{
"code": "501.1",
"message": "The requested feature $unsupported is not supported by this server."
}
object
|
Data Download Path#
GET /#/dl/projects{projectId}/forms/{xmlFormId}/submissions/{instanceId}/attachments/{filename}
(introduced: version 1.2)
This route is a web browser oriented endpoint intended for user-interactive usage only. It's not part of the Central API, but is documented here as it can be useful.
If you are writing or configuring an OData client and have submission media files to deal with, you can run into authentication problems directly fetching or linking the media file URLs that are provided in the OData feed. This can be due to several reasons: if the user is not logged into the Central administration site (and thus has no valid cookie), if the request comes from a foreign origin (and thus cookies are not sent by the browser), and more.
To help manage this, the frontend provides a /#/dl
path that allows file download. Just take a normal attachment download path and replace the /v1
near the beginning of the path with /#/dl
, and the user will be taken to a page managed by the Central administration website that will ensure the user is logged in, and offer the file as a download.
Because this /#/dl
path returns a web page that causes a file download rather than directly returning the media file in question, it cannot be used to directly embed or retrieve these files, for example in a <img>
tag.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
xmlFormId |
The Example: |
instanceId |
The Example: |
filename |
The name of the file to be retrieved. Example: |
Response
HTTP Status: 200
Content Type: text/html
(html markup data)
string |
OData Dataset Service#
ODK Central presents one OData service for every Dataset
as a way to get an OData feed of Entities
. To access the OData service, simply add .svc
to the resource URL for the given Dataset.
Service Document#
GET /v1/projects/{projectId}/datasets/{name}.svc
The Service Document provides a link to the main source of information in this OData service: the list of Entities
in this Dataset
, as well as the Metadata Document describing the schema of this information.
This document is available only in JSON format.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
The Example: |
Response
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
Metadata Document#
GET /v1/projects/{projectId}/datasets/{name}.svc/$metadata
The Metadata Document describes, in EDMX CSDL, the schema of all the data you can retrieve from the OData Dataset Service in question. Essentially, these are the Dataset properties, or the schema of each Entity
, translated into the OData format.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
Response
HTTP Status: 200
Content Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="org.opendatakit.entity">
<ComplexType Name="metadata">
<Property Name="createdAt" Type="Edm.DateTimeOffset"/>
<Property Name="creatorId" Type="Edm.String"/>
<Property Name="creatorName" Type="Edm.String"/>
<Property Name="updates" Type="Edm.Int64"/>
<Property Name="updatedAt" Type="Edm.DateTimeOffset"/>
</ComplexType>
</Schema>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="org.opendatakit.user.trees">
<EntityType Name="Entities">
<Key>
<PropertyRef Name="__id"/>
</Key>
<Property Name="__id" Type="Edm.String"/>
<Property Name="__system" Type="org.opendatakit.entity.metadata"/>
<Property Name="label" Type="Edm.String"/>
<Property Name="geometry" Type="Edm.String"/>
<Property Name="species" Type="Edm.String"/>
<Property Name="circumference_cm" Type="Edm.String"/>
</EntityType>
<EntityContainer Name="trees">
<EntitySet Name="Entities" EntityType="org.opendatakit.user.trees.Entities">
<Annotation Term="Org.OData.Capabilities.V1.ConformanceLevel" EnumMember="Org.OData.Capabilities.V1.ConformanceLevelType/Minimal"/>
<Annotation Term="Org.OData.Capabilities.V1.BatchSupported" Bool="false"/>
<Annotation Term="Org.OData.Capabilities.V1.CountRestrictions">
<Record>
<PropertyValue Property="Countable" Bool="true"/>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Record>
<PropertyValue Property="NonCountableProperties">
<Collection>
<String>eq</String>
</Collection>
</PropertyValue>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Record>
<PropertyValue Property="Filterable" Bool="true"/>
<PropertyValue Property="RequiresFilter" Bool="false"/>
<PropertyValue Property="NonFilterableProperties">
<Collection>
<PropertyPath>geometry</PropertyPath>
<PropertyPath>species</PropertyPath>
<PropertyPath>circumference_cm</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.SortRestrictions">
<Record>
<PropertyValue Property="Sortable" Bool="false"/>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.ExpandRestrictions">
<Record>
<PropertyValue Property="Expandable" Bool="false"/>
</Record>
</Annotation>
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
string |
HTTP Status: 403
Content Type: application/xml
No Example
string |
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/xml
No Example
string |
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
Data Document#
GET /v1/projects/{projectId}/datasets/{name}.svc/Entities
A data document is the straightforward JSON representation of all the Entities
in a Dataset
.
The $top
and $skip
querystring parameters, specified by OData, apply limit
and offset
operations to the data, respectively. The $count
parameter, also an OData standard, will annotate the response data with the total row count, regardless of the scoping requested by $top
and $skip
. If $top
parameter is provided in the request then the response will include @odata.nextLink
that you can use as is to fetch the next set of data.
The $filter
querystring parametercan be used to filter by any data field in the system-level schema, but not the Dataset properties. The operators lt
, le
, eq
, ne
, ge
, gt
, not
, and
, and or
are supported. The built-in functions now
, year
, month
, day
, hour
, minute
, second
are supported.
The fields you can query against are as follows:
Entity Metadata | OData Field Name |
---|---|
Entity UUID | __id |
Entity Name (same as UUID) | name |
Entity Label | label |
Entity Creator Actor ID | __system/creatorId |
Entity Timestamp | __system/createdAt |
Entity Update Timestamp | __system/updatedAt |
Note that createdAt
and updatedAt
are time components. This means that any comparisons you make need to account for the full time of the entity. It might seem like $filter=__system/createdAt le 2020-01-31
would return all results on or before 31 Jan 2020, but in fact only entities made before midnight of that day would be accepted. To include all of the month of January, you need to filter by either $filter=__system/createdAt le 2020-01-31T23:59:59.999Z
or $filter=__system/createdAt lt 2020-02-01
. Remember also that you can query by a specific timezone.
Please see the OData documentation on $filter
operations and functions for more information.
The $select
query parameter will return just the fields you specify and is supported on __id
, __system
, __system/creatorId
, __system/createdAt
and __system/updatedAt
, as well as on user defined properties.
As the vast majority of clients only support the JSON OData format, that is the only format ODK Central offers.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
name |
Name of the Dataset Example: |
%24skip (query) |
If supplied, the first Example: |
%24top (query) |
If supplied, only up to Example: |
%24count (query) |
If set to Example: |
%24filter (query) |
If provided, will filter responses to those matching the query. Only certain fields are available to reference. The operators Example: |
%24select (query) |
If provided, will return only the selected fields. Example: |
Response
HTTP Status: 200
Content Type: application/json
{
"@odata.context": "https://your.odk.server/v1/projects/7/datasets/trees.svc/$metadata#Entities",
"value": [
{
"__id": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"label": "25cm purpleheart",
"geometry": "32.7413996 -117.1394617 53.80000305175781 13.933,",
"species": "purpleheart,",
"circumference_cm": 2,
"__system": {
"createdAt": "2022-12-09T19:41:16.478Z",
"creatorId": 39,
"creatorName": "Tree surveyor",
"updates": "1,",
"updatedAt": "2023-04-31T19:41:16.478Z",
"version": 1
}
},
{
"__id": "aeebd746-3b1e-4a24-ba9d-ed6547bd5ff1",
"label": "345cm mora",
"__system": {
"createdAt": "2023-04-09T19:10:16.128Z",
"creatorId": 39,
"creatorName": "Tree surveyor",
"updates": "1,",
"updatedAt": "2023-04-31T19:41:16.478Z",
"version": 2
},
"geometry": "47.722581 18.562111 0 0,",
"species": "mora,",
"circumference_cm": 345
}
]
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
HTTP Status: 501
Content Type: application/json
{
"code": "501.1",
"message": "The requested feature $unsupported is not supported by this server."
}
object
|
Draft Testing#
(introduced: version 0.8)
To facilitate testing, there is an alternative collection of OData endpoints that will give access to the submissions uploaded to a Draft Form. This can be useful for ensuring that changes to your form do not break downstream dashboards or applications.
They are all identical to the non-Draft OData endpoints, but they will only return the Draft Form schema and Submissions.
Service Document#
GET /v1/projects/{projectId}/forms/{xmlFormId}/draft.svc
Identical to the non-Draft version of this endpoint.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
xmlFormId |
The Example: |
Response
HTTP Status: 200
Content Type: application/json; charset=utf-8; odata.metadata=minimal
{
"@odata.context": "https://your.odk.server/v1/projects/7/forms/sample.svc/$metadata",
"value": [
{
"kind": "EntitySet",
"name": "Submissions",
"url": "Submissions"
},
{
"kind": "EntitySet",
"name": "Submissions.children.child",
"url": "Submissions.children.child"
}
]
}
object
|
HTTP Status: 200
Content Type: application/json
{
"@odata.context": "https://your.odk.server/v1/projects/7/forms/sample.svc/$metadata",
"value": [
{
"kind": "EntitySet",
"name": "Submissions",
"url": "Submissions"
},
{
"kind": "EntitySet",
"name": "Submissions.children.child",
"url": "Submissions.children.child"
}
]
}
object
|
HTTP Status: 403
Content Type: application/json; charset=utf-8; odata.metadata=minimal
{
"code": "pencil",
"message": "pencil"
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/json; charset=utf-8; odata.metadata=minimal
{
"code": "pencil",
"message": "pencil"
}
object
|
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
Metadata Document#
GET /v1/projects/{projectId}/forms/{xmlFormId}/draft.svc/$metadata
Identical to the non-Draft version of this endpoint.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
xmlFormId |
The Example: |
Response
HTTP Status: 200
Content Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="org.opendatakit.user.simple">
<EntityType Name="Submissions">
<Key><PropertyRef Name="__id"/></Key>
<Property Name="__id" Type="Edm.String"/>
<Property Name="meta" Type="org.opendatakit.user.simple.meta"/>
<Property Name="name" Type="Edm.String"/>
<Property Name="age" Type="Edm.Int64"/>
</EntityType>
<ComplexType Name="meta">
<Property Name="instanceID" Type="Edm.String"/>
</ComplexType>
<EntityContainer Name="simple">
<EntitySet Name="Submissions" EntityType="org.opendatakit.user.simple.Submissions">
<Annotation Term="Org.OData.Capabilities.V1.ConformanceLevel" EnumMember="Org.OData.Capabilities.V1.ConformanceLevelType/Minimal"/>
<Annotation Term="Org.OData.Capabilities.V1.BatchSupported" Bool="false"/>
<Annotation Term="Org.OData.Capabilities.V1.CountRestrictions">
<Record><PropertyValue Property="Countable" Bool="true"/></Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Record>
<PropertyValue Property="NonCountableProperties">
<Collection>
<String>eq</String>
</Collection>
</PropertyValue>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Record>
<PropertyValue Property="Filterable" Bool="true"/>
<PropertyValue Property="RequiresFilter" Bool="false"/>
<PropertyValue Property="NonFilterableProperties">
<Collection>
<PropertyPath>meta</PropertyPath>
<PropertyPath>name</PropertyPath>
<PropertyPath>age</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.SortRestrictions">
<Record><PropertyValue Property="Sortable" Bool="false"/></Record>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.ExpandRestrictions">
<Record><PropertyValue Property="Expandable" Bool="false"/></Record>
</Annotation>
</EntitySet>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
string |
HTTP Status: 403
Content Type: application/xml
No Example
string |
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/xml
No Example
string |
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
Data Document#
GET /v1/projects/{projectId}/forms/{xmlFormId}/draft.svc/{table}
Identical to the non-Draft version of this endpoint.
Request
Parameters
projectId |
The numeric ID of the Project Example: |
xmlFormId |
The Example: |
table |
The name of the table to be returned. These names can be found in the output of the Service Document. Example: |
%24skip (query) |
If supplied, the first Example: |
%24top (query) |
If supplied, only up to Example: |
%24count (query) |
If set to Example: |
%24wkt (query) |
If set to Example: |
%24filter (query) |
If provided, will filter responses to those matching the query. Only certain fields are available to reference. The operators Example: |
%24expand (query) |
Repetitions, which should get expanded. Currently, only Example: |
%24select (query) |
If provided, will return only the selected fields. Example: |
Response
HTTP Status: 200
Content Type: application/json
{
"@odata.context": "https://your.odk.server/v1/projects/7/forms/simple.svc/$metadata#Submissions",
"value": [
{
"__id": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44",
"age": 25,
"meta": {
"instanceID": "uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44"
},
"name": "Bob"
},
{
"__id": "uuid:297000fd-8eb2-4232-8863-d25f82521b87",
"age": 30,
"meta": {
"instanceID": "uuid:297000fd-8eb2-4232-8863-d25f82521b87"
},
"name": "Alice"
}
]
}
object
|
HTTP Status: 403
Content Type: application/json
{
"code": "403.1",
"message": "The authenticated actor does not have rights to perform that action."
}
object
|
HTTP Status: 406
Content Type: application/json
{
"code": "406.1",
"message": "Requested format not acceptable; this resource allows: (application/json, json)."
}
object
|
HTTP Status: 501
Content Type: application/json
{
"code": "501.1",
"message": "The requested feature $unsupported is not supported by this server."
}
object
|