# Source at https://github.com/getodk/central-backend/blob/master/docs/api.yaml
# Copied at release time to https://github.com/getodk/docs/blob/master/docs/_static/api-spec/central.yaml
# for publishing at https://docs.getodk.org/central-api/
openapi: 3.0.1
info:
title: ODK Central API
description: |-
[ODK Central Backend](https://github.com/getodk/central-backend) is a RESTful API server that provides key functionality for creating and managing ODK data collection campaigns. It couples with [Central Frontend](https://github.com/getodk/central-frontend), an independent frontend interface, to form [ODK Central](https://github.com/getodk/central), a complete user-installable ODK server solution. While Central Frontend is the primary consumer of the ODK Central API, the API this server provides is fully public and generic: anything that can be done in the user interface can be done directly via the API.
You can read on for a brief overview of the main concepts and how they fit together, or jump to one of the sections for a more in-depth description.
## API Overview
To use the API to manage your data collection campaigns, you will need to **authenticate** with it, so it knows who you are and what you are allowed to do. We provide multiple methods to authenticate with the API, as well as different models for managing the identities and permissions in your system. Human staff users that manage data collection campaigns are `User`s, and mobile devices are granted access via `App User`s, and each of these account types have their own way of authenticating. But, these concepts both boil down to `Actor`s, which are how the API actually thinks about authentication and permissioning.
The `/users` resource can be used to create, manage, and delete **Users**. These are the staff members who have administrative rights on your server, some projects, or both. Additional tasks like resetting a user's password are also available. You could use this API to, for example, synchronize accounts with another system or mass-provision Users.
Actors (and thus Users) may be granted rights via Assignments. In short, a Roles API is available which describes the defined Roles within the system, each of which allows some set of verbs. The Assignments APIs, in turn, assign Roles to certain Actors upon certain system objects. More information on these may be found below, under [Accounts and Users](/central-api-accounts-and-users).
The rest of system is made up mostly of standard REST resources and subresources, nested under and partitioned by the `/projects` Projects resource. Forms, submissions to those forms, attachments on forms or submissions, and App Users ("App Users" in the management interface), are all subresources within `/projects`. This way, each project is essentially its own sandbox which can be managed and manipulated at will.
The `/projects/:id/app-users` subresource can be used to create, manage, and delete **App Users**.
The `/projects/:id/forms` resource and its subresource `/projects/:id/forms/…/submissions` provide full access to create, manage, and delete **`Form`s and `Submission`s to those Forms**. Each Form is a single [ODK XForms form](https://getodk.github.io/xforms-spec/), and many Submissions (filled-out forms, also sometimes called `Instance`s) may be attached to each Form. These resources are created by sending XML in the ODK XForms format instead of JSON. One can also retrieve all the multimedia attachments associated with any submission through the `/projects/:id/forms/…/submissions/…/attachments` subresource.
Forms and their submissions are also accessible through two **open standards specifications** that we follow:
* The [OpenRosa](https://docs.getodk.org/openrosa/) standard allows standard integration with tools like the [ODK Collect](https://docs.getodk.org/collect-intro/) mobile data collection app, or various other compatible tools like [Enketo](https://enketo.org/). It allows them to see the forms available on the server, and to send new submissions to them.
* The [OData](http://odata.org/) standard allows data to be shared between platforms for analysis and reporting. Tools like [Microsoft Power BI](https://powerbi.microsoft.com/en-us/) and [Tableau](https://public.tableau.com/en-us/s/) are examples of clients that consume the standard OData format and provide advanced features beyond what we offer. If you are looking for a straightforward JSON output of your data, or you are considering building a visualization or reporting tool, this is your best option.
Projects can also contain **[`Entities`](/central-api-entity-management/)**, data objects that can be created by `Submission`s and shared between `Form`s to support workflows with multiple steps. Entities are organized into named Datasets and are managed from the `/projects/:id/datasets` resource.
> ⚠️ In this API and in the related [ODK XForms specification](https://getodk.github.io/xforms-spec/entities), collections of `Entities` are referred to as `Datasets`. The term "Entity List" is used for this concept in the Central frontend UI, user documentation, and all other text intended for end users who are not developers.
Finally, **system information and configuration** is available via a set of specialized resources. Currently, you may set the Usage Reporting configuration and retrieve Server Audit Logs.
## Changelog
Here major and breaking changes to the API are listed by version.
## ODK Central v2024.1
**Added**:
- Bulk Entity Creation!
* The existing [Entity Create](/central-api-entity-management/#creating-entities) endpoint now also accepts a list of Entities to append to a Dataset.
* The `uuid` property is no longer required and Central will generate a UUID for each new Entity if needed.
- [Datasets (Entity Lists)](/central-api-dataset-management/#creating-datasets) and [Properties](/central-api-dataset-management/#adding-properties) can now be added via the API instead of only through Forms.
- OData Data Document for requests of Submissions and Entities now allow use of `$orderby`.
- ETag headers on all Blobs.
**Changed**:
- The [Entity Create](/central-api-entity-management/#creating-entities) endpoint will now generate a UUID if the `uuid` parameter is not provided.
## ODK Central v2023.5
**Added**:
- Central now supports _Entity Updates via Submissions_ as part of our continued work on Entity-Based Data Collection!
* Submissions for Entity Updates specify which properties/label to update with new values and an Entity's target `baseVersion`, which is used to track conflicts
- Entities accessed via the API have additional information about conflicts (when multiple Submissions update the same Entity)
* Each [Entity](/central-api-entity-management/#getting-entity-details) now has a `conflict` field, which is either:
* `null`. The Entity does not have conflicting versions.
* `soft`. The Entity has a version that was based on a version other than the version immediately prior to it. (The specified `baseVerson` was not the latest version on the server.)
* `hard`. The Entity has a version that was based on a version other than the version immediately prior to it. Further, that version updated the same property as another update.
* If an Entity has a conflict, it can be marked as resolved. After that, the conflict field will be null until a new conflicting version is received.
* Each Entity Version (`currentVersion` or list of versions) has new fields `baseVersion`, `dataReceived`, and `conflictingProperties`
- [Datasets](/central-api-dataset-management/#listing-datasets) extended metadata now has a `conflicts` field, which counts number of Entities currently in conflict
- Entity conflicts can be resolved using the existing [PATCH](/central-api-entity-management/#updating-an-entity) endpoint, with or without new data
- New `relevantToConflict` query parameter on [GET entities/:uuid/versions](/central-api-entity-management/#listing-versions)
**Changed**:
- Dataset entity list [entities.csv](/central-api-dataset-management/#download-dataset) can now be filtered
- Entity Update [PATCH](/central-api-entity-management/#updating-an-entity) endpoint now expects `baseVersion` query parameter or `force` flag
## ODK Central v2023.4
**Added**:
- [DELETE /sessions/current](/central-api-authentication/#logging-out-current-session) logs out the current session.
**Changed**:
- If single sign-on (SSO) with Open ID Connect (OIDC) is enabled then HTTP Basic Authentication and login with `POST /v1/session` are disabled.
- [GET /v1/projects](/central-api-project-management/#listing-projects) returns list of Datasets if `?dataset=true` parameter is provided in the request.
- Version number of the Entity is added to the response of [GET /projects/{projectId}/datasets/{name}/entities.csv](/central-api-dataset-management/#download-dataset) and [Entity OData feed](/central-api-odata-endpoints/#id3)
## ODK Central v2023.3
**Added**:
- New endpoint [PATCH /projects/:id/datasets/:name](/central-api-dataset-management/#update-dataset-metadata) to change whether approval of Submission is required to create an Entity.
- New [Entities](/central-api-entity-management) endpoints for richer Entity-Based Data Collection workflows. These endpoints provide ways of accessing Entities, as well as the ability to _create_, _update_ and _soft-delete_ Entities via the API!
* New endpoint [GET /projects/:id/datasets/:name/entities](/central-api-entity-management/#entities-metadata) for listing Entities within a Dataset.
* New endpoint [GET /projects/:id/datasets/:name/entities/:uuid](/central-api-entity-management/#getting-entity-details) for getting the metadata, or details, about a specific Entity.
* New endpoint [GET /projects/:id/datasets/:name/entities/:uuid/versions](/central-api-entity-management/#listing-versions) for listing the versions of an Entity.
* New endpoint [GET /projects/:id/datasets/:name/entities/:uuid/diffs](/central-api-entity-management/#getting-changes-between-versions) for getting the changes between versions of an Entity.
* New endpoint [GET /projects/:id/datasets/:name/entities/:uuid/audits](/central-api-entity-management/#entity-audit-log) for getting the server audit logs about a specific Entity.
* New endpoint [POST /projects/:id/datasets/:name/entities](/central-api-entity-management/#creating-entities) for creating an Entity from JSON.
* New endpoint [PATCH /projects/:id/datasets/:name/entities/:uuid](/central-api-entity-management/#updating-an-entity) for updating the data or label of an Entity.
* New endpoint [DELETE /projects/:id/datasets/:name/entities/:uuid](/central-api-entity-management/#deleting-an-entity) for soft-deleting an Entity.
**Changed**:
- ETag support has been added for [Download Dataset](/central-api-dataset-management/#download-dataset) and [Download Form Attachment](/central-api-form-management/#downloading-a-form-attachment).
- The format of [Download Dataset](/central-api-dataset-management/#download-dataset) was changed to more closely match the OData Dataset format.
- In the [OData Dataset Service](/central-api-odata-endpoints/#odata-dataset-service), `name` was removed because it is a duplication of an `__id` representing an Entity's UUID.
- The `properties` returned by the [Dataset Metadata endpoint](/central-api-dataset-management/#dataset-metadata) each now include a field `odataName`, which represents the way the property name will be sanitized and outputted for OData.
## ODK Central v2023.2
**Added**:
- New [OData Dataset Service](/central-api-odata-endpoints/#odata-dataset-service) for each `Dataset` that provides a list of `Entities`.
**Changed**:
- The response of `GET`, `POST`, `PUT` and `PATCH` methods of [Submissions](/central-api-submission-management/#listing-all-submissions-on-a-form) endpoint has been updated to include metadata of the `currentVersion` of the Submission.
## ODK Central v2023.1
**Added**:
- New endpoint [GET /projects/:id/datasets/:name](/central-api-dataset-management/#dataset-metadata) to get the metadata of a Dataset
**Changed**:
- [GET /projects/:id/datasets](/central-api-dataset-management/#listing-datasets) now supports `X-Extended-Metadata` header to retrieve number of Entities in the Dataset and timestamp of the last Entity
- `$select` in OData now supports selecting complex type(groups)
- [Creating a form](/central-api-form-management/#creating-a-new-form) can now return workflow warnings
**Removed**:
- Scheduled backups to Google Drive are no longer supported. As a result, backups are no longer configurable. It is no longer possible to get or terminate a backups configuration or to use a backups configuration to GET a Direct Backup. For more information about these changes, please see [this topic](https://forum.getodk.org/t/backups-to-google-drive-from-central-will-stop-working-after-jan-31st/38895) in the ODK Forum.
## ODK Central v2022.3
**Added**:
* Introducing [Datasets](/central-api-dataset-management) as the first step of Entity-Based Data Collection! Future versions of Central will build on these new concepts. We consider this functionality experimental and subject to change in the next release.
* Forms can now create Datasets in the project, see [Creating a New Form](/central-api-form-management/#creating-a-new-form) and the [ODK XForms specification](https://getodk.github.io/xforms-spec) for details.
* New endpoint [GET /projects/:id/datasets](/central-api-dataset-management/#listing-datasets) for listing Datasets of a project.
* New endpoint [GET /projects/:id/datasets/:name/entities.csv](/central-api-dataset-management/#download-dataset) to download the Dataset as a CSV file.
* New endpoints for [Related Datasets](/central-api-form-management/#related-datasets) to see the Datasets affected by published and unpublished Forms.
* New endpoint [PATCH .../attachments/:name](/central-api-form-management/#linking-a-dataset-to-a-draft-form-attachment) to link/unlink a Dataset to a Form Attachment.
* OData Data Document requests now allow limited use of `$select`.
**Changed**:
* The following endpoints have changed with the addition of Datasets:
* The [Extended Project](/central-api-project-management/#listing-projects) endpoint now returns the `datasets` count for the Project.
* The [Extended Form](/central-api-form-management/#list-all-forms) endpoint now returns the `entityRelated` flag if the form defines a Dataset schema.
* [DELETE .../draft/attachments/:name](/central-api-form-management/#clearing-a-draft-form-attachment) will unlink the Dataset if there's a Dataset link to the attachment.
* [GET .../draft/attachments/:filename](/central-api-form-management/#downloading-a-form-attachment) will return the Dataset as a CSV file if the attachment is linked to a Dataset.
* [GET .../draft/attachments](/central-api-form-management/#listing-expected-draft-form-attachments) returns two additional flags `blobExists` and `datasetExists`.
* In the [OpenRosa Form Manifest](/central-api-form-management/#openrosa-form-manifest-api), if a Form Attachment is linked to a Dataset then the value of `hash` is the MD5 of the last updated timestamp or the MD5 of `1970-01-01 00:00:00` if the Dataset is empty.
## ODK Central v1.5.3
**Removed**:
* It is no longer possible to initiate a new backups configuration (`POST /v1/config/backups/initiate`) or to verify one (`POST /v1/config/backups/verify`). However, for now, if there is an existing configuration, it is still possible to get it or terminate it. If the existing configuration is terminated, it will not be possible to set up a new configuration. Note that it is still possible to download a [Direct Backup](/central-api-system-endpoints/#direct-backup). For more information about this change, please see [this topic](https://forum.getodk.org/t/backups-to-google-drive-from-central-will-stop-working-after-jan-31st/38895) in the ODK Forum.
## ODK Central v1.5
ODK Central v1.5 adds editable Project descriptions as well as more detailed information about Forms and Submissions when listing Projects.
**Added**:
* New `description` field returned for each [Project](/central-api-project-management/#projects) that can be set or updated through `POST`/`PATCH`/`PUT` on `/projects/…`
* Note that for the `PUT` request, the Project's description must be included in the request. [Read more](/central-api-project-management/#deep-updating-project-and-form-details).
* [Form extended metadata](/central-api-form-management/#getting-form-details) now includes a `reviewStates` object of counts of Submissions with specific review states.
* e.g. `{"received":12, "hasIssues":2, "edited":3}`
* New `?forms=true` option on [Project Listing](/central-api-project-management/#listing-projects) that includes a `formList` field containing a list of extended Forms (and the review state counts described above) associated with that Project.
## ODK Central v1.4
ODK Central v1.4 enables additional CSV export options and creates an API-manageable 30 day permanent purge system for deleted Forms. Previously, deleted Forms were made inaccessible but the data was not purged from the database.
**Added**:
* New `?groupPaths` and `?splitSelectMultiples` options on [CSV export paths](/central-api-submission-management/#exporting-form-submissions-to-csv) which aim to replicate ODK Briefcase export behavior. One simplifies nested path names and the other breaks select multiple options out into multiple columns.
* New `?deletedFields` option on [CSV export](/central-api-submission-management/#exporting-form-submissions-to-csv) which exports all previously known and deleted fields and data on the form.
* Deleted Forms (either by API `DELETE` or through the web interface) are now placed in a 30 day hold, after which an automated process will permanently delete all data related to the Form.
* You can see Forms in the 30 day wait by [listing Forms with `?deleted=true`](/central-api-form-management/#list-all-forms). You can also see them in the Trash section on the web interface.
* `POST /projects/…/forms/…/restore` to restore a Form that hasn't yet been permanently purged.
* Additional metadata field 'formVersion' on [CSV export](/central-api-submission-management/#exporting-form-submissions-to-csv), [OData feed](/central-api-odata-endpoints/#data-document), and [extended Submission Version request](/central-api-submission-management/#listing-versions) which reports the version of the Form the Submission was _originally_ created with.
* Additional metadata fields `userAgent` and `deviceId` tracked and returned for each [Submission Version](/central-api-submission-management/#listing-versions).
* These are collected automatically upon submission through transmitted client metadata information, similar to the existing `deviceId` field returned with each Submission.
## ODK Central v1.3
ODK Central v1.3 adds granular Submission edit history, as well as opt-in usage reporting to the Central team.
**Added**:
* `GET /projects/…/forms/…/submissions/…/diffs` will return the [changes between each version](/central-api-submission-management/#getting-changes-between-versions) of a Submission.
* You can set the [Usage Reporting configuration](/central-api-system-endpoints/#usage-reporting-configuration) to choose whether the server will share anonymous usage data with the Central team. By default, no usage information will be sent at all.
* You can also [preview the Usage Report](/central-api-system-endpoints/#usage-report-preview) to see exactly what information would be sent in a Usage Report.
**Changed**:
* Additional actions are now logged in the [Server Audit Log](/central-api-system-endpoints/#server-audit-logs):
* A `user.session.create` action will be logged when a User [logs in using Session Authentication](/central-api-authentication/#logging-in).
* A `form.submissions.export` action will be logged when a User exports Form Submissions to CSV.
* The Submission update timestamp is now included in OData (as `__system/updatedAt`). Resources that accept the `$filter` query parameter can be filered on `__system/updatedAt`.
* All groups are now included in OData, even if they are not relevant. For more information, see [this post](https://forum.getodk.org/t/include-non-relevant-groups-and-fields-in-odk-central-api-responses/33536) in the ODK Forum.
* The `Content-Disposition` header now specifies the `filename*` parameter, allowing filenames to contain Unicode.
### ODK Central v1.2
ODK Central v1.2 adds submission editing, review states, and commenting.
**Added**:
* `POST /projects/…/submission` now accepts ecosystem-compatible submission updates over OpenRosa, using the `deprecatedID`.
* REST-friendly submission updates by `PUT`ing XML directly to the submission resource path.
* `GET /projects/…/forms/…/submissions/…/edit` will now redirect the authenticated user (after some thought) to an Enketo-powered webform for editing the submission.
* There is now a subresource `/projects/…/forms/…/submissions/…/versions` to get all versions of a submission, and details about each one, including submitted media files.
* There is now a subresource `/projects/…/forms/…/submissions/…/comments` which allows very simple comment creation (`POST`) and listing (`GET`) on a submission.
* Submissions now have a `reviewState` property which can be updated via `PATCH /projects/…/forms/…/submissions`.
* You can now provide `X-Action-Notes` on any API request that might generate audit logs, to leave a note on those log entries.
* `GET /projects/…/forms/…/submissions/…/audits` will return just audit logs pertaining to that submission.
* OData queries may now request `?expand=*` to request all nested data structures inline. Only `*` is accepted.
* OData `$filter` queries may now reference the new `__system/reviewState` metadata field.
* There is now a [data download path](/central-api-odata-endpoints/#data-download-path) you can direct users to which eases media file access.
* Submissions now have an `instanceName` field which reflects the `` tag on the submitted XML.
* The REST submission endpoint now accepts optional `?deviceID=` just like the OpenRosa submission endpoint.
**Changed**:
* Unpublished Forms (Forms that only have a Draft and have never been published) will now appear with full details in `GET /projects/…/forms`. Previously, values like `name` would be `null` for these Forms. You can still identify unpublished Forms as they will have a `publishedAt` value of `null`.
* Date and Boolean OData types are now given as date and boolean rather than text.
* Broke Forms and Submissions section apart into two below. This may break some links.
## ODK Central v1.1
ODK Central v1.1 adds minor new features to the API.
**Added**:
* `POST`/`GET /backup`, will immediately perform a backup of the database and return the encrypted backup.
* `POST`/`GET /projects/…/forms/…/submissions.csv`, which allows download of the root table (excluding repeat data) as CSV, without a zipfile.
* `POST`/`GET /projects/…/forms/…/submissions.csv.zip` now allows `?attachments=false` to exclude attachments.
* OData Data Document requests now allow limited use of `$filter`.
* The various `submissions.csv.*` endpoints also allow `$filter`, using the same limited OData syntax.
* `GET /projects/…/forms/…/submissions/submitters` which returns submitter Actors for a given Form.
**Fixed**:
* Documented the `deviceId` property of submission, which was added in version 0.4.
## ODK Central v1.0
ODK Central v1.0 adds Public Links to the API, and makes one minor breaking change.
**Added**:
* The new [Public Link](/central-api-form-management/#public-access-links) resource lets you create Public Access Links, granting anonymous browser-based access to submit to your Forms using Enketo.
**Changed**:
* The non-extended App User response no longer includes a `createdBy` numeric ID. To retrieve the creator of an App User, request the extended response.
* We no longer reject the request if multiple authentication schemes are presented, and instead document the priority order of the different schemes [here](/central-api-authentication).
## ODK Central v0.9
ODK Central v0.9 does not change the API except for one minor breaking change.
**Changed**:
* The [OpenRosa Form Listing API](/central-api-openrosa-endpoints/#openrosa-form-listing-api) has been modified to always require authentication. If a valid Actor is authenticated at all, a form list will always be returned, filtered by what that Actor is allowed to access.
## ODK Central v0.8
ODK Central v0.8 introduces Draft Forms, publishing, and archived Form versions, which has a significant breaking impact on the existing API. The changes should be straightforward to adapt to, however. If you are currently creating Forms with `POST /projects/…/forms`, you may wish to add `?publish=true` to skip the Draft state and mimic the old behaviour. If you are using the API to push Form Attachments onto Forms, you'll only be able to do so now in draft state, at `/projects/…/forms/…/draft/attachments`.
**Added**:
* Draft Forms and publishing, and archived Form versions.
* This includes [a subresource](/central-api-form-management/#draft-form) at `/projects/…/forms/…/draft`,
* and [another](/central-api-form-management/#published-form-versions) at `/projects/…/forms/…/versions`,
* and a [new collection of OpenRosa endpoints](/central-api-openrosa-endpoints/#draft-testing-endpoints), under `/test/…/projects/…/forms/…/draft`, for submitting test submissions to the draft version of the form.
* `GET /projects/…/forms/…/fields`, which replaces `GET /projects/…/forms/….schema.json`.
* App User responses now include the `projectId` they are bound to.
**Changed**:
* As part of the Draft Forms change, the read/write endpoints for Form Attachments have been moved to the Draft Form state and subresource, at `/projects/…/forms/…/draft/attachments`.
**Removed**:
* `GET /projects/…/forms/….schema.json` has been removed in favor of `GET /projects/…/forms/…/fields`.
**Fixed**:
* Documented `GET /projects/…/forms/….xls(x)`, which was added in 0.7.
## ODK Central v0.7
**Added**:
* Form-specific [Assignments resource](/central-api-form-management/#form-assignments) at `projects/…/forms/…/assignments`, allowing granular role assignments on a per-Form basis.
* Relatedly, the [OpenRosa Form Listing API](/central-api-openrosa-endpoints/#openrosa-form-listing-api) no longer rejects requests outright based on authentication. Rather, it will only return Forms that the authenticated user is allowed to view.
* A [new summary API](/central-api-project-management/#seeing-all-form-assignments-within-a-project) `GET /projects/…/assignments/forms` which returns all assignments on all Forms within a Project, so you don't have to request this information separately for each Form.
* `PUT /projects/:id`, which while complex allows you to update many Forms' states and assignments with a single transactional request.
* `POST /projects/…/forms` now allows upload of `.xls` and `.xlsx` XLSForm files. The correct MIME type must be given.
* `GET /users/?q` will now always return user details given an exact match for an email, even for users who cannot `user.list`. The request must still be authenticate as a valid Actor. This allows non-Administrators to choose a user for an action (eg grant rights) without allowing full search.
**Changed**:
* Newly created App Users are no longer automatically granted download and submission access to all Forms within their Project. You will want to use the [Form Assignments resource](/central-api-form-management/#form-assignments) to explicitly grant `app-user` role access to the Forms they should be allowed to see.
**Fixed**:
* Correctly documented `keyId` property on Projects.
## ODK Central v0.6
**Added**:
* `GET /audits` Server Audit Log retrieval resource.
* Project Managed Encryption:
* `POST /projects/…/key` to enable project managed encryption.
* Both submission intake methods (OpenRosa and REST) now support encrypted submissions.
* `GET /projects/…/forms/…/submissions/keys` to get a list of encryption keys needed to decrypt all submitted data.
* `?{keyId}={passphrase}` option on `GET /projects/…/forms/…/submissions.csv.zip` to get a decrypted archive given the `passphrase`.
* `POST /projects/…/forms/…/submissions.csv.zip` to provide a browser-secure (no querystring) method of accessing the above `GET .csv.zip` resource.
* OData and `.csv.zip` data responses now contain an additional `status` system column.
* Form resource data now includes `projectId` and 'keyId'.
* `?odata=true` option on `GET /projects/…/forms/….schema.json` to sanitize the field names to match the way they will be outputted for OData.
**Changed**:
* `GET /projects/…/forms/…/attachments` now always returns `updatedAt`. There is no longer a separate Extended Metadata response for this resource.
* The Submission response format now provides the submitter ID at `submitterId` rather than `submitter`. This is so that the Extended responses for Submissions can use `submitter` to provide the full Actor subobject rather than replacing it. This brings the response format to be more similar to the other Extended formats.
* OData resources now namespace the `__system` schema information under `org.opendatakit.submission` rather than alongside user metadata (`org.opendatakit.user.*`). The actual returned data has not changed; this is purely a metadata document change.
**Removed**:
* The Extended responses for Forms and Submissions no longer include an `xml` property. To retrieve Form or Submission XML, use the dedicated endpoints for [Form XML](/central-api-form-management/#retrieving-form-xml) and [Submission XML](/central-api-submission-management/#retrieving-submission-xml).
## ODK Central v0.5
**Added**:
* Roles and Assignments resources at `/roles`, `/assignments`, and `/projects/…/assignments`.
* Optional `?q=` querystring parameter on Users `GET` listing, for searching users.
* Extended `GET /users/current`: added `verbs` list of verbs the authenticated Actor may perform server-wide.
* Extended Project `GET`: added `appUsers` count of App Users and `verbs` list of verbs the authenticated Actor may perform upon/within the Project.
* User `DELETE`.
* Projects now have an `archived` flag which may be set to clear a Project out of the way without deleting it.
**Changed**:
* **Removed** autopromotion of Users to Administrator upon creation (`POST`). Roles must be assigned separately and explicitly.
* **Changed** Project Listing (`GET /projects`) to never reject based on authentication; instead it filters the response based on the access of the authenticated Actor.
* **Changed** `xmlFormId`/`version` conflict errors on `POST`ing a new Form from a `400` code to a `409` code.
* **Changed** all remaining textual references to "Field Keys" to "App Users" in the documentation.
**Fixed**:
* Corrected Actor documentation to match reality: **removed** `meta` field and added `type` field.
* Corrected Extended Form documentation: **added** `createdBy` field.
* Corrected Backup Config documentation. It was almost entirely wrong.
* Added Submission POST REST documentation.
## ODK Central v0.4
**Added**:
* Projects resource at `/projects`.
* Submission XML resource fetch at `GET /projects/…/forms/…/submissions/….xml`.
* Submission attachment management over REST, at the `/attachments` subresource within Submissions.
**Changed**:
* **Renamed** all `/field-keys` routes to `/app-users`.
* **Moved** all Forms, Submissions, and App User resources under Projects (e.g. `/forms/simple` would now be something like `/projects/1/forms/simple`).
* **Changed** `GET` Form to not return Form XML. The Extended Metadata version of those requests will give the XML.
* **Changed** both OpenRosa and REST Submission creation processes to create and accept only the attachment filenames that are indicated to exist by the Submission XML.
* **Changed** `GET` Submission Attachemnts listing to return an array of objects containing attachment details rather than an array of filename strings.
version: ""
servers:
- url: /
tags:
- name: Authentication
description: |-
In ODK Central, the server thinks about identity and permissioning in terms of one core concept: the `Actor`. No matter how you authenticate with the API, you are doing so as an Actor of some kind or another, and when permissions are assigned and checked, they are done against the authenticated Actor.
In practice, there are two types of Actors available in the system today:
* `User`s are accounts used by the staff members who manage the server and the data collection campaigns. They each have a set of rights assigned to them via Roles and Assignments. They are the only account types that have passwords associated with them. They also always have an email address. Users can authenticate using **Session Bearer Tokens** or using **HTTPS Basic** authentication.
* `App User`s are only allowed to access the OpenRosa parts of the API: in essence, they are allowed to list forms, download form definitions, and create new submissions against those forms. They can only authenticate using **App User URL**s.
Next, you will find documentation on each of the three authentication methods described above. It is best not to present multiple credentials. If you do, the first _presented_ scheme out of `/key` token, Bearer, Basic, then Cookie will be used for the request. If the multiple schemes are sent at once, and the first matching scheme fails, the request will be immediately rejected.
**Note:** If Single Sign-on with Open ID Connect is enabled on the ODK Central, you can neither use HTTP Basic Authentication nor login with `POST /v1/session` endpoint.
- name: Accounts and Users
description: |-
Today, there are two types of accounts: `Users`, which are the administrative accounts held by staff members managing the data collection process, and `App Users`, which are restricted access keys granted per Form within a Project to data collection clients in the field. Although both of these entities are backed by `Actor`s as we explain in the [Authentication section](/central-api-authentication) above, there is not yet any way to directly create or manipulate an Actor. Today, you can only create, manage, and delete Users and App Users.
Actors (and thus Users) may be granted rights via Roles. The `/roles` Roles API is open for all to access, which describes all defined roles on the server. Getting information for an individual role from that same API will reveal which verbs are associated with each role: some role might allow only `submission.create` and `submission.update`, for example.
Right now, there are four predefined system roles: Administrator (`admin`), Project Manager (`manager`), Data Collector (`formfill`), and App User (`app-user`). Administrators are allowed to perform any action upon the server, while Project Managers are allowed to perform any action upon the projects they are assigned to manage.
Data Collectors can see all Forms in a Project and submit to them, but cannot see Submissions and cannot edit Form settings. Similarly, App Users are granted minimal rights: they can read Form data and create new Submissions on those Forms. While Data Collectors can perform these actions directly on the Central administration website by logging in, App Users can only do these things through Collect or a similar data collection client device.
The Roles API alone does not, however, tell you which Actors have been assigned with Roles upon which system objects. For that, you will need to consult the various Assignments resources. There are two, one under the API root (`/v1/assignments`), which manages assignments to the entire system, and another nested under each Project (`/v1/projects/…/assignments`) which manage assignments to that Project.
- name: Project Management
description: Apart from staff users ("Web Users" in the Central management interface)
and some site-wide configuration details like Usage Reporting, all of ODK Central's
objects (Forms, Submissions, App Users) are partitioned by Project, and available
only as subresources below the main Projects resource.
- name: Form Management
description: |-
`Form`s are the heart of ODK. They are created out of XML documents in the [ODK XForms](https://getodk.github.io/xforms-spec/) specification format. The [Intro to Forms](https://docs.getodk.org/form-design-intro/) on the ODK Documentation website is a good resource if you are unsure what this means. Once created, Forms can be retrieved in a variety of ways, their state can be managed, and they can be deleted.
These subsections cover only the modern RESTful API resources involving Forms. For documentation on the OpenRosa `formList` endpoint (which can be used to list Forms), see that section below.
- name: Submission Management
description: |-
`Submission`s are filled-out forms (also called `Instance`s in some other ODK documentation). Each is associated with a particular Form (and in many cases with a particular _version_ of a Form), and is also created out of a standard XML format based on the Form itself. Submissions can be sent with many accompanying multimedia attachments, such as photos taken in the course of the survey. Once created, the Submissions themselves as well as their attachments can be retrieved through this API.
These subsections cover only the modern RESTful API resources involving Submissions. For documentation on the OpenRosa submission endpoint (which can be used to submit Submissions), or the OData endpoint (which can be used to retrieve and query submission data), see those sections below.
> Like Forms, Submissions can have versions. Each Form has an overall `xmlFormId` that represents the Form as a whole, and each version has a `version` that identifies that particular version. Often, when fetching data by the `xmlFormId` alone, information from the latest Form version is included in the response.
> Similarly with Submissions, the `instanceId` each Submission is first submitted with will always represent that Submission as a whole. Each version of the Submission, though, has its own `instanceId`. Sometimes, but not very often, when getting information about the Submission by only its overall `instanceId`, information from the latest Submission version is included in the response.
- name: Dataset Management
description: |-
_(introduced: version 2022.3)_
> ⚠️ In this API and in the related [ODK XForms specification](https://getodk.github.io/xforms-spec/entities), collections of `Entities` are referred to as `Datasets`. The term "Entity List" is used for this concept in the Central frontend UI, user documentation, and all other text intended for end users who are not developers.
A Dataset is a named collection of [Entities](/central-api-entity-management/) that have the same properties.
A Dataset can be linked to Forms as Attachments. This will make it available to clients as an automatically-updating CSV.
**Related APIs:**
- [Implicit creation of Datasets via Forms](/central-api-form-management/#creating-a-new-form)
- [Link a Dataset to a Form Attachment](/central-api-form-management/#linking-a-dataset-to-a-draft-form-attachment)
- [Get a Form's Related Datasets](/central-api-form-management/#related-datasets)
- name: Entity Management
description: |-
_(introduced: version 2023.3)_
> ⚠️ In this API and in the related [ODK XForms specification](https://getodk.github.io/xforms-spec/entities), collections of `Entities` are referred to as `Datasets`. The term "Entity List" is used for this concept in the Central frontend UI, user facing documentation, and all other text intended for end users who are not developers.
Entities are data objects that can be shared between Forms to support workflows with multiple steps. They can be created either through form design or through this API. A collection of `Entities` is a [Dataset](/central-api-dataset-management/).
- name: OpenRosa Endpoints
description: |-
[OpenRosa](https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaAPI) is an API standard which accompanies the ODK XForms XML standard, allowing compliant servers and clients to use a common protocol to communicate `Form`s and `Submission`s to each other. When survey clients like ODK Collect and Enketo submit Submission data to a Form, this is the API they use.
ODK Central is _not_ a fully compliant OpenRosa server. OpenRosa requires compliance with five major components:
1. [**Metadata Schema**](https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaMetaDataSchema), which defines a standard way to include metadata like the survey device ID and survey duration with a Submission. ODK Central will accept and return this data, but does nothing special with anything besides the `instanceId` at this time.
2. [**HTTP Request API**](https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaRequest), which defines a set of requirements every OpenRosa request and response must follow. ODK Central is fully compliant with this component, except that we do _not_ require the `Date` header.
3. [**Form Submission API**](https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI), which defines how Submissions are submitted to the server. ODK Central is fully compliant with this component.
4. [**Authentication API**](https://bitbucket.org/javarosa/javarosa/wiki/AuthenticationAPI), which defines how users authenticate with the server. ODK Central provides [three authentication methods](/central-api-authentication). One of these is HTTPS Basic Authentication, which is recommended by the OpenRosa specification. However, because [we do not follow the try/retry pattern](/central-api-authentication/#using-basic-authentication) required by the OpenRosa and the RFC specification, ODK Central is _not compliant_ with this component. Our recommendation generally is to use [App User Authentication](/central-api-authentication/#app-user-authentication) when submitting data from survey clients.
5. [**Form Discovery (Listing) API**](https://bitbucket.org/javarosa/javarosa/wiki/FormListAPI), which returns a listing of Forms available for survey clients to download and submit to. At this time, ODK Central is _partially compliant_ with this component: the server will return a correctly formatted `formList` response, but it does not currently handle the optional filter parameters.
In practical usage, ODK survey clients like Collect will interact with Central in three places:
* The OpenRosa Form Listing API, [documented below](/central-api-openrosa-endpoints/#openrosa-form-listing-api), lists the Forms the client can retrieve.
* The [Form XML download](/central-api-form-management/#retrieving-form-xml) endpoint, a part of the standard REST API for Forms, is linked in the Form Listing response and allows clients to then download the ODK XForms XML for each form.
* The OpenRosa Submission API, [documented below](/central-api-openrosa-endpoints/#openrosa-form-submission-api), allows survey clients to submit new Submissions to any Form.
The Form Listing and Submission APIs are partitioned by Project, and their URLs are nested under the Project in question as a result. When you List or Submit, you will only be able to get forms from and submit submissions to that particular Project at a time.
Where the **HTTP Request API** OpenRosa standards specification requires two headers for any request, Central requires only one:
* `X-OpenRosa-Version` **must** be set to exactly `1.0` or the request will be rejected.
* But Central does not require a `Date` header field. You may set it if you wish, but it will have no effect on Central.
- name: OData Endpoints
description: |-
[OData](http://www.odata.org/) is a standard for sharing data and its schema between web services. It allows for interoperability with tools like Excel, Power BI or Tableau. If you want to use your data in a service that does not support the OData standard but does support JSON data sources, you can use the [data document](/central-api-odata-endpoints/#data-document) directly.
ODK Central implements the [4.0 Minimal Conformance level](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#_Toc505771292) 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. Our implementation primarily targets [Microsoft Power BI](https://docs.microsoft.com/en-us/power-bi/desktop-connect-odata) and [Tableau](https://onlinehelp.tableau.com/current/pro/desktop/en-us/examples_odata.html), 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. Our current solution for representing ODK's `repeat` structures in OData is to treat every `repeat` in the `Form` definition as its own relational table, and we compute 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 every `Dataset`.
* The **Metadata Document** defines the data schema using [an XML-based standard](https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#sec_Introduction). It is linked in every OData response.
* The **data documents**, linked from the Service Document, are a simple JSON representation of the Submission or Entity data, conforming to the schema we describe in our Metadata Document.
- name: System Endpoints
description: There are some resources available for getting or setting system information
and configuration. You can set the [Usage Reporting configuration](/central-api-system-endpoints/#usage-reporting-configuration)
for the server, retrieve the [Server Audit Logs](/central-api-system-endpoints/#server-audit-logs),
or perform a [Direct Backup](/central-api-system-endpoints/#direct-backup).
- name: Encryption
description: |-
ODK Central supports two types of encryption:
1. The [old methodology](https://docs.getodk.org/encrypted-forms/), where you generate an RSA keypair and use it with locally-downloaded encrypted data to decrypt submissions. We refer to these sorts of keys in this documentation as "self-supplied keys."
2. Managed Encryption, where Central will generate and store an RSA keypair for you, secured under a passphrase that Central does not save. The CSV export path can then decrypt all records on the fly given the passphrase.
Given the self-supplied key case, Central does not understand how to decrypt records, and the CSV export will export only metadata fields (and no binary attachments) for encrypted records. You may retrieve each data resource over the REST API and decrypt them yourself, or use ODK Briefcase to do this.
Managed Encryption is recommended for most people. The data is still encrypted "at rest" on the server, and the private key needed to decrypt the data is itself encrypted by the passphrase. Neither the passphrase nor the decrypted private key are ever stored; they are forgotten as soon as the server has finished the work at hand.
The relevant API operations are documented inline above; here we guide you through what exists from a high level.
To invoke Project Manage Encryption, you may use the web management interface, or you may [POST /projects/…/key](/central-api-project-management/#enabling-project-managed-encryption).
To list all the encryption keys associated with the submissions on a given form, you can [GET /projects/…/forms/…/submissions/keys](/central-api-submission-management/#listing-encryption-keys). This is particularly useful for obtaining the integer numeric ID associated with each key, which will be necessary to decrypt the records, as well as for obtaining reminder hints about each passphrase.
To perform decryption, you can [GET or POST /projects/…/forms/…/submissions.csv.zip](/central-api-submission-management/#exporting-form-submissions-to-csv) with extra parameters to provide the necessary passphrases. If you are building a browser-based application, it is recommended that you `POST` rather than `GET`: please see the notes in the linked sections for additional details.
Note that the OData JSON API does not (presently) decrypt data. Any encrypted submissions will be returned only with basic metadata, like submission date and user.
- name: Session Authentication
x-parent-tag: Authentication
description: |-
This is the authentication method used by the ODK Central Frontend packaged with Central Backend. Only `User`s can authenticate this way. It consists mostly of two steps:
1. **Logging in**: presenting an Email Address and a Password for verification, after which a new `Session` is created. Associated with the Session is an expiration and a bearer token. Sessions expire 24 hours after they are created.
2. **Using the session**: each request to the API needs a header attached to it: `Authorization: Bearer {token}`. This authenticates that particular request as belonging to the Session we created by logging in.
You might notice that Step 2 greatly resembles how OAuth 2.0 works. This was an intentional first step towards OAuth support, and should make the forward migration of your code easier down the road.
- name: HTTPS Basic Authentication
x-parent-tag: Authentication
description: |-
Standard HTTP Basic Authentication is allowed, but **strongly discouraged**. This is because the server must verify your password with every single request, which is very slow to compute: typically, this will add hundreds of milliseconds to each request. For some one-off tasks and in cases where there is no other choice, it is reasonable to choose Basic authentication, but wherever possible we strongly encourage the use of any other authentication method.
In addition, because credentials are sent in plaintext as part of the request, **the server will only accept Basic auth over HTTPS**. If your ODK Central server is set up over plain HTTP, it will not accept Basic auth.
- name: App User Authentication
x-parent-tag: Authentication
description: |-
App Users are only allowed to list and download forms, and upload new submissions to those forms. Primarily, this is to allow clients like ODK Collect to use the OpenRosa API (`/formList` and `/submission`), but any action in this API reference falling into those categories will be allowed.
Revoking an App User is same as deleting session token. You can do this by calling [DELETE /sessions/{appUser}](/central-api-authentication/#logging-out-current-session).
- name: Users
x-parent-tag: Accounts and Users
description: |-
Presently, it is possible to create and list `User`s in the system, as well as to perform password reset operations. In future versions of this API it will be possible to manage existing user information and delete accounts as well.
- name: App Users
x-parent-tag: Accounts and Users
description: |-
App Users may only be created, fetched, and manipulated within the nested Projects subresource, as App Users themselves are limited to the Project in which they are created. Through the `App User`s API, you can create, list, and delete the App Users of any given Project. Because they have extremely limited permissions, App Users cannot manage themselves; only `User`s may access this API.
For more information about the `/projects` containing resource, please see the following section.
- name: Roles
x-parent-tag: Accounts and Users
description: |-
_(introduced: version 0.5)_
The Roles API lists and describes each known Role within the system. Right now, Roles may not be created or customized via the API, but this will likely change in the future.
Each Role contains information about the verbs it allows its assignees to perform. Some Roles have a system name associated with them; the Roles may always be referenced by this system name in request URLs, and system Roles are always read-only.
- name: Assignments
x-parent-tag: Accounts and Users
description: |-
_(introduced: version 0.5)_
There are multiple Assignments resources. This one, upon the API root (`/v1/assignments`), manages Role assignment to the entire system (e.g. if you are assigned a Role that gives you `form.create`, you may create a form anywhere on the entire server).
The [Project Assignments resource](/central-api-project-management/#project-assignments), nested under Projects, manages Role assignment to that Project in particular, and all objects within it. And the [Form Assignments resource](/central-api-form-management/#form-assignments) allows even more granular assignments, to specific Forms within a Project. All of these resources have the same structure and take and return the same data types.
Assignments may be created (`POST`) and deleted (`DELETE`) like any other resource in the system. Here, creating an Assignment grants the referenced Actor the verbs associated with the referenced Role upon all system objects. The pathing for creation and deletion is not quite REST-standard: we represent the relationship between Role and Actor directly in the URL rather than as body data: `assignments/{role}/{actor}` represents the assignment of the given Role to the given Actor.
- name: Projects
x-parent-tag: Project Management
description: |-
_(introduced: version 0.4)_
You must create a containing Project before you can create any of its subobjects.
- name: Project Assignments
x-parent-tag: Project Management
description: |-
_(introduced: version 0.5)_
There are multiple Assignments resources. This one, specific to the Project it is nested within, only governs Role assignments to that Project. Assigning an Actor a Role that grants, for example, a verb `submission.create`, allows that Actor to create a submission anywhere within this Project. It is also possible to assign rights only to specific forms for actions related only to that form and its submissions: see the [Form Assignments resource](/central-api-form-management/#form-assignments) for information about this.
The [sitewide Assignments resource](/central-api-accounts-and-users/#assignments), at the API root, manages Role assignments for all objects across the server. Apart from this difference in scope, the introduction to that section contains information useful for understanding the following endpoints.
There are only one set of Roles, applicable to either scenario. There are not a separate set of Roles used only upon Projects or Forms.
- name: Forms
x-parent-tag: Form Management
description: |-
In this API, `Form`s are distinguished by their [`formId`](https://getodk.github.io/xforms-spec/#primary-instance)s, which are a part of the XForms XML that defines each Form. In fact, as you will see below, many of the properties of a Form are extracted automatically from the XML: `hash`, `name`, `version`, as well as the `formId` itself (which to reduce confusion internally is known as `xmlFormId` in ODK Central).
The only other property Forms currently have is `state`, which can be used to control whether Forms show up in mobile clients like ODK Collect for download, as well as whether they accept new `Submission`s or not.
It is not yet possible to modify a Form's XML definition once it is created.
- name: Individual Form
x-parent-tag: Form Management
- name: Draft Form
x-parent-tag: Form Management
description: |-
_(introduced: version 0.8)_
Draft Forms allow you to test and fix issues with Forms before they are finalized and presented to data collectors. They make this process easier, as Draft Forms can be created and discarded without consequence: your Drafts will not count against the overall Form schema, nor against the set of unique `version` strings for the Form.
You can create or replace the current Draft Form at any time by `POST`ing to the `/draft` subresource on the Form, and you can publish the current Draft by `POST`ing to `/draft/publish`.
When a Draft Form is created, a Draft Token is also created for it, which can be found in Draft Form responses at `draftToken`. This token allows you to [submit test Submissions to the Draft Form](/central-api-submission-management/#creating-a-submission) through clients like Collect. If the Draft is published or deleted, the token will be deactivated. But if you replace the Draft without first deleting it, the existing Draft Token will be carried forward, so that you do not have to reconfigure your device.
- name: Published Form Versions
x-parent-tag: Form Management
description: |-
All published versions of a Form are available read-only at the `/versions` subresource for reference, including the currently published version. You may read that version and its details, retrieve the Form definition, and any attachments associated with each version.
- name: Form Assignments
x-parent-tag: Form Management
description: |-
_(introduced: version 0.7)_
There are multiple Assignments resources. This one, specific to the Form it is nested within, only governs Role assignments to that Form. Assigning an Actor a Role that grants, for example, a verb `submission.create`, allows that Actor to create a submission to this Form alone. It is also possible to assign umbrella rights to a whole Project and therefore all Forms within it: see the [Project Assignments resource](/central-api-project-management/#project-assignments) for information about this.
The [sitewide Assignments resource](/central-api-accounts-and-users/#assignments), at the API root, manages Role assignments for all objects across the server. Apart from this difference in scope, the introduction to that section contains information useful for understanding the following endpoints.
There are only one set of Roles, applicable to either scenario. There are not a separate set of Roles used only upon Projects or Forms.
- name: Public Access Links
x-parent-tag: Form Management
description: |-
_(introduced: version 1.0)_
Anybody in possession of a Public Access Link for a Form can use that link to submit data to that Form. Public Links are useful for collecting direct responses from a broad set of respondents, and can be revoked using the administration website or the API at any time.
The API for Public Links is particularly useful, as it can be used to, for example, programmatically create and send individually customized and controlled links for direct distribution. The user-facing link for a Public Link has the following structure: `/-/{enketoId}?st={token}` where `-` is the Enketo root, `enketoId` is the survey ID of this published Form on Enketo and `token` is a session token to identify this Public Link.
To revoke the access of any Link, terminate its session `token` by issuing [`DELETE /sessions/:token`](/central-api-authentication/#logging-out-current-session).
- name: Related Datasets
x-parent-tag: Form Management
description: |-
_(introduced: version 2022.3)_
Datasets are created and updated through Forms. Dataset-related Forms follow [the entities sub-spec](https://getodk.github.io/xforms-spec/entities) of the ODK XForms specification that allow them to define a Dataset and a mapping of Form Fields to Dataset Properties. Submissions from such a Form can create Entities within the Dataset defined in the Form.
Currently, Datasets and Dataset Properties are purely additive. Multiple Forms can add Properties to the same Dataset and multiple Forms can create Entities in the same Dataset. Not all Properties of a Dataset have to be included in a Form for that Dataset. For example, one Form publishing to a Dataset called `trees` could add `location` and `species`, while another could add `species` and `circumference`. The Properties of the Dataset would be the union of Properties from all Forms for that Dataset (`location`, `species`, `circumference`). Note that it is not necessary that a Form will save to all Properties of a Dataset, so the endpoint also returns a `inForm` flag for each property which is true only if the Form affects that Property.
The following endpoints return the Dataset(s) that Submissions of that Form will populate. They also return all of the Entity Properties for each Dataset and indicate which ones are mapped to Fields in the specified Form.
- name: Submissions
x-parent-tag: Submission Management
description: |-
`Submission`s are available as a subresource under `Form`s. So, for instance, `/v1/projects/1/forms/myForm/submissions` refers only to the Submissions that have been submitted to the Form `myForm`.
Once created (which, like with Forms, is done by way of their XML data rather than a JSON description), it is possible to retrieve and export Submissions in a number of ways, as well as to access the multimedia `Attachment`s associated with each Submission.
- name: Comments
x-parent-tag: Submission Management
description: |-
_(introduced: version 1.2)_
This API is likely to change in the future. In version 1.2 we have added comments to submissions, so changes and problems with the data can be discussed. It's very likely we will want comments in more places in the future, and at that time a more complete comments API will be introduced, and this current one may be changed or deprecated entirely.
Currently, it is not possible to get a specific comment's details, or to edit or delete a comment once it has been made.
- name: Attachments
x-parent-tag: Submission Management
description: |-
When a `Submission` is created, either over the OpenRosa or the REST interface, its XML data is analyzed to determine which file attachments it references: these may be photos or video taken as part of the survey, or an audit/timing log, among other things. Each reference is an expected attachment, and these expectations are recorded permanently alongside the Submission.
With this subresource, you can list the expected attachments, see whether the server actually has a copy or not, and download, upload, re-upload, or clear binary data for any particular attachment.
- name: Submission Versions
x-parent-tag: Submission Management
description: |-
_(introduced: version 1.2)_
The `instanceId` that is submitted with the initial version of the submission is used permanently to reference that submission logically, which is to say the initial submission and all its subsequent versions. Each subsequent version will also provide its own `instanceId`. This `instanceId` becomes that particular version's identifier.
So if you submit a submission with `one` and then update it, deprecating `one` for version `two`, then the full route for version `one` is `/v1/projects/…/forms/…/submissions/one/versions/one`, and for `two` it is `/v1/projects/…/forms/…/submissions/one/versions/two`.
As of version 1.4, a `deviceId` and `userAgent` will also be returned with each submission. For each submission of a version, the submitting client device may transmit these extra metadata. If it does, those fields will be recognized and returned here for reference.
- name: Draft Submissions
x-parent-tag: Submission Management
description: |-
All [Draft Forms](/central-api-form-management/#draft-form) feature a `/submissions` subresource (`/draft/submissions`), which is identical to the same subresource on the form itself. These submissions exist only as long as the Draft Form does: they are removed if the Draft Form is published, and they are abandoned if the Draft Form is deleted or overwritten.
Here we list all those resources again just for completeness.
- name: Draft Testing Endpoints
x-parent-tag: OpenRosa Endpoints
description: |-
_(introduced: version 0.8)_
To facilitate testing, there is an alternative collection of OpenRosa endpoints that will give access to the draft version of a form and allow submitting test submissions to it. If you are using User or App User authentication, you can use the following resources without the `/test/{token}` prefix with your existing authentication.
Otherwise, and in particular if you plan to test your form in Collect or another OpenRosa-compliant client, you will likely want to use the `/test` Draft Token prefix. It functions similarly to the standard OpenRosa support, with App User authentication, but instead of a `/key` route prefix they feature a `/test` route prefix, and they point directly at each form (example: `/test/lSpA…EjR7/projects/1/forms/myform/draft`).
You can get the appropriate Draft Token for any given draft by [requesting the Draft Form](/central-api-form-management/#getting-draft-form-details).
The `/test` tokens are not actual App Users, and Central does not keep track of user identity when they are used.
With the `/test` prefix, the following resources are available:
- name: OData Form Service
x-parent-tag: OData Endpoints
description: |-
ODK Central presents one OData service for every `Form` it knows about. To access the OData service, add `.svc` to the resource URL for the given Form.
- name: OData Dataset Service
x-parent-tag: OData Endpoints
description: |-
ODK Central presents one OData service for every `Dataset` as a way to get an OData feed of `Entities`. To access the OData service, add `.svc` to the resource URL for the given Dataset.
- name: Draft Testing
x-parent-tag: OData Endpoints
description: |-
_(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.
- name: Usage Reporting Configuration
x-parent-tag: System Endpoints
description: |-
_(introduced: version 1.3)_
- name: Usage Report Preview
x-parent-tag: System Endpoints
description: |-
_(introduced: version 1.3)_
An Administrator of Central may opt in to sending periodic reports summarizing usage. Configuration of this reporting is described [here](/central-api-system-endpoints/#usage-reporting-configuration). For added transparency, the API provides a preview of the reported metrics.
- name: Server Audit Logs
x-parent-tag: System Endpoints
description: |-
_(introduced: version 0.6)_
Many actions on ODK Central will automatically log an event to the Server Audit Log. Creating a new Form, for instance, will log a `form.create` event, with information about the Actor who performed the action, and sometimes some additional details specific to the event.
Any time an audit action is logged, the request headers are checked. If `X-Action-Notes` are provided anywhere, those notes will be logged into the audit entries as well. Note that some requests generate multiple audit entries; in these cases, the `note` will be attached to every entry logged.
Server Audit Logs entries are created for the following `action`s:
* `user.create` when a new User is created.
* `user.update` when User information is updated, like email or password.
* `user.assignment.create` when a User is assigned to a Server Role.
* `user.assignment.delete` when a User is unassigned from a Server Role.
* `user.session.create` when a User logs in.
* `user.delete` when a User is deleted.
* `project.create` when a new Project is created.
* `project.update` when top-level Project information is updated, like its name.
* `project.delete` when a Project is deleted.
* `form.create` when a new Form is created.
* `form.update` when top-level Form information is updated, like its name or state.
* `form.update.draft.set` when a Draft Form definition is set.
* `form.update.draft.delete` when a Draft Form definition is deleted.
* `form.update.publish` when a Draft Form is published to the Form.
* `form.attachment.update` when a Form Attachment binary is set or cleared.
* `form.submissions.export` when a Form's Submissions are exported to CSV.
* `form.delete` when a Form is deleted.
* `form.restore` when a Form that was deleted is restored.
* `form.purge` when a Form is permanently purged.
* `field_key.create` when a new App User is created.
* `field_key.assignment.create` when an App User is assigned to a Server Role.
* `field_key.assignment.delete` when an App User is unassigned from a Server Role.
* `field_key.session.end` when an App User's access is revoked.
* `field_key.delete` when an App User is deleted.
* `public_link.create` when a new Public Link is created.
* `public_link.assignment.create` when a Public Link is assigned to a Server Role.
* `public_link.assignment.delete` when a Public Link is unassigned from a Server Role.
* `public_link.session.end` when a Public Link's access is revoked.
* `public_link.delete` when a Public Link is deleted.
* `submission.create` when a new Submission is created.
* `submission.update` when a Submission's metadata is updated.
* `submission.update.version` when a Submission XML data is updated.
* `submission.attachment.update` when a Submission Attachment binary is set or cleared, but _only via the REST API_. Attachments created alongside the submission over the OpenRosa `/submission` API (including submissions from Collect) do not generate audit log entries.
* `dataset.create` when a Dataset is created.
* `dataset.update` when a Dataset is updated.
* `dataset.update.publish` when a Dataset is published.
* `entity.create` when an Entity is created.
* `entity.error` when there is an error processing a Submission to create or update an Entity.
* `entity.update.version` when an Entity is updated.
* `entity.update.resolve` when an Entity conflict is resolved.
* `entity.delete` when an Entity is deleted.
* `config.set` when a system configuration is set.
* `analytics` when a Usage Report is attempted.
* Deprecated: `backup` when a backup operation is attempted for Google Drive backups.
- name: Direct Backup
x-parent-tag: System Endpoints
description: |-
_(introduced: version 1.1)_
ODK Central offers an HTTP endpoint that will immediately perform a backup on the system database and send that encrypted backup as the response. To use it, `POST` with an encryption passphrase.
Note that performing the backup takes a great deal of time, during which the request will be held open. As a result, the endpoint will trickle junk data every five seconds while that processing is occurring to prevent the request from timing out. Depending on how much data you have, it can take many minutes for the data stream to speed up to a full transfer rate.
paths:
/v1/sessions:
post:
tags:
- Session Authentication
summary: Logging in
description: |-
In order to log a `User` in to a new `Session`, you must provide their credentials, in JSON format.
For security reasons, the only possible results are success or failure. No detail is provided upon failure.
Successful responses will come with an HTTP-Only, Secure-Only cookie. This cookie is primarily meant for use by the Central frontend, and we do not recommend relying upon it. It will only work on `GET` requests, and it will only work over HTTPS.
operationId: Logging in
requestBody:
content:
'application/json':
schema:
required:
- email
- password
type: object
properties:
email:
type: string
description: The `User`'s full email address.
example: my.email.address@getodk.org
password:
type: string
description: The `User`'s password.
example: my.super.secure.password
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- expiresAt
- token
type: object
properties:
createdAt:
type: string
description: ISO date format
expiresAt:
type: string
description: ISO date format
token:
type: string
description: The bearer token associated with the session. It
consists only of URL-safe characters, so it should never need
any escaping.
example:
createdAt: 2018-04-18T03:04:51.695Z
expiresAt: 2018-04-19T03:04:51.695Z
token: lSpAIeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QPEjR7
401:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
/v1/example1:
get:
tags:
- Session Authentication
summary: Using the session
description: |-
Once you have logged in, to use your session token to authenticate with any action, supply it in a request header `Authorization` with a value of `Bearer {token}`, as seen here.
_(There is not really anything at `/v1/example1`; this section only demonstrates how generally to use Session Bearer Token Authentication.)_
operationId: Session Authentication
parameters:
- name: Authorization
in: header
description: Bearer encoding of the credentials
required: true
schema:
type: string
example: Bearer lSpAIeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QPEjR7
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
/v1/example2:
get:
tags:
- HTTPS Basic Authentication
summary: Using Basic Authentication
description: |-
To use HTTPS Basic Authentication, attach an `Authorization` header formatted so:
`Authorization: Basic bXkuZW1haWwuYWRkcmVzc0BvcGVuZGF0YWtpdC5vcmc6bXkucGFzc3dvcmQ=`
As given by [the standard](https://en.wikipedia.org/wiki/Basic_access_authentication), the text following the `Basic` marker here is a base64 encoding of the credentials, provided in the form `email:password` (in this example `my.email.address@getodk.org:my.password`).
Unlike the standard, we do not require the client to first send an unauthenticated request and retry the request only after receiving a `WWW-Authenticate` response, and in fact we will never send the `WWW-Authenticate` header. This is mostly because, as noted above, we generally discourage the use of this authentication method, and would rather not advertise its use openly. As a result, if you wish to use Basic Authentication, directly supply the header on any request that needs it.
_(There is not really anything at `/v1/example2`; this section only demonstrates how generally to use Basic Authentication.)_
operationId: Using Basic Authentication
parameters:
- name: Authorization
in: header
description: Base64 encoding of the credentials
required: true
schema:
type: string
example: Basic bXkuZW1haWwuYWRkcmVzc0BvcGVuZGF0YWtpdC5vcmc6bXkucGFzc3dvcmQ=
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
/v1/key/{appUser}/example3:
get:
tags:
- App User Authentication
summary: Using App User Authentication
description: |-
To use App User Authentication, first obtain a App User, typically by using the configuration panel in the user interface, or else by using the [App User API Resource](/central-api-accounts-and-users/#app-users). Once you have the token, you can apply it to any eligible action by prefixing the URL with `/key/{appUser}` as follows:
`/v1/key/!Ms7V3$Zdnd63j5HFacIPFEvFAuwNqTUZW$AsVOmaQFf$vIC!F8dJjdgiDnJXXOt/example/request/path`
_(There is not really anything at `/v1/example3`; this section only demonstrates how generally to use App User Authentication.)_
operationId: Using App User Authentication
parameters:
- name: appUser
in: path
description: The App User token. As with Session Bearer tokens, these tokens
only contain URL-safe characters, so no escaping is required.
required: true
schema:
type: string
example: '!Ms7V3$Zdnd63j5HFacIPFEvFAuwNqTUZW$AsVOmaQFf$vIC!F8dJjdgiDnJXXOt'
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
/v1/sessions/{token}:
delete:
tags:
- Session Authentication
summary: Logging out / Revoking an App User
description: |-
Logging out is not strictly necessary for Web Users; all sessions expire 24 hours after they are created. But it can be a good idea, in case someone else manages to steal your token. It is also the way Public Link and App User access are revoked. To do so, issue a `DELETE` request to that token resource.
**Revoking an App User**
The token associated with a App User is actually just its Session Token. As a result, although a App User Token can uniquely be used as a URL prefix as described here, the session associated with it can be revoked in exactly the same way a session is logged out, by issuing a `DELETE` request to its Session resource.
Note, however, that a App User cannot revoke itself; a `User` must perform this action.
operationId: Revoking an App User
parameters:
- name: token
in: path
description: The session bearer token, obtained at login time.
required: true
schema:
type: string
example: lSpAIeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QPEjR7
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/sessions/current:
delete:
tags:
- Session Authentication
summary: Logging out current session
description: |-
This endpoint causes the current session to log itself out. Logging out is not strictly necessary for Web Users; all sessions expire 24 hours after they are created. But it can be a good idea, in case someone else manages to steal your token.
Only the session that was used to authenticate the request is logged out. If the Actor associated with the session has other sessions as well, those are not logged out.
operationId: Logging out current session
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/users:
get:
tags:
- Users
summary: Listing all Users
description: |-
Currently, there are no paging or filtering options, so listing `User`s will get you every User in the system, every time.
Optionally, a `q` querystring parameter may be provided to filter the returned users by any given string. The search is performed via a [trigram similarity index](https://www.postgresql.org/docs/14/pgtrgm.html) over both the Email and Display Name fields, and results are ordered by match score, best matches first. Note that short search terms (less than 4 or 5 characters) may not return any results. Try a longer search if nothing is appearing.
If a `q` parameter is given, and it exactly matches an email address that exists in the system, that user's details will always be returned, even for actors who cannot `user.list`. The request must still authenticate as a valid Actor. This allows non-Administrators to choose a user for an action (eg grant rights) without allowing full search.
Actors who cannot `user.list` will always receive `[]` with a `200 OK` response.
operationId: Listing all Users
parameters:
- name: q
in: query
description: An optional search parameter.
schema:
type: string
example: alice
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
email: my.email.address@getodk.org
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Users
summary: Creating a new User
description: |-
All that is required to create a new user is an email address. That email address will receive a message instructing the new user on how to claim their new account and set a password.
Optionally, a password may also be supplied as a part of this request. If it is, the account is immediately usable with the given credentials. However, an email will still be dispatched with claim instructions as above.
Users are not able to do anything upon creation besides log in and change their own profile information. To allow Users to perform useful actions, you will need to [assign them one or more Roles](/central-api-accounts-and-users/#assignments).
operationId: Creating a new User
requestBody:
content:
'*/*':
schema:
required:
- email
type: object
properties:
email:
type: string
description: The email address of the User account to be created.
password:
type: string
description: If provided, the User account will be created with
this password. Otherwise, the user will still be able set their
own password later.
example:
email: my.email.address@getodk.org
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- displayName
- email
- id
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be `user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
email:
type: string
description: Only `User`s have email addresses associated with
them
example:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
email: my.email.address@getodk.org
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/users/{actorId}:
get:
tags:
- Users
summary: Getting User details
description: |-
Typically, you supply the integer ID to get information about the user associated with that id.
It is also possible to supply the text `current` instead of an integer ID; please see the following endpoint for documentation about this.
operationId: Getting User details
parameters:
- name: actorId
in: path
description: Typically the integer ID of the `User`. For getting user details,
you can also supply the text `current`, which will tell you about the currently
authenticated user.
required: true
schema:
type: string
example: "42"
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- displayName
- email
- id
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be `user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
email:
type: string
description: Only `User`s have email addresses associated with
them
example:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
email: my.email.address@getodk.org
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Users
summary: Deleting a User
description: |-
Upon User deletion:
* The account will be removed,
* the user will be logged out of all existing sessions,
* and should the user attempt to reset their password, they will receive an email informing them that their account has been removed.
The User record will remain on file within the database, so that when for example information about the creator of a Form or Submission is requested, basic details are still available on file. A new User account may be created with the same email address as any deleted accounts.
operationId: Deleting a User
parameters:
- name: actorId
in: path
description: Typically the integer ID of the `User`. For getting user details,
you can also supply the text `current`, which will tell you about the currently
authenticated user.
required: true
schema:
type: string
example: "42"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
patch:
tags:
- Users
summary: Modifying a User
description: |-
You can `PATCH` JSON data to update User details. Not all user information is modifiable; right now, the following fields may be updated:
* `displayName` sets the friendly display name the web interface uses to refer to the user.
* `email` sets the email address associated with the account.
When user details are updated, the `updatedAt` field will be automatically updated.
operationId: Modifying a User
parameters:
- name: actorId
in: path
description: The integer ID of the `User`.
required: true
schema:
type: string
example: "42"
requestBody:
content:
'*/*':
schema:
type: object
properties:
displayName:
type: string
description: The friendly display name that should be associated
with this User.
email:
type: string
description: The email address that should be associated with this
User.
example:
displayName: New Name
email: new.email.address@getodk.org
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- displayName
- email
- id
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be `user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
email:
type: string
description: Only `User`s have email addresses associated with
them
example:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
email: my.email.address@getodk.org
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/users/current:
get:
tags:
- Users
summary: Getting authenticated User details
description: |-
Typically, you would get User details by the User's numeric Actor ID.
However, if you only have a Bearer token, for example, you don't have any information about the user attached to that session, including even the ID with which to get more information. So you can instead supply the text `current` to get the user information associated with the authenticated session.
If you _do_ use `current`, you may request extended metadata. Supply an `X-Extended-Metadata` header value of `true` to additionally retrieve an array of strings of the `verbs` the authenticated User/Actor is allowed to perform server-wide.
operationId: Getting authenticated User details
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be `user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
email:
type: string
description: Only `User`s have email addresses associated with
them
example:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
email: my.email.address@getodk.org
application/json; extended:
schema:
required:
- createdAt
- displayName
- email
- id
- type
- verbs
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be `user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
email:
type: string
description: Only `User`s have email addresses associated with
them
verbs:
type: array
description: The verbs the authenticated Actor is allowed to perform
server-wide.
items:
type: object
example:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
email: my.email.address@getodk.org
verbs:
- project.create
- project.update
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/users/{actorId}/password:
put:
tags:
- Users
summary: Directly updating a user password
description: To directly update a user password, you will need to reprove the
user's intention by supplying the `old` password alongside the `new`. If you
simply want to initiate an email-based password reset process, see the following
endpoint.
operationId: Directly updating a user password
parameters:
- name: actorId
in: path
description: The integer ID of the `User`.
required: true
schema:
type: string
example: "42"
requestBody:
content:
'*/*':
schema:
required:
- new
- old
type: object
properties:
old:
type: string
description: The user's current password.
new:
type: string
description: The new password that the user wishes to set.
example:
old: old.password
new: new.password
required: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/users/reset/initiate:
post:
tags:
- Users
summary: Initating a password reset
description: |-
Anybody can initate a reset of any user's password. An email will be sent with instructions on how to complete the password reset; it contains a token that is required to complete the process.
The optional query parameter `invalidate` may be set to `true` to immediately invalidate the user's current password, regardless of whether they complete the reset process. This can be done if, for example, their password has been compromised. In order to do this, though, the request must be performed as an authenticated user with permission to do this. If invalidation is attempted without the proper permissions, the entire request will fail.
If the email address provided does not match any user in the system, that address will still be sent an email informing them of the attempt and that no account was found.
operationId: Initating a password reset
parameters:
- name: invalidate
in: query
description: Specify `true` in order to immediately invalidate the user's
present password.
schema:
type: boolean
example: "true"
requestBody:
content:
'*/*':
schema:
required:
- email
type: object
properties:
email:
type: string
description: The email address of the User account whose password
is to be reset.
example:
email: my.email.address@getodk.org
required: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/projects/{projectId}/app-users:
get:
tags:
- App Users
summary: Listing all App Users
description: |-
Currently, there are no paging or filtering options, so listing `App User`s will get you every App User in the system, every time.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to additionally retrieve the `lastUsed` timestamp of each App User, as well as to retrieve the details of the `Actor` the App User was `createdBy`.
operationId: Listing all App Users
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/AppUser'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
token: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
projectId: 1
lastUsed: 2018-04-14T08:34:21.633Z
application/json; extended:
schema:
type: array
description: Extended App Users
items:
$ref: '#/components/schemas/ExtendedAppUser'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
token: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
projectId: 1
createdBy:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
lastUsed: 2018-04-14T08:34:21.633Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- App Users
summary: Creating a new App User
description: |-
The only information required to create a new `App User` is its `displayName` (this is called "Nickname" in the administrative panel).
When an App User is created, they are assigned no rights. They will be able to authenticate and list forms on a mobile client, but the form list will be empty, as the list only includes Forms that the App User has read access to. Once an App User is created, you'll likely wish to use the [Form Assignments resource](/central-api-form-management/#form-assignments) to actually assign the `app-user` role to them for the Forms you wish.
operationId: Creating a new App User
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
requestBody:
content:
'*/*':
schema:
required:
- displayName
type: object
properties:
displayName:
type: string
description: The friendly nickname of the `App User` to be created.
example:
displayName: My Display Name
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- displayName
- id
- projectId
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be `user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
token:
type: string
description: If present, this is the Token that can be used to
authenticate a request as this `App User`. If not present, this
`App User`'s access has been revoked.
projectId:
type: number
description: The ID of the `Project` that this `App User` is bound
to.
example:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
token: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
projectId: 1
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/projects/{projectId}/app-users/{id}:
delete:
tags:
- App Users
summary: Deleting a App User
description: |-
You don't have to delete a `App User` in order to cut off its access. Using a `User`'s credentials you can simply [log the App User's session out](/central-api-authentication/#logging-out-current-session) using its token. This will end its session without actually deleting the App User, which allows you to still see it in the configuration panel and inspect its history. This is what the administrative panel does when you choose to "Revoke" the App User.
That said, if you do wish to delete the App User altogether, you can do so by issuing a `DELETE` request to its resource path. App Users cannot delete themselves.
operationId: Deleting a App User
parameters:
- name: id
in: path
description: The numeric ID of the App User
required: true
schema:
type: number
example: "16"
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/roles:
get:
tags:
- Roles
summary: Listing all Roles
description: 'Currently, there are no paging or filtering options, so listing
`Role`s will get you every Role in the system, every time. There are no authorization
restrictions upon this endpoint: anybody is allowed to list all Role information
at any time.'
operationId: Listing all Roles
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Role'
example:
- id: 4
name: Project Manager
system: manager
verbs:
- project.update
- project.delete
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
/v1/roles/{id}:
get:
tags:
- Roles
summary: Getting Role Details
description: |-
Getting an individual Role does not reveal any additional information over listing all Roles. It is, however, useful for direct lookup of a specific role:
The `id` parameter for Roles here and elsewhere will accept the numeric ID associated with that Role, _or_ a `system` name if there is one associated with the Role. Thus, you may request `/v1/roles/admin` on any ODK Central server and receive information about the Administrator role.
As with Role listing, there are no authorization restrictions upon this endpoint: anybody is allowed to get information about any Role at any time.
operationId: Getting Role Details
parameters:
- name: id
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: "1"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Role'
example:
id: 4
name: Project Manager
system: manager
verbs:
- project.update
- project.delete
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
/v1/assignments:
get:
tags:
- Assignments
summary: Listing all Assignments
description: |-
This will list every server-wide assignment, in the form of `actorId`/`roleId` pairs. It will _not_ list Project-specific Assignments. To find those, you will need the [Assignments subresource](/central-api-project-management/#project-assignments) within Projects.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to expand the `actorId` into a full `actor` objects. The Role reference remains a numeric ID.
operationId: Listing all Assignments
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Assignment'
example:
- actorId: 115
roleId: 4
application/json; extended:
schema:
type: array
description: Extended Assignment
items:
$ref: '#/components/schemas/ExtendedAssignment'
example:
- actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
roleId: 4
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/assignments/{roleId}:
get:
tags:
- Assignments
summary: Listing all Actors assigned some Role
description: Given a `roleId`, which may be a numeric ID or a string role `system`
name, this endpoint lists all `Actors` that have been assigned that Role on
a server-wide basis.
operationId: Listing all Actors assigned some Role
parameters:
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: admin
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Actor'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/assignments/{roleId}/{actorId}:
post:
tags:
- Assignments
summary: Assigning an Actor to a server-wide Role
description: |-
Given a `roleId`, which may be a numeric ID or a string role `system` name, and a numeric `actorId`, assigns that Role to that Actor across the entire server.
No `POST` body data is required, and if provided it will be ignored.
operationId: Assigning an Actor to a server-wide Role
parameters:
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: admin
- name: actorId
in: path
description: The integer ID of the `Actor`.
required: true
schema:
type: number
example: "14"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Assignments
summary: Stripping an Role Assignment from an Actor
description: Given a `roleId`, which may be a numeric ID or a string role `system`
name, and a numeric `actorId`, unassigns that Role from that Actor across
the entire server.
operationId: Stripping an Role Assignment from an Actor
parameters:
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: admin
- name: actorId
in: path
description: The integer ID of the `Actor`.
required: true
schema:
type: number
example: "14"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects:
get:
tags:
- Projects
summary: Listing Projects
description: |-
The Projects listing endpoint is somewhat unique in that it is freely accessible to anybody, even unauthenticated clients. Rather than reject the user with a `403` or similar error, the Projects listing will only return Projects that the authenticated Actor is allowed to see. In most cases, this means that unauthenticated requests will receive `[]` in reply.
Currently, there are no paging or filtering options, so listing `Project`s will get you every Project you have access to.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to additionally retrieve the `appUsers` count of App Users and `forms` count of Forms within the Project, as well as the `lastSubmission` timestamp of the latest submission to any for in the project, if any.
operationId: Listing Projects
parameters:
- name: forms
in: query
description: |-
_(introduced: Version 1.5)_
If set to true then endpoint also returns the Forms that the authenticated Actor is allowed to see, with those Forms nested within their corresponding Project under a new parameter `formList`. The returned Forms will match structure of Forms requested with extended metadata (including additional `lastSubmission` timestamp and `submissions` and `reviewStates` counts)
schema:
type: boolean
example: "true"
- name: datasets
in: query
description: |-
_(introduced: Version 2023.4)_
If set to true then endpoint also returns the Datasets that the authenticated Actor is allowed to see, with those Datasets nested within their corresponding Project under a new parameter `datasetList`. The returned Datasets will match structure of Datasets requested with extended metadata (including additional `lastEntity` timestamp and `entities`)
schema:
type: boolean
example: "true"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
description: Standard Response
items:
$ref: '#/components/schemas/Project'
example:
- id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
application/json; extended:
schema:
type: array
description: Extended Response
items:
$ref: '#/components/schemas/ExtendedProject'
example:
- id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
appUsers: 4
forms: 7
lastSubmission: 2018-04-18T03:04:51.695Z
datasets: 2
lastEntity: 2023-04-18T03:04:51.695Z
post:
tags:
- Projects
summary: Creating a Project
description: To create a Project, the only information you must supply (via
POST body) is the desired name of the Project.
operationId: Creating a Project
requestBody:
content:
'*/*':
schema:
required:
- name
type: object
properties:
name:
type: string
description: The desired name of the Project.
example:
name: Project Name
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- name
type: object
properties:
id:
type: number
description: The numerical ID of the Project.
name:
type: string
description: The name of the Project.
description:
type: string
description: The description of the Project, which is rendered
as Markdown on Frontend.
keyId:
type: number
description: If managed encryption is enabled on the project,
the numeric ID of the encryption key as tracked by Central is
given here.
archived:
type: boolean
description: Whether the Project is archived or not. `null` is
equivalent to `false`. All this does is sort the Project to
the bottom of the list and disable management features in the
web management application.
example:
id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/projects/{id}:
get:
tags:
- Projects
summary: Getting Project Details
description: |-
To get just the details of a single Project, `GET` its single resource route by its numeric ID.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to additionally retrieve the `appUsers` count of App Users and `forms` count of forms within the Project, as well as the `lastSubmission` timestamp of the latest submission to any for in the project, if any.
In addition, the extended metadata version of this endpoint (but not the overall Project listing) returns an array of the `verbs` the authenticated Actor is able to perform on/within the Project.
operationId: Getting Project Details
parameters:
- name: id
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: object
description: Standard Response
$ref: '#/components/schemas/Project'
example:
id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
application/json; extended:
schema:
type: object
description: Extended Response
$ref: '#/components/schemas/ExtendedProjectWithVerbs'
example:
id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
appUsers: 4
forms: 7
lastSubmission: 2018-04-18T03:04:51.695Z
datasets: 2
lastEntity: 2023-04-18T03:04:51.695Z
verbs:
- "form.create"
- "form.delete"
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
put:
tags:
- Projects
summary: Deep Updating Project and Form Details
description: |-
_(introduced: version 0.7)_
When managing a large deployment, it can be necessary to make sweeping changes to all Form States and Assignments within it at once—when rolling out a new Form, for example, or replacing a deprecated version with a new revision.
For this purpose, we offer this `PUT` resource, which allows a deep update of Project metadata, Form metadata, and Form Assignment metadata at once and transactionally using a nested data format.
One important mechanic to note immediately here is that we follow true `PUT` semantics, meaning that the data you provide is not merged with existing data to form an update. With our usual `PATCH` endpoints, we do this kind of merging and so data that you don't explicitly pass us is left alone. Because we allow the deletion of Form Assignments by way of omission with this API, we treat _all_ omissions as an explicit specification to null the omitted field. This means that, for example, you must always re-specify the Project name, the Project description, and archival flag with every `PUT`.
This adherence to `PUT` semantics would normally imply that Forms could be created or deleted by way of this request, but such an operation could become incredibly complex. We currently return a `501 Not Implemented` error if you supply nested Form information but you do not give us exactly the entire set of extant Forms.
You can inspect the Request format for this endpoint to see the exact nested data structure this endpoint accepts. Each level of increased granularity is optional: you may `PUT` just Project metadata, with no `forms` array, and you may `PUT` Project and Form metadata but omit `assignments` from any Form, in which case the omitted detail will be left as-is.
operationId: Deep Updating Project and Form Details
parameters:
- name: id
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
requestBody:
content:
'*/*':
schema:
required:
- name
type: object
properties:
name:
type: string
description: The desired name of the Project.
description:
type: string
description: The desired description of the Project.
archived:
type: boolean
description: Archives the Project.
forms:
type: array
description: If given, the Form metadata to update.
items: {
type: object
}
example:
name: New Project Name
description: New Project Description
archived: false
forms:
- xmlFormId: simple
state: open
assignments:
- roleId: 2
actorId: 14
- roleId: 2
actorId: 21
- xmlFormId: test
state: closed
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- name
type: object
properties:
id:
type: number
description: The numerical ID of the Project.
name:
type: string
description: The name of the Project.
description:
type: string
description: The description of the Project, which is rendered
as Markdown on Frontend.
keyId:
type: number
description: If managed encryption is enabled on the project,
the numeric ID of the encryption key as tracked by Central is
given here.
archived:
type: boolean
description: Whether the Project is archived or not. `null` is
equivalent to `false`. All this does is sort the Project to
the bottom of the list and disable management features in the
web management application.
example:
id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
501:
description: Not Implemented
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "501.1"
message: The requested feature $unsupported is not supported by this
server.
x-codegen-request-body-name: body
delete:
tags:
- Projects
summary: Deleting a Project
description: Deleting a Project will remove it from the management interface
and make it permanently inaccessible. Do not do this unless you are certain
you will never need any of its data again. For now, deleting a Project will
not purge its Forms. (We will change that in a future release.)
operationId: Deleting a Project
parameters:
- name: id
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
patch:
tags:
- Projects
summary: Updating Project Details
description: |-
The Project name may be updated, as well as the Project description and the `archived` flag.
By default, `archived` is not set, which is equivalent to `false`. If `archived` is set to `true`, the Project will be sorted to the bottom of the list, and in the web management application the Project will become effectively read-only. API write access will not be affected.
operationId: Updating Project Details
parameters:
- name: id
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
requestBody:
content:
'*/*':
schema:
required:
- name
type: object
properties:
name:
type: string
description: The desired name of the Project.
description:
type: string
description: The description of the Project.
archived:
type: boolean
description: Archives the Project.
example:
name: New Project Name
description: Description of this Project to show on Central.
archived: true
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- name
type: object
properties:
id:
type: number
description: The numerical ID of the Project.
name:
type: string
description: The name of the Project.
description:
type: string
description: The description of the Project, which is rendered
as Markdown on Frontend.
keyId:
type: number
description: If managed encryption is enabled on the project,
the numeric ID of the encryption key as tracked by Central is
given here.
archived:
type: boolean
description: Whether the Project is archived or not. `null` is
equivalent to `false`. All this does is sort the Project to
the bottom of the list and disable management features in the
web management application.
example:
id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/projects/{id}/key:
post:
tags:
- Projects
summary: Enabling Project Managed Encryption
description: |-
_(introduced: version 0.6)_
[Project Managed Encryption](/central-api-encryption) can be enabled via the API. To do this, `POST` with the `passphrase` and optionally a reminder `hint` about the passphrase. If managed encryption is already enabled, a `409` error response will be returned.
Enabling managed encryption will modify all unencrypted forms in the project, and as a result the `version` of all forms within the project will also be modified. It is therefore best to enable managed encryption before devices are in the field. Any forms in the project that already have self-supplied encryption keys will be left alone.
operationId: Enabling Project Managed Encryption
parameters:
- name: id
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
requestBody:
content:
'*/*':
schema:
required:
- passphrase
type: object
properties:
passphrase:
type: string
description: The encryption passphrase. If this passphrase is lost,
the data will be irrecoverable.
hint:
type: string
description: A reminder about the passphrase. This is primarily
useful when multiple encryption keys and passphrases are being
used, to tell them apart.
example:
passphrase: super duper secret
hint: it was a secret
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- name
type: object
properties:
id:
type: number
description: The numerical ID of the Project.
name:
type: string
description: The name of the Project.
description:
type: string
description: The description of the Project, which is rendered
as Markdown on Frontend.
keyId:
type: number
description: If managed encryption is enabled on the project,
the numeric ID of the encryption key as tracked by Central is
given here.
archived:
type: boolean
description: Whether the Project is archived or not. `null` is
equivalent to `false`. All this does is sort the Project to
the bottom of the list and disable management features in the
web management application.
example:
id: 1
name: Default Project
description: Description of this Project to show on Central.
keyId: 3
archived: false
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
409:
description: Conflict
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "409.1"
message: A resource already exists with id value(s) of 1.
x-codegen-request-body-name: body
/v1/projects/{projectId}/assignments:
get:
tags:
- Project Assignments
summary: Listing all Project Assignments
description: |-
This will list every assignment upon this Project, in the form of `actorId`/`roleId` pairs.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to expand the `actorId` into a full `actor` objects. The Role reference remains a numeric ID.
operationId: Listing all Project Assignments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "2"
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Assignment'
example:
- actorId: 115
roleId: 4
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedAssignment'
example:
- actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
roleId: 4
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/assignments/{roleId}:
get:
tags:
- Project Assignments
summary: Listing all Actors assigned some Project Role
description: Given a `roleId`, which may be a numeric ID or a string role `system`
name, this endpoint lists all `Actors` that have been assigned that Role upon
this particular Project.
operationId: Listing all Actors assigned some Project Role
parameters:
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: manager
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Actor'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/assignments/{roleId}/{actorId}:
post:
tags:
- Project Assignments
summary: Assigning an Actor to a Project Role
description: |-
Given a `roleId`, which may be a numeric ID or a string role `system` name, and a numeric `actorId`, assigns that Role to that Actor for this particular Project.
No `POST` body data is required, and if provided it will be ignored.
operationId: Assigning an Actor to a Project Role
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: manager
- name: actorId
in: path
description: The integer ID of the `Actor`.
required: true
schema:
type: number
example: "14"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Project Assignments
summary: Revoking a Project Role Assignment from an Actor
description: Given a `roleId`, which may be a numeric ID or a string role `system`
name, and a numeric `actorId`, unassigns that Role from that Actor for this
particular Project.
operationId: Revoking a Project Role Assignment from an Actor
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: manager
- name: actorId
in: path
description: The integer ID of the `Actor`.
required: true
schema:
type: number
example: "14"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/assignments/forms:
get:
tags:
- Project Assignments
summary: Seeing all Form Assignments within a Project
description: |-
Returns a summary of all _Form-specific_ Assignments within this Project. This endpoint is meant to simplify the task of summarizing all Form permissions within a Project at a glance and in one transactional request. Because it is necessary to specify which Form each Assignment is attached to, returned results form this endpoint include an `xmlFormId` field.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to expand the `actorId` into a full `actor` objects. The Role reference remains a numeric ID and the Form reference remains a string ID.
operationId: Seeing all Form Assignments within a Project
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/FormSummaryAssignment'
example:
- actorId: 115
xmlFormId: simple
roleId: 4
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedFormSummaryAssignment'
example:
- actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
xmlFormId: simple
roleId: 4
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/assignments/forms/{roleId}:
get:
tags:
- Project Assignments
summary: Seeing Role-specific Form Assignments within a Project
description: |-
Like the [Form Assignments summary API](/central-api-form-management/#listing-all-form-assignments), but filtered by some `roleId`.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to expand the `actorId` into a full `actor` objects. The Role reference remains a numeric ID and the Form reference remains a string ID.
operationId: Seeing Role-specific Form Assignments within a Project
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: roleId
in: path
description: The numeric ID of the Role
required: true
schema:
type: number
example: "16"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/FormSummaryAssignment'
example:
- actorId: 115
xmlFormId: simple
roleId: 4
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedFormSummaryAssignment'
example:
- actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
xmlFormId: simple
roleId: 4
403:
description: Forbidden
content:
application/json; extended:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms:
get:
tags:
- Forms
summary: List all Forms
description: |-
Currently, there are no paging or filtering options, so listing `Form`s will get you every Form you are allowed to access, every time.
As of version 1.2, Forms that are unpublished (that only carry a draft and have never been published) will appear with full metadata detail. Previously, certain details like `name` were omitted. You can determine that a Form is unpublished by checking the `publishedAt` value: it will be `null` for unpublished forms.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to additionally retrieve the `submissions` count of the number of Submissions that each Form has, the `reviewStates` object of counts of Submissions with specific review states, the `lastSubmission` most recent submission timestamp, as well as the Actor the Form was `createdBy`.
operationId: List all Forms
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Form'
example:
- projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedForm'
example:
- projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
submissions: 10
reviewStates:
received: 3
hasIssues: 2
edited: 1
lastSubmission: 2018-04-18T03:04:51.695Z
createdBy:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
entityRelated: false
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Forms
summary: Creating a new Form
description: |-
When creating a `Form`, the only required data is the actual XForms XML or XLSForm itself. Use it as the `POST` body with a `Content-Type` header of `application/xml` (`text/xml` works too), and the Form will be created.
As of Version 0.8, Forms will by default be created in Draft state, accessible under `/projects/…/forms/…/draft`. The Form itself will not have a public XML definition, and will not appear for download onto mobile devices. You will need to [publish the form](/central-api-form-management/#publishing-a-draft-form) to finalize it for data collection. To disable this behaviour, and force the new Form to be immediately ready, you can pass the querystring option `?publish=true`.
For XLSForm upload, either `.xls` or `.xlsx` are accepted. You must provide the `Content-Type` request header corresponding to the file type: `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` for `.xlsx` files, and `application/vnd.ms-excel` for `.xls` files. You must also provide an `X-XlsForm-FormId-Fallback` request header with the `formId` you want the resulting form to have, if the spreadsheet does not already specify. This header field accepts percent-encoded values to support Unicode characters and other non-ASCII values.
By default, any XLSForm conversion Warnings will fail this request and return the warnings rather than use the converted XML to create a form. To override this behaviour, provide a querystring flag `?ignoreWarnings=true`. Conversion Errors will always fail this request.
The API will currently check the XML's structure in order to extract the information we need about it, but ODK Central does _not_ run comprehensive validation on the full contents of the XML to ensure compliance with the ODK specification. Future versions will likely do this, but in the meantime you will have to use a tool like [ODK Validate](https://getodk.org/use/validate/) to be sure your Forms are correct.
You will get following workflow warnings while creating a new form or uploading a new version of an existing form:
- Structural Change: Returned when the uploaded definition of the form removes, renames or moves a field to a different group/repeat. [Learn more](https://docs.getodk.org/central-forms/#central-forms-updates)
- Deleted Form: Returned when there is a form with the same ID in the Trash. [Learn more](https://docs.getodk.org/central-forms/#deleting-a-form)
**Creating Datasets with Forms**
Starting from Version 2022.3, a Form can also create a Dataset by defining a Dataset schema in the Form definition (XForms XML or XLSForm). When a Form with a Dataset schema is uploaded, a Dataset and its Properties are created. The state of the Dataset is dependent on the state of the Form; you will need to publish the Form to publish the Dataset. Datasets in the Draft state are not returned in [Dataset APIs](/central-api-dataset-management), however the [Related Datasets](/central-api-form-management/#draft-form-dataset-diff) API for the Form can be called to get the Dataset and its Properties.
It is possible to define the schema of a Dataset in multiple Forms. Such Forms can be created and published in any order. Publishing any of the Forms will also publish the Dataset and will generate a `dataset.create` event; `dataset.update` events are generated in Audit logs when a Form adds a new property in the Dataset. The state of a Property of a Dataset is also dependent on the state of the Form that FIRST defines that Property, which means if a Form is in the Draft state then the Properties defined by that Form will not appear in the [.csv file](/central-api-dataset-management/#download-dataset) of the Dataset.
operationId: Creating a new Form
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: ignoreWarnings
in: query
description: Defaults to `false`. Set to `true` if you want the Form to be
created even if the XLSForm conversion results in warnings.
schema:
type: boolean
example: "false"
- name: publish
in: query
description: Defaults to `false`. Set to `true` if you want the Form to skip
the Draft state to Published.
schema:
type: boolean
example: "false"
- name: X-XlsForm-FormId-Fallback
in: header
description: e.g. filename.xlsx
schema:
type: string
example: filename.xlsx
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- hash
- projectId
- state
- version
- xmlFormId
type: object
properties:
projectId:
type: number
description: The `id` of the project this form belongs to.
xmlFormId:
type: string
description: The `id` of this form as given in its XForms XML
definition
name:
type: string
description: The friendly name of this form. It is given by the
`
` in the XForms XML definition.
version:
type: string
description: The `version` of this form as given in its XForms
XML definition. If no `version` was specified in the Form, a
blank string will be given.
enketoId:
type: string
description: If it exists, this is the survey ID of this Form
on Enketo at `/-`. This will be the ID of the published version
if it exists, otherwise it will be the draft ID. Only a cookie-authenticated
user may access the preview through Enketo.
hash:
type: string
description: An MD5 sum automatically computed based on the XForms
XML definition. This is required for OpenRosa compliance.
keyId:
type: number
description: If a public encryption key is present on the form,
its numeric ID as tracked by Central is given here.
state:
type: string
description: The present lifecycle status of this form. Controls
whether it is available for download on survey clients or accepts
new submissions.
enum:
- open
- closing
- closed
publishedAt:
type: string
description: Indicates when a draft has most recently been published
for this Form. If this value is `null`, this Form has never
been published yet, and contains only a draft.
createdAt:
type: string
description: ISO date format
updatedAt:
type: string
description: ISO date format
example:
projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
409:
description: Conflict
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "409.1"
message: A resource already exists with id value(s) of 1.
/v1/projects/{projectId}/forms/{xmlFormId}:
get:
tags:
- Individual Form
summary: Getting Form Details
description: 'This endpoint supports retrieving extended metadata; provide a
header `X-Extended-Metadata: true` to additionally retrieve the `submissions`
count of the number of `Submission`s that this Form has, as well as the `lastSubmission`
most recent submission timestamp.'
operationId: Getting Form Details
parameters:
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
$ref: '#/components/schemas/Form'
example:
- projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
application/json; extended:
schema:
$ref: '#/components/schemas/ExtendedForm'
example:
projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
submissions: 10
reviewStates:
received: 3
hasIssues: 2
edited: 1
lastSubmission: 2018-04-18T03:04:51.695Z
createdBy:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
entityRelated: false
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Individual Form
summary: Deleting a Form
description: When a Form is deleted, it goes into the Trash section, but it
can now be restored from the Trash. After 30 days in the Trash, the Form and
all of its resources and submissions will be automatically purged. If your
goal is to prevent it from showing up on survey clients like ODK Collect,
consider setting its `state` to `closing` or `closed` instead (see [Modifying
a Form](/central-api-form-management/#modifying-a-form) just above for
more details).
operationId: Deleting a Form
parameters:
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
patch:
tags:
- Individual Form
summary: Modifying a Form
description: |-
It is currently possible to modify only one thing about a `Form`: its `state`, which governs whether it is available for download onto survey clients and whether it accepts new `Submission`s. See the `state` Attribute in the Request documentation to the right to see the possible values and their meanings.
We use `PATCH` rather than `PUT` to represent the update operation, so that you only have to supply the properties you wish to change. Anything you do not supply will remain untouched.
operationId: Modifying a Form
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
requestBody:
content:
'*/*':
schema:
type: object
properties:
state:
type: string
description: If supplied, the Form lifecycle state will move to
this value.
enum:
- open
- closing
- closed
example:
state: open
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- hash
- projectId
- state
- version
- xmlFormId
type: object
properties:
projectId:
type: number
description: The `id` of the project this form belongs to.
xmlFormId:
type: string
description: The `id` of this form as given in its XForms XML
definition
name:
type: string
description: The friendly name of this form. It is given by the
`` in the XForms XML definition.
version:
type: string
description: The `version` of this form as given in its XForms
XML definition. If no `version` was specified in the Form, a
blank string will be given.
enketoId:
type: string
description: If it exists, this is the survey ID of this Form
on Enketo at `/-`. This will be the ID of the published version
if it exists, otherwise it will be the draft ID. Only a cookie-authenticated
user may access the preview through Enketo.
hash:
type: string
description: An MD5 sum automatically computed based on the XForms
XML definition. This is required for OpenRosa compliance.
keyId:
type: number
description: If a public encryption key is present on the form,
its numeric ID as tracked by Central is given here.
state:
type: string
description: The present lifecycle status of this form. Controls
whether it is available for download on survey clients or accepts
new submissions.
enum:
- open
- closing
- closed
publishedAt:
type: string
description: Indicates when a draft has most recently been published
for this Form. If this value is `null`, this Form has never
been published yet, and contains only a draft.
createdAt:
type: string
description: ISO date format
updatedAt:
type: string
description: ISO date format
example:
projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/projects/{projectId}/forms/{xmlFormId}.xml:
get:
tags:
- Individual Form
summary: Retrieving Form XML
description: To get the XML of the `Form`, add `.xml` to the end of the request
URL.
operationId: Retrieving Form XML
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/xml:
example: |
Simple
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}.xlsx:
get:
tags:
- Individual Form
summary: Retrieving Form XLS(X)
description: If a Form was created with an Excel file (`.xls` or `.xlsx`), you
can get that file back by adding `.xls` or `.xlsx` as appropriate to the Form
resource path.
operationId: Retrieving Form XLS(X)
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
example: |
(binary data)
403:
description: Forbidden
content:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/attachments:
get:
tags:
- Individual Form
summary: Listing Form Attachments
description: This endpoint allows you to fetch the list of expected attachment
files, and will tell you whether the server is in possession of each file
or not. To modify an attachment, you'll need to create a Draft.
operationId: Listing Form Attachments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/FormAttachment'
example:
- name: myfile.mp3
type: image
exists: true
blobExists: true
datasetExists: true
updatedAt: 2018-03-21T12:45:02.312Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/attachments/{filename}:
get:
tags:
- Individual Form
summary: Downloading a Form Attachment
description: |-
To download a single file, use this endpoint. The appropriate `Content-Disposition` (attachment with a filename) and `Content-Type` (based on the type supplied at upload time) will be given.
This endpoint supports `ETag`, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, it returns a value in `ETag` header, you can pass this value in the header `If-None-Match` of subsequent requests. If the file has not been changed since the previous request, you will receive `304 Not Modified` response otherwise you'll get the latest file.
operationId: Downloading a Form Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: filename
in: path
description: The name of the file to download.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
ETag:
schema:
type: string
description: content version identifier
content:
"{the MIME type of the attachment file itself}":
schema:
type: object
example: (binary data)
304:
description: Not Modified
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/fields:
get:
tags:
- Individual Form
summary: Getting Form Schema Fields
description: |-
_(introduced: version 0.8)_
For applications that do not rely on JavaRosa, it can be challenging to parse XForms XML into a simple schema structure. Because Central Backend already implements and performs such an operation for its own internal purposes, we also expose this utility for any downstream consumers which wish to make use of it.
While this may eventually overlap with the new OData JSON CSDL specification, we are likely to maintain this API as it more closely mirrors the original XForms data types and structure.
Central internally processes the XForms schema tree into a flat list of fields, and this is how the data is returned over this endpoint as well. It will always return fields in a _depth-first traversal order_ of the original `` XML block in the XForm.
You may optionally add the querystring parameter `?odata=true` to sanitize the field names and paths to match the way they will be outputted for OData. While the original field names as given in the XForms definition may be used as-is for CSV output, OData has some restrictions related to the domain-qualified identifier syntax it uses.
operationId: Getting Form Schema Fields
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: odata
in: query
description: If set to `true`, will sanitize field names.
schema:
type: boolean
example: "false"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
example:
- name: meta
path: /meta
type: structure
- name: instanceID
path: /meta/instanceID
type: string
- name: name
path: /name
type: string
- name: age
path: /age
type: int
- name: photo
path: /photo
type: binary
binary: true
items:
required:
- name
- path
- type
type: object
properties:
name:
type: string
path:
type: string
type:
type: string
binary:
type: boolean
example:
- name: meta
path: /meta
type: structure
- name: instanceID
path: /meta/instanceID
type: string
- name: name
path: /name
type: string
- name: age
path: /age
type: int
- name: photo
path: /photo
type: binary
binary: true
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{id}/restore:
post:
tags:
- Individual Form
summary: Restoring a Form
description: |-
_(introduced: version 1.4)_
Deleted forms can now be restored (as long as they have been in the Trash less than 30 days and have not been purged). However, a deleted Form with the same `xmlFormId` as an active Form cannot be restored while that other Form is active. This `/restore` URL uses the numeric ID of the Form (now returned by the `/forms` endpoint) rather than the `xmlFormId` to unambigously restore.
operationId: Restoring a Form
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: id
in: path
description: The ID (not xmlFormId) of the Form
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft:
get:
tags:
- Draft Form
summary: Getting Draft Form Details
description: The response here will include standard overall Form metadata,
like `xmlFormId`, in addition to the Draft-specific information.
operationId: Getting Draft Form Details
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/DraftForm'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Draft Form
summary: Creating a Draft Form
description: |-
`POST`ing here will create a new Draft Form on the given Form. For the most part, it takes the same parameters as the [Create Form request](/central-api-form-management/#creating-a-new-form): you can submit XML or Excel files, you can provide `ignoreWarnings` if you'd like.
Additionally, however, you may `POST` with no `Content-Type` and an empty body to create a Draft Form with a copy of the definition (XML, XLS, etc) that is already published, if there is one. This can be useful if you don't wish to update the Form definition itself, but rather one or more Form Attachments.
If your Draft form schema contains any field path which overlaps with a field path of a previous version of the Form, but with a different data type, your request will be rejected. You can rename the conflicting field, or correct it to have the same data type as it did previously.
When a Draft is created, the expected Form Attachments are computed and slots are created, as with a new Form. Any attachments that match existing ones on the published Form, if it exists, will be copied over to the new Draft.
Even if a Draft exists, you can always replace it by `POST`ing here again. In that case, the attachments that exist on the Draft will similarly be copied over to the new Draft. If you wish to copy from the published version instead, you can do so by first `DELETE`ing the extant Draft.
Draft `version` conflicts are allowed with prior versions of a Form while in Draft state. If you attempt to [publish the Form](/central-api-form-management/#publishing-a-draft-form) without correcting the conflict, the publish operation will fail. You can request that Central update the version string on your behalf as part of the publish operation to avoid this: see that endpoint for more information.
The `xmlFormId`, however, must exactly match that of the Form overall, or the request will be rejected.
Starting from Version 2022.3, a Draft Form can also create or update a Dataset by defining a Dataset schema in the Form definition. The state of the Dataset and its Properties is dependent on the state of the Form, see [Creating a new form](/central-api-form-management/#creating-a-new-form) for more details.
operationId: Creating a Draft Form
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: ignoreWarnings
in: query
description: Defaults to `false`. Set to `true` if you want the form to be
created even if the XLSForm conversion results in warnings.
schema:
type: boolean
example: "false"
- name: X-XlsForm-FormId-Fallback
in: header
description: e.g. filename.xlsx
schema:
type: string
example: filename.xlsx
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Draft Form
summary: Deleting a Draft Form
description: |-
Once a Draft Form is deleted, its definition and any Form Attachments associated with it will be removed.
You will not be able to delete the draft if there is no published version of the form.
operationId: Deleting a Draft Form
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft.xml:
get:
tags:
- Draft Form
summary: Retrieving Draft Form XML
description: To get the XML of the Draft Form, add `.xml` to the end of the
request URL.
operationId: Retrieving Draft Form XML
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/xml:
example: |
Simple
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft.xlsx:
get:
tags:
- Draft Form
summary: Retrieving Draft Form XLS(X)
description: If a Draft Form was created with an Excel file (`.xls` or `.xlsx`),
you can get that file back by adding `.xls` or `.xlsx` as appropriate to the
Draft Form resource path.
This endpoint supports `ETag`, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, it returns a value in `ETag` header, you can pass this value in the header `If-None-Match` of subsequent requests. If the file has not been changed since the previous request, you will receive `304 Not Modified` response otherwise you'll get the latest file.
operationId: Retrieving Draft Form XLS(X)
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
headers:
ETag:
schema:
type: string
description: content version identifier
content:
application/xml:
example: |
(binary data)
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft/attachments:
get:
tags:
- Draft Form
summary: Listing expected Draft Form Attachments
description: Form Attachments for each form are automatically determined when
the form is first created, by scanning the XForms definition for references
to media or data files. Because of this, it is not possible to directly modify
the list of form attachments; that list is fully determined by the given XForm.
Instead, the focus of this API subresource is around communicating that expected
list of files, and uploading binaries into those file slots.
operationId: Listing expected Draft Form Attachments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/FormAttachment'
example:
- name: myfile.mp3
type: image
exists: true
blobExists: true
datasetExists: true
updatedAt: 2018-03-21T12:45:02.312Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft/attachments/{filename}:
get:
tags:
- Draft Form
summary: Downloading a Draft Form Attachment
description: To download a single file, use this endpoint. The appropriate `Content-Disposition`
(attachment with a filename or Dataset name) and `Content-Type` (based on
the type supplied at upload time or `text/csv` in the case of a linked Dataset)
will be given.
This endpoint supports `ETag`, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, it returns a value in `ETag` header, you can pass this value in the header `If-None-Match` of subsequent requests. If the file has not been changed since the previous request, you will receive `304 Not Modified` response otherwise you'll get the latest file.
operationId: Downloading a Draft Form Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: filename
in: path
description: The name of tha attachment.
required: true
schema:
type: string
example: people.csv
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
ETag:
schema:
type: string
description: content version identifier
content:
'{the MIME type of the attachment file itself or text/csv for a Dataset}':
example: |
(binary data)
403:
description: Forbidden
content:
'{the MIME type of the attachment file itself or text/csv for a Dataset}':
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Draft Form
summary: Uploading a Draft Form Attachment
description: |-
To upload a binary to an expected file slot, `POST` the binary to its endpoint. Supply a `Content-Type` MIME-type header if you have one.
As of version 2022.3, if there is already a Dataset linked to this attachment, it will be unlinked and replaced with the uploaded file.
operationId: Uploading a Draft Form Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: filename
in: path
description: The name of that attachment.
required: true
schema:
type: string
example: people.csv
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Draft Form
summary: Clearing a Draft Form Attachment
description: Because Form Attachments are completely determined by the XForms
definition of the form itself, there is no direct way to entirely remove a
Form Attachment entry from the list, only to clear its uploaded content or
to unlink the Dataset. Thus, when you issue a `DELETE` to the attachment's
endpoint, that is what happens.
operationId: Clearing a Draft Form Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: filename
in: path
description: The name of tha attachment.
required: true
schema:
type: string
example: people.csv
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
patch:
tags:
- Draft Form
summary: Linking a Dataset to a Draft Form Attachment
description: |-
_(introduced: version 2022.3)_
This endpoint can update a Form Attachment's link to a Dataset. You can use this to link or unlink a Dataset to a Form Attachment. Linking of a Dataset to the Attachment only happens if the Attachment type is `file` and there is a Dataset with the exact name of the Attachment (excluding extension `.csv`) in the Project. For example, if the Form definition includes an Attachment named `people.csv`, then it can be linked to a Dataset named `people`. Pay special attention to letter case and spaces.
When linking a Dataset, if there is any existing file attached then it will be removed.
operationId: Linking a Dataset to a Draft Form Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: filename
in: path
description: The name of the attachment.
required: true
schema:
type: string
example: people.csv
requestBody:
content:
'*/*':
schema:
$ref: '#/components/schemas/PatchAttachment'
required: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
404:
description: Not Found
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "404.1"
message: Could not find the resource you were looking for.
x-codegen-request-body-name: body
/v1/projects/{projectId}/forms/{xmlFormId}/draft/fields:
get:
tags:
- Draft Form
summary: Getting Draft Form Schema Fields
description: Identical to the [same request](/central-api-form-management/#getting-form-schema-fields)
for the published Form, but will return the fields related to the current
Draft version.
operationId: Getting Draft Form Schema Fields
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: odata
in: query
description: If set to `true`, will sanitize field names.
schema:
type: boolean
example: "false"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
example:
- name: meta
path: /meta
type: structure
- name: instanceID
path: /meta/instanceID
type: string
- name: name
path: /name
type: string
- name: age
path: /age
type: int
- name: photo
path: /photo
type: binary
binary: true
items:
required:
- name
- path
- type
type: object
properties:
name:
type: string
path:
type: string
type:
type: string
binary:
type: boolean
example:
- name: meta
path: /meta
type: structure
- name: instanceID
path: /meta/instanceID
type: string
- name: name
path: /name
type: string
- name: age
path: /age
type: int
- name: photo
path: /photo
type: binary
binary: true
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft/publish:
post:
tags:
- Draft Form
summary: Publishing a Draft Form
description: |-
This will publish your current Draft Form and make it the active Form definition (and attachments).
If your Draft `version` conflicts with an older version of the Form, you will get an error.
If you wish for the `version` to be set on your behalf as part of the publish operation, you can provide the new version string as a querystring parameter `?version`.
Once the Draft is published, there will no longer be a Draft version of the form.
Starting with Version 2022.3, publishing a Draft Form that defines a Dataset schema will also publish the Dataset. It will generate `dataset.create` event in Audit logs and make the Dataset available in [Datasets APIs](/central-api-dataset-management). If the Dataset is already published and the Form adds new properties then `dataset.update` event will be generated.
operationId: Publishing a Draft Form
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: version
in: query
description: The `version` to be associated with the Draft once it's published.
schema:
type: string
example: newVersion
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
409:
description: Conflict
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "409.1"
message: A resource already exists with id value(s) of 1.
/v1/projects/{projectId}/forms/{xmlFormId}/versions:
get:
tags:
- Published Form Versions
summary: Listing Published Form Versions
description: |-
Each entry of the version listing will contain some of the same duplicate keys with basic information about the Form: `xmlFormId` and `createdAt`, for example. This is done to match the data you'd receive if you'd requested each version separately.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to additionally retrieve the `Actor` that each version was `publishedBy`.
operationId: Listing Published Form Versions
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: Ok
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Form'
example:
- projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedFormVersion'
example:
- projectId: 1
xmlFormId: simple
name: Simple
version: "2.1"
enketoId: abcdef
hash: 51a93eab3a1974dbffc4c7913fa5a16a
keyId: 3
state: open
publishedAt: 2018-01-21T00:04:11.153Z
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
publishedBy:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json; extended:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/versions/{version}:
get:
tags:
- Published Form Versions
summary: Getting Form Version Details
description: Since the XForms specification allows blank strings as `version`s
(and Central treats the lack of a `version` as a blank string), you may run
into trouble using this resource if you have such a Form. In this case, pass
the special value `___` (three underscores) as the `version` to retrieve the
blank `version` version.
operationId: Getting Form Version Details
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: version
in: path
description: The `version` of the Form version being referenced. Pass `___`
to indicate a blank `version`.
required: true
schema:
type: string
example: one
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Form'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/versions/{version}.xml:
get:
tags:
- Published Form Versions
summary: Retrieving Form Version XML
description: To get the XML of the Form Version, add `.xml` to the end of the
request URL.
operationId: Retrieving Form Version XML
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: version
in: path
description: The `version` of the Form version being referenced. Pass `___`
to indicate a blank `version`.
required: true
schema:
type: string
example: one
responses:
200:
description: OK
content:
application/xml:
example: |
Simple
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/versions/{version}.xlsx:
get:
tags:
- Published Form Versions
summary: Retrieving Form Version XLS(X)
description: If a Form Version was created with an Excel file (`.xls` or `.xlsx`),
you can get that file back by adding `.xls` or `.xlsx` as appropriate to the
Form Version resource path.
This endpoint supports `ETag` header, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, the endpoint returns a value in `ETag` header. If you pass that value in the `If-None-Match` header of a subsequent request, then if the file has not been changed since the previous request, you will receive `304 Not Modified` response; otherwise you'll get the latest file.
operationId: Retrieving Form Version XLS(X)
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: version
in: path
description: The `version` of the Form version being referenced. Pass `___`
to indicate a blank `version`.
required: true
schema:
type: string
example: one
responses:
200:
description: OK
headers:
ETag:
schema:
type: string
description: content version identifier
content:
application/xml:
example: |
(binary data)
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/versions/{version}/attachments:
get:
tags:
- Published Form Versions
summary: Listing Form Version Attachments
description: Attachments are specific to each version of a Form. You can retrieve
the attachments associated with a given version here.
operationId: Listing Form Version Attachments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: version
in: path
description: The `version` of the Form version being referenced. Pass `___`
to indicate a blank `version`.
required: true
schema:
type: string
example: one
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/FormAttachment'
example:
- name: myfile.mp3
type: image
exists: true
blobExists: true
datasetExists: true
updatedAt: 2018-03-21T12:45:02.312Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/versions/{version}/attachments/{filename}:
get:
tags:
- Published Form Versions
summary: Downloading a Form Version Attachment
description: |-
To download a single file, use this endpoint. The appropriate `Content-Disposition` (attachment with a filename) and `Content-Type` (based on the type supplied at upload time) will be given.
This endpoint supports `ETag` header, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, the endpoint returns a value in `ETag` header. If you pass that value in the `If-None-Match` header of a subsequent request, then if the file has not been changed since the previous request, you will receive `304 Not Modified` response; otherwise you'll get the latest file.
operationId: Downloading a Form Version Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: version
in: path
description: The `version` of the Form version being referenced. Pass `___`
to indicate a blank `version`.
required: true
schema:
type: string
example: one
- name: filename
in: path
description: The name of tha attachment.
required: true
schema:
type: string
example: people.csv
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
ETag:
schema:
type: string
description: content version identifier
content:
"{the MIME type of the attachment file itself}":
schema:
type: object
example: (binary data)
304:
description: Not Modified
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/versions/{version}/fields:
get:
tags:
- Published Form Versions
summary: Getting Form Version Schema Fields
description: Identical to the [same request](/central-api-form-management/#getting-form-schema-fields)
for the published Form, but will return the fields related to the specified
version.
operationId: Getting Form Version Schema Fields
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: version
in: path
description: The `version` of the Form version being referenced. Pass `___`
to indicate a blank `version`.
required: true
schema:
type: string
example: one
- name: odata
in: query
description: If set to `true`, will sanitize field names.
schema:
type: boolean
example: "false"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
example:
- name: meta
path: /meta
type: structure
- name: instanceID
path: /meta/instanceID
type: string
- name: name
path: /name
type: string
- name: age
path: /age
type: int
- name: photo
path: /photo
type: binary
binary: true
items:
required:
- name
- path
- type
type: object
properties:
name:
type: string
path:
type: string
type:
type: string
binary:
type: boolean
example:
- name: meta
path: /meta
type: structure
- name: instanceID
path: /meta/instanceID
type: string
- name: name
path: /name
type: string
- name: age
path: /age
type: int
- name: photo
path: /photo
type: binary
binary: true
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/assignments:
get:
tags:
- Form Assignments
summary: Listing all Form Assignments
description: |-
This will list every assignment upon this Form, in the form of `actorId`/`roleId` pairs.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to expand the `actorId` into a full `actor` objects. The Role reference remains a numeric ID.
operationId: Listing all Form Assignments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "2"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Assignment'
example:
- actorId: 115
roleId: 4
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedAssignment'
example:
- actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
roleId: 4
403:
description: Forbidden
content:
application/json; extended:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/assignments/{roleId}:
get:
tags:
- Form Assignments
summary: Listing all Actors assigned some Form Role
description: Given a `roleId`, which may be a numeric ID or a string role `system`
name, this endpoint lists all `Actors` that have been assigned that Role upon
this particular Form.
operationId: Listing all Actors assigned some Form Role
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: manager
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Actor'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/assignments/{roleId}/{actorId}:
post:
tags:
- Form Assignments
summary: Assigning an Actor to a Form Role
description: |-
Given a `roleId`, which may be a numeric ID or a string role `system` name, and a numeric `actorId`, assigns that Role to that Actor for this particular Form.
No `POST` body data is required, and if provided it will be ignored.
operationId: Assigning an Actor to a Form Role
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: manager
- name: actorId
in: path
description: The integer ID of the `Actor`.
required: true
schema:
type: number
example: "14"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content: {}
delete:
tags:
- Form Assignments
summary: Revoking a Form Role Assignment from an Actor
description: Given a `roleId`, which may be a numeric ID or a string role `system`
name, and a numeric `actorId`, unassigns that Role from that Actor for this
particular Form.
operationId: Revoking a Form Role Assignment from an Actor
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: roleId
in: path
description: Typically the integer ID of the `Role`. You may also supply the
Role `system` name if it has one.
required: true
schema:
type: string
example: manager
- name: actorId
in: path
description: The integer ID of the `Actor`.
required: true
schema:
type: number
example: "14"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/public-links:
get:
tags:
- Public Access Links
summary: Listing all Links
description: |-
This will list every Public Access Link upon this Form.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to retrieve the Actor the Link was `createdBy`.
operationId: Listing all Links
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "2"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PublicLink'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: Public Survey
id: 115
type: public_link
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
token: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
once: false
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedPublicLink'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: Public Survey
id: 115
type: public_link
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
token: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
once: false
createdBy:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
post:
tags:
- Public Access Links
summary: Creating a Link
description: 'To create a new Public Access Link to this Form, you must send
at least a `displayName` for the resulting Actor. You may also provide `once:
true` if you want to create a link that [can only be filled by each respondent
once](https://blog.enketo.org/single-submission-surveys/). This setting is
enforced by Enketo using local device tracking; the link is still distributable
to multiple recipients, and the enforcement can be defeated by using multiple
browsers or devices.'
operationId: Creating a Link
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "2"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
requestBody:
content:
'*/*':
schema:
required:
- displayName
type: object
properties:
displayName:
type: string
description: The name of the Link, for keeping track of. This name
is displayed on the Central administration website but not to
survey respondents.
once:
type: boolean
description: If set to `true`, an Enketo [single submission survey](https://blog.enketo.org/single-submission-surveys/)
will be created instead of a standard one, limiting respondents
to a single submission each.
example:
displayName: my public link
once: false
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- displayName
- id
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be `user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
token:
type: string
description: If present, this is the Token to include as the `st`
query parameter for this `Public Link`. If not present, this
`Public Link` has been revoked.
once:
type: boolean
description: If set to `true`, an Enketo [single submission survey](https://blog.enketo.org/single-submission-surveys/)
will be created instead of a standard one, limiting respondents
to a single submission each.
example:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
token: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
once: false
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/projects/{projectId}/forms/{xmlFormId}/public-links/{linkId}:
delete:
tags:
- Public Access Links
summary: Deleting a Link
description: You can fully delete a link by issuing `DELETE` to its resource.
This will remove the Link from the system entirely. If instead you wish to
revoke the Link's access to prevent future submission without removing its
record entirely, you can issue [`DELETE /sessions/:token`](/central-api-authentication/#logging-out-current-session).
operationId: Deleting a Link
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: linkId
in: path
description: The numeric ID of the Link
required: true
schema:
type: integer
example: "42"
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/dataset-diff:
get:
tags:
- Related Datasets
summary: Published Form Related Datasets
description: This endpoint lists the name and Properties of a Dataset that are
affected by a Form. The list of Properties includes all published Properties
on that Dataset, but each property has the `inForm` flag to note whether or
not it will be filled in by that form.
operationId: Published Form Related Datasets
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: This is the standard response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DatasetDiff'
example:
- name: people
properties:
- name: first_name
inForm: true
/v1/projects/{projectId}/forms/{xmlFormId}/draft/dataset-diff:
get:
tags:
- Related Datasets
summary: Draft Form Dataset Diff
description: This endpoint reflects the change to a Dataset that will go into
effect once the form is Published. Like the endpoint above, it lists the Dataset
name and Properties, but it also includes the `isNew` flag on both the Dataset,
and on each individual property. This flag is true only if the Dataset/Property
is new and is going to be created by publishing the Draft Form.
operationId: Draft Form Dataset Diff
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: This is the standard response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DraftDatasetDiff'
example:
- name: people
isNew: true
properties:
- name: first_name
inForm: true
isNew: true
/v1/projects/{projectId}/forms/{xmlFormId}/submissions:
get:
tags:
- Submissions
summary: Listing all Submissions on a Form
description: |-
Currently, there are no paging or filtering options, so listing `Submission`s will get you every Submission in the system, every time.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to return a `submitter` data object alongside the `submitterId` Actor ID reference.
operationId: Listing all Submissions on a Form
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Submission'
example:
- instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedSubmission'
example:
- instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
submitter:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json; extended:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Submissions
summary: Creating a Submission
description: |-
To create a Submission by REST rather than over the [OpenRosa interface](/central-api-openrosa-endpoints/#openrosa-form-submission-api), you may `POST` the Submission XML to this endpoint. The request must have an XML `Content-Type` (`text/xml` or `application/xml`).
Unlike the OpenRosa Form Submission API, this interface does _not_ accept Submission attachments upon Submission creation. Instead, the server will determine which attachments are expected based on the Submission XML, and you may use the endpoints found in the following section to add the appropriate attachments and check the attachment status and content.
If the XML is unparseable or there is some other input problem with your data, you will get a `400` error in response. If a submission already exists with the given `instanceId`, you will get a `409` error in response.
operationId: Creating a Submission
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: deviceID
in: query
description: Optionally record a particular `deviceID` associated with this
submission. It is recorded along with the data, but Central does nothing
more with it.
schema:
type: string
example: b1628661-65ed-4cab-8e30-19c17fef2de0
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission`, given by the
Submission XML.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or `Public
Link`) that originally submitted this `Submission`.
deviceId:
type: string
description: The self-identified `deviceId` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `deviceId` will be returned here.
userAgent:
type: string
description: The self-identified `userAgent` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `userAgent` will be returned here.
reviewState:
type: string
description: The current review state of the submission.
enum:
- null
- edited
- hasIssues
- rejected
- approved
- approved
createdAt:
type: string
description: ISO date format. The time that the server received
the Submission.
updatedAt:
type: string
description: ISO date format. `null` when the Submission is first
created, then updated when the Submission's XML data or metadata
is updated.
currentVersion:
required:
- createdAt
- current
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission` version,
given by the Submission XML.
instanceName:
type: string
description: The `instanceName`, if any, given by the Submission
XML in the metadata section.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or
`Public Link`) that submitted this `Submission` version.
deviceId:
type: string
description: The self-identified `deviceId` of the device
that submitted the `Submission` version.
userAgent:
type: string
description: The self-identified `userAgent` of the device
that submitted the `Submission` version.
createdAt:
type: string
description: ISO date format. The time that the server received
the `Submission` version.
current:
type: boolean
description: Whether the version is current or not.
description: The current version of the `Submission`.
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
409:
description: Conflict
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "409.1"
message: A resource already exists with id value(s) of 1.
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}:
get:
tags:
- Submissions
summary: Getting Submission metadata
description: |-
Like how `Form`s are addressed by their XML `formId`, individual `Submission`s are addressed in the URL by their `instanceId`.
As of version 1.4, a `deviceId` and `userAgent` will also be returned with each submission. The client device may transmit these extra metadata when the data is submitted. If it does, those fields will be recognized and returned here for reference. Here, only the initial `deviceId` and `userAgent` will be reported. If you wish to see these metadata for any submission edits, including the most recent edit, you will need to [list the versions](/central-api-submission-management/#listing-versions).
As of version 2023.2, this API returns `currentVersion` that contains metadata of the most recent version of the Submission.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to return a `submitter` data object alongside the `submitterId` Actor ID reference.
operationId: Getting Submission metadata
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
$ref: '#/components/schemas/Submission'
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
application/json; extended:
schema:
$ref: '#/components/schemas/ExtendedSubmission'
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
submitter:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
301:
description: Returns 301 with URL of the specific Submission version if `instanceId` of a Submission edit is provided
content:
text/html:
example: ""
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
put:
tags:
- Submissions
summary: Updating Submission Data
description: |-
_(introduced: version 1.2)_
You can use this endpoint to submit _updates_ to an existing submission.
The `instanceId` that is submitted with the initial version of the submission is used permanently to reference that submission logically, which is to say the initial submission and all its subsequent versions. Each subsequent version will also provide its own `instanceId`. This `instanceId` becomes that particular version's identifier.
To perform an update, you need to provide in the submission XML an additional [`deprecatedID` metadata node](https://getodk.github.io/xforms-spec/#metadata) with the `instanceID` of the particular and current submission version you are replacing. If the `deprecatedID` you give is anything other than the identifier of the current version of the submission at the time the server receives it, you will get a `409 Conflict` back. You can get the current version `instanceID` by getting the [current XML of the submission](/central-api-submission-management/#retrieving-submission-xml).
The XML data you send will _replace_ the existing data entirely. All of the data must be present in the updated XML.
When you create a new submission version, any uploaded media files attached to the current version that match expected attachment names in the new version will automatically be copied over to the new version. So if you don't make any changes to media files, there is no need to resubmit them. You can get information about all the submission versions [from the `/versions` subresource](/central-api-submission-management/#submission-versions).
operationId: Updating Submission Data
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being updated.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission`, given by the
Submission XML.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or `Public
Link`) that originally submitted this `Submission`.
deviceId:
type: string
description: The self-identified `deviceId` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `deviceId` will be returned here.
userAgent:
type: string
description: The self-identified `userAgent` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `userAgent` will be returned here.
reviewState:
type: string
description: The current review state of the submission.
enum:
- null
- edited
- hasIssues
- rejected
- approved
- approved
createdAt:
type: string
description: ISO date format. The time that the server received
the Submission.
updatedAt:
type: string
description: ISO date format. `null` when the Submission is first
created, then updated when the Submission's XML data or metadata
is updated.
currentVersion:
required:
- createdAt
- current
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission` version,
given by the Submission XML.
instanceName:
type: string
description: The `instanceName`, if any, given by the Submission
XML in the metadata section.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or
`Public Link`) that submitted this `Submission` version.
deviceId:
type: string
description: The self-identified `deviceId` of the device
that submitted the `Submission` version.
userAgent:
type: string
description: The self-identified `userAgent` of the device
that submitted the `Submission` version.
createdAt:
type: string
description: ISO date format. The time that the server received
the `Submission` version.
current:
type: boolean
description: Whether the version is current or not.
description: The current version of the `Submission`.
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
409:
description: Conflict
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "409.1"
message: A resource already exists with id value(s) of 1.
patch:
tags:
- Submissions
summary: Updating Submission metadata
description: |-
Currently, the only updatable _metadata_ on a Submission is its `reviewState`. To update the submission _data_ itself, please see [Updating Submission data](/central-api-submission-management/#updating-submission-data).
Starting with Version 2022.3, changing the `reviewState` of a Submission to `approved` can create an Entity in a Dataset if the corresponding Form maps Dataset Properties to Form Fields. If an Entity is created successfully then an `entity.create` event is logged in Audit logs, else `entity.error` is logged.
operationId: Updating Submission metadata
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission`, given by the
Submission XML.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or `Public
Link`) that originally submitted this `Submission`.
deviceId:
type: string
description: The self-identified `deviceId` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `deviceId` will be returned here.
userAgent:
type: string
description: The self-identified `userAgent` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `userAgent` will be returned here.
reviewState:
type: string
description: The current review state of the submission.
enum:
- null
- edited
- hasIssues
- rejected
- approved
- approved
createdAt:
type: string
description: ISO date format. The time that the server received
the Submission.
updatedAt:
type: string
description: ISO date format. `null` when the Submission is first
created, then updated when the Submission's XML data or metadata
is updated.
currentVersion:
required:
- createdAt
- current
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission` version,
given by the Submission XML.
instanceName:
type: string
description: The `instanceName`, if any, given by the Submission
XML in the metadata section.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or
`Public Link`) that submitted this `Submission` version.
deviceId:
type: string
description: The self-identified `deviceId` of the device
that submitted the `Submission` version.
userAgent:
type: string
description: The self-identified `userAgent` of the device
that submitted the `Submission` version.
createdAt:
type: string
description: ISO date format. The time that the server received
the `Submission` version.
current:
type: boolean
description: Whether the version is current or not.
description: The current version of the `Submission`.
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}.xml:
get:
tags:
- Submissions
summary: Retrieving Submission XML
description: To get only the XML of the `Submission` rather than all of the
details with the XML as one of many properties, just add `.xml` to the end
of the request URL.
operationId: Retrieving Submission XML
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/xml:
example: |
uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44Alice32
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/edit:
get:
tags:
- Submissions
summary: Getting an Enketo Edit URL
description: |-
_(introduced: version 1.2)_
This endpoint redirects the user to an Enketo-powered page that allows the user to interactively edit the submission. Once the user is satisfied, they can perform the submission update directly through the Enketo interface.
The Enketo instance is already hosted inside of ODK Central. There is no reason to create or use a separate Enketo installation.
This endpoint is intended for use by the Central administration frontend and will not work without it. In particular, the user must be logged into the Central administration site for Enketo editing to work. If there is no Central authentication cookie present when Enketo is loaded, the browser will then be redirected by Enketo to a Central login page.
operationId: Getting an Enketo Edit URL
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being updated.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
302:
description: Found
headers:
Location:
schema:
type: string
content: {}
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions.csv.zip:
get:
tags:
- Submissions
summary: Exporting Form Submissions to CSV
description: |-
To export all the `Submission` data associated with a `Form`, just add `.csv.zip` to the end of the listing URL. The response will be a ZIP file containing one or more CSV files, as well as all multimedia attachments associated with the included Submissions.
You can exclude the media attachments from the ZIP file by specifying `?attachments=false`.
If [Project Managed Encryption](/central-api-encryption) is being used, additional querystring parameters may be provided in the format `{keyId}={passphrase}` for any number of keys (eg `1=secret&4=password`). This will decrypt any records encrypted under those managed keys. Submissions encrypted under self-supplied keys will not be decrypted. **Note**: if you are building a browser-based application, please consider the alternative `POST` endpoint, described in the following section.
If a passphrase is supplied but is incorrect, the entire request will fail. If a passphrase is not supplied but encrypted records exist, only the metadata for those records will be returned, and they will have a `status` of `not decrypted`.
If you are running an unsecured (`HTTP` rather than `HTTPS`) Central server, it is not a good idea to export data this way as your passphrase and the decrypted data will be sent plaintext over the network.
You can use an [OData-style `$filter` query](/central-api-odata-endpoints/#data-document) to filter the submissions that will appear in the ZIP file. This is a bit awkward, since this endpoint has nothing to do with OData, but since we already must recognize the OData syntax, it is less strange overall for now not to invent a whole other one here. Only a subset of the `$filter` features are available; please see the linked section for more information.
operationId: Exporting Form Submissions to CSV
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: attachments
in: query
description: Set to false to exclude media attachments from the export.
schema:
type: boolean
example: "true"
- name: '%24filter'
in: query
description: If provided, will filter responses to those matching the given
OData query. Only [certain fields](/central-api-odata-endpoints/#data-document)
are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`,
`gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`,
`year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: year(__system/submissionDate) lt year(now())
- name: groupPaths
in: query
description: Set to false to remove group path prefixes from field header
names (eg `instanceID` instead of `meta-instanceID`). This behavior mimics
a similar behavior in ODK Briefcase.
schema:
type: boolean
example: "true"
- name: deletedFields
in: query
description: Set to true to restore all fields previously deleted from this
form for this export. All known fields and data for those fields will be
merged and exported.
schema:
type: boolean
example: "false"
- name: splitSelectMultiples
in: query
description: Set to true to create a boolean column for every known select
multiple option in the export. The option name is in the field header, and
a `0` or a `1` will be present in each cell indicating whether that option
was checked for that row. This behavior mimics a similar behavior in ODK
Briefcase.
schema:
type: boolean
example: "false"
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
content: {}
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Submissions
summary: Exporting Form Submissions to CSV via POST
description: |-
This non-REST-compliant endpoint is provided for use with [Project Managed Encryption](/central-api-encryption). In every respect, it behaves identically to the `GET` endpoint described in the previous section, except that it works over `POST`. This is necessary because for browser-based applications, it is a dangerous idea to simply link the user to `/submissions.csv.zip?2=supersecretpassphrase` because the browser will remember this route in its history and thus the passphrase will become exposed. This is especially dangerous as there are techniques for quickly learning browser-visited URLs of any arbitrary domain.
You can exclude the media attachments from the ZIP file by specifying `?attachments=false`.
And so, for this `POST` version of the Submission CSV export endpoint, the passphrases may be provided via `POST` body rather than querystring. Two formats are supported: form URL encoding (`application/x-www-form-urlencoded`) and JSON. In either case, the keys should be the `keyId`s and the values should be the `passphrase`s, as with the `GET` version above.
operationId: Exporting Form Submissions to CSV via POST
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: attachments
in: query
description: Set to false to exclude media attachments from the export.
schema:
type: boolean
example: "true"
- name: '%24filter'
in: query
description: If provided, will filter responses to those matching the given
OData query. Only [certain fields](/central-api-odata-endpoints/#data-document)
are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`,
`gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`,
`year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: year(__system/submissionDate) lt year(now())
- name: groupPaths
in: query
description: Set to false to remove group path prefixes from field header
names (eg `instanceID` instead of `meta-instanceID`). This behavior mimics
a similar behavior in ODK Briefcase.
schema:
type: boolean
example: "true"
- name: deletedFields
in: query
description: Set to true to restore all fields previously deleted from this
form for this export. All known fields and data for those fields will be
merged and exported.
schema:
type: boolean
example: "false"
- name: splitSelectMultiples
in: query
description: Set to true to create a boolean column for every known select
multiple option in the export. The option name is in the field header, and
a `0` or a `1` will be present in each cell indicating whether that option
was checked for that row. This behavior mimics a similar behavior in ODK
Briefcase.
schema:
type: boolean
example: "false"
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
content: {}
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions.csv:
get:
tags:
- Submissions
summary: Exporting Root Data to Plain CSV
description: |-
_(introduced: version 1.1)_
The above submission endpoints will give you a ZIP file with the submission data in it. This is necessary to provide all the possible related repeat table files, as well as the media files associated with the submissions. But ZIP files can be difficult to work with, and many Forms have no repeats nor media attachments.
To export _just_ the root table (no repeat data nor media files), you can call this endpoint instead, which will directly give you CSV data.
Please see the [above endpoint](/central-api-submission-management/#exporting-form-submissions-to-csv) for notes on dealing with Managed Encryption.
operationId: Exporting Root Data to Plain CSV
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: '%24filter'
in: query
description: If provided, will filter responses to those matching the given
OData query. Only [certain fields](/central-api-odata-endpoints/#data-document)
are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`,
`gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`,
`year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: year(__system/submissionDate) lt year(now())
responses:
200:
description: OK
content: {}
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Submissions
summary: Exporting Root Data to Plain CSV via POST
description: |-
_(introduced: version 1.1)_
This endpoint is useful only for Forms under Project Managed Encryption.
As with `GET` to `.csv` just above, this endpoint will only return CSV text data, rather than a ZIP file containing ore or more files. Please see that endpoint for further explanation.
As with [`POST` to `.csv.zip`](/central-api-submission-management/#exporting-form-submissions-to-csv-via-post) it allows secure submission of decryption passkeys. Please see that endpoint for more information on how to do this.
operationId: Exporting Root Data to Plain CSV via POST
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: '%24filter'
in: query
description: If provided, will filter responses to those matching the given
OData query. Only [certain fields](/central-api-odata-endpoints/#data-document)
are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`,
`gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`,
`year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: year(__system/submissionDate) lt year(now())
responses:
200:
description: OK
content: {}
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/audits:
get:
tags:
- Submissions
summary: Retrieving Audit Logs
description: |-
_(introduced: version 1.2)_
You can retrieve all [Server Audit Logs](/central-api-system-endpoints/#server-audit-logs) relating to a submission. They will be returned most recent first.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to additionally expand the `actorId` into full `actor` details, and `acteeId` into full `actee` details. The `actor` will always be an Actor, and the `actee` will be the Form this Submission is a part of.
operationId: Retrieving Audit Logs
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Audit'
example:
- actorId: 42
action: form.create
acteeId: 85cb9aff-005e-4edd-9739-dc9c1a829c44
loggedAt: 2018-04-18T23:19:14.802Z
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedAudit'
example:
- actorId: 42
action: form.create
acteeId: 85cb9aff-005e-4edd-9739-dc9c1a829c44
loggedAt: 2018-04-18T23:19:14.802Z
actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/keys:
get:
tags:
- Submissions
summary: Listing Encryption Keys
description: This endpoint provides a listing of all known encryption keys needed
to decrypt all Submissions for a given Form. It will return at least the `base64RsaPublicKey`
property (as `public`) of all known versions of the form that have submissions
against them. If managed keys are being used and a `hint` was provided, that
will be returned as well.
operationId: Listing Encryption Keys
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Key'
example:
- id: 1
public: bcFeKDF3Sg8W91Uf5uxaIlsuhzmjbgUnIyiLzIjrx4CAaf9Y9LG7TAu6wKPqfbH6ZAkJTFSfjLNovbKhpOQcmO5VZGGay6yvXrX1TFW6C6RLITy74erxfUAStdtpP4nraCYqQYqn5zD4/1OmgweJt5vzGXW2ch7lrROEQhXB9lK+bjEeWx8TFW/+6ha/oRLnl6a2RBRL6mhwy3PoByNTKndB2MP4TygCJ/Ini4ivk74iSqVnoeuNJR/xUcU+kaIpZEIjxpAS2VECJU9fZvS5Gt84e5wl/t7bUKu+dlh/cUgHfk6+6bwzqGQYOe5A==
managed: true
hint: it was a secret
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/submitters:
get:
tags:
- Submissions
summary: Listing Submitters
description: This endpoint provides a listing of all known submitting actors
to a given Form. Each Actor that has submitted to the given Form will be returned
once.
operationId: Listing Submitters
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Actor'
example:
- createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/comments:
get:
tags:
- Comments
summary: Listing Comments
description: |-
Comments have only a `body` comment text and an `actor` that made the comment.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to return a `actor` data object alongside the `actorId` Actor ID reference.
operationId: Listing Comments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Comment'
example:
- body: this is my comment
actorId: 42
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedComment'
example:
- body: this is my comment
actorId: 42
actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Comments
summary: Posting Comments
description: Currently, the only accepted data is `body`, which contains the
body of the comment to be made.
operationId: Posting Comments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
requestBody:
content:
'*/*':
schema:
required:
- body
type: object
properties:
body:
type: string
description: The text of the comment.
example:
body: this is the text of my comment
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- actorId
- body
type: object
properties:
body:
type: string
description: The text of the comment.
actorId:
type: number
description: The ID of the Actor that made the comment.
example:
body: this is my comment
actorId: 42
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/attachments:
get:
tags:
- Attachments
summary: Listing expected Submission Attachments
description: You can retrieve the list of expected Submission attachments at
this route, along with a boolean flag indicating whether the server actually
has a copy of the expected file or not. If the server has a file, you can
then append its filename to the request URL to download only that file (see
below).
operationId: Listing expected Submission Attachments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SubmissionAttachment'
example:
- name: file1.jpg
exists: true
- name: file2.jpg
exists: false
- name: file3.jpg
exists: true
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/attachments/{filename}:
get:
tags:
- Attachments
summary: Downloading an Attachment
description: The `Content-Type` and `Content-Disposition` will be set appropriately
based on the file itself when requesting an attachment file download.
This endpoint supports `ETag`, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, it returns a value in `ETag` header, you can pass this value in the header `If-None-Match` of subsequent requests. If the file has not been changed since the previous request, you will receive `304 Not Modified` response otherwise you'll get the latest file.
operationId: Downloading an Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
ETag:
schema:
type: string
description: content version identifier
content:
'{the MIME type of the attachment file itself}':
example: |
(binary data)
403:
description: Forbidden
content:
'{the MIME type of the attachment file itself}':
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Attachments
summary: Uploading an Attachment
description: |-
_(introduced: version 0.4)_
To upload a binary to an expected file slot, `POST` the binary to its endpoint. Supply a `Content-Type` MIME-type header if you have one.
operationId: Uploading an Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Attachments
summary: Clearing a Submission Attachment
description: |-
_(introduced: version 0.4)_
Because Submission Attachments are completely determined by the XML data of the submission itself, there is no direct way to entirely remove a Submission Attachment entry from the list, only to clear its uploaded content. Thus, when you issue a `DELETE` to the attachment's endpoint, that is what happens.
operationId: Clearing a Submission Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/versions:
get:
tags:
- Submission Versions
summary: Listing Versions
description: |-
This will return all submission metadata for every version of this submission, in descending creation order.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to return a `submitter` data object alongside the `submitterId` Actor ID reference.
operationId: Listing Versions
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the initially submitted version. Please see
the notes at the top of this documentation section for more information.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SubmissionVersion'
example:
- instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
formVersion: "1.0"
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedSubmissionVersion'
example:
- instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
submitter:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
formVersion: "1.0"
403:
description: Forbidden
content:
application/json; extended:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/versions/{versionId}:
get:
tags:
- Submission Versions
summary: Getting Version Details
description: |-
Returns metadata about a particular version of the submission. As with the normal submission endpoint, you'll only get metadata in JSON out of this route. If you want to retrieve the XML, [add `.xml`](/central-api-submission-management/#getting-version-xml).
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to return a `submitter` data object alongside the `submitterId` Actor ID reference.
operationId: Getting Version Details
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: versionId
in: path
description: The `instanceId` of the particular version of this submission
in question.
required: true
schema:
type: string
example: uuid:b1628661-65ed-4cab-8e30-19c17fef2de0
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
$ref: '#/components/schemas/SubmissionVersion'
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
formVersion: "1.0"
application/json; extended:
schema:
$ref: '#/components/schemas/ExtendedSubmissionVersion'
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
submitter:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
formVersion: "1.0"
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/versions/{versionId}.xml:
get:
tags:
- Submission Versions
summary: Getting Version XML
description: Returns the XML of a particular version of the submission.
operationId: Getting Version XML
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: versionId
in: path
description: The `instanceId` of the particular version of this submission
in question.
required: true
schema:
type: string
example: uuid:b1628661-65ed-4cab-8e30-19c17fef2de0
responses:
200:
description: OK
content:
application/xml:
example: |
uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44Alice32
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/versions/{versionId}/attachments:
get:
tags:
- Submission Versions
summary: Listing Version expected Attachments
description: You can retrieve the list of expected Submission attachments for
the given version at this route, along with a boolean flag indicating whether
the server actually has a copy of the expected file or not. If the server
has a file, you can then append its filename to the request URL to download
only that file (see below).
operationId: Listing Version expected Attachments
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: versionId
in: path
description: The `instanceId` of the particular version of this submission
in question.
required: true
schema:
type: string
example: uuid:b1628661-65ed-4cab-8e30-19c17fef2de0
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SubmissionAttachment'
example:
- name: file1.jpg
exists: true
- name: file2.jpg
exists: false
- name: file3.jpg
exists: true
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/versions/{versionId}/attachments/{filename}:
get:
tags:
- Submission Versions
summary: Downloading a Version's Attachment
description: It is important to note that this endpoint returns whatever is
_currently_ uploaded against the _particular version_ of the _Submission_.
It will not track overwritten attachments.
This endpoint supports `ETag`, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, it returns a value in `ETag` header, you can pass this value in the header `If-None-Match` of subsequent requests. If the file has not been changed since the previous request, you will receive `304 Not Modified` response otherwise you'll get the latest file.
operationId: Downloading a Version's Attachment
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: versionId
in: path
description: The `instanceId` of the particular version of this submission
in question.
required: true
schema:
type: string
example: uuid:b1628661-65ed-4cab-8e30-19c17fef2de0
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
ETag:
schema:
type: string
description: content version identifier
content:
'{the MIME type of the attachment file itself}':
example: |
(binary data)
403:
description: Forbidden
content:
'{the MIME type of the attachment file itself}':
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/submissions/{instanceId}/diffs:
get:
tags:
- Submission Versions
summary: Getting changes between Versions
description: This returns the changes, or edits, between different versions
of a Submission. These changes are returned in an object that is indexed by
the `instanceId` that uniquely identifies that version. Between two submissions,
there is an array of objects representing how each field changed. This change
object contains the old and new values, as well as the path of that changed
node in the Submission XML. These changes reflect the updated `instanceID`
and `deprecatedID` fields as well as the edited value.
operationId: Getting changes between Versions
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
type: array
items:
$ref: '#/components/schemas/SubmissionDiffValue'
example:
two:
- new: Donna
old: Dana
path:
- name
- new: '55'
old: '44'
path:
- age
- new: two
old: one
path:
- meta
- instanceID
- new: one
old:
path:
- meta
- deprecatedID
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft/submissions:
get:
tags:
- Draft Submissions
summary: Listing all Submissions on a Draft Form
description: Identical to [the non-Draft version](/central-api-submission-management/#listing-all-submissions-on-a-form)
of this endpoint.
operationId: Listing all Submissions on a Draft Form
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `id` of this form as given in its XForms XML definition
required: true
schema:
type: string
example: simple
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Submission'
example:
- instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedSubmission'
example:
- instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
submitter:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Draft Submissions
summary: Creating a Submission
description: Identical to [the non-Draft version](/central-api-submission-management/#creating-a-submission)
of this endpoint.
operationId: Creating a Submission for a draft Form
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
required:
- createdAt
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission`, given by the
Submission XML.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or `Public
Link`) that originally submitted this `Submission`.
deviceId:
type: string
description: The self-identified `deviceId` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `deviceId` will be returned here.
userAgent:
type: string
description: The self-identified `userAgent` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `userAgent` will be returned here.
reviewState:
type: string
description: The current review state of the submission.
enum:
- null
- edited
- hasIssues
- rejected
- approved
- approved
createdAt:
type: string
description: ISO date format. The time that the server received
the Submission.
updatedAt:
type: string
description: ISO date format. `null` when the Submission is first
created, then updated when the Submission's XML data or metadata
is updated.
currentVersion:
required:
- createdAt
- current
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission` version,
given by the Submission XML.
instanceName:
type: string
description: The `instanceName`, if any, given by the Submission
XML in the metadata section.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or
`Public Link`) that submitted this `Submission` version.
deviceId:
type: string
description: The self-identified `deviceId` of the device
that submitted the `Submission` version.
userAgent:
type: string
description: The self-identified `userAgent` of the device
that submitted the `Submission` version.
createdAt:
type: string
description: ISO date format. The time that the server received
the `Submission` version.
current:
type: boolean
description: Whether the version is current or not.
description: The current version of the `Submission`.
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
409:
description: Conflict
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "409.1"
message: A resource already exists with id value(s) of 1.
/v1/projects/{projectId}/forms/{xmlFormId}/draft/submissions.csv.zip:
get:
tags:
- Draft Submissions
summary: Exporting Form Submissions to CSV
description: Identical to [the non-Draft version](/central-api-submission-management/#exporting-form-submissions-to-csv)
of this endpoint.
operationId: Exporting Form(Draft) Submissions to CSV
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
content: {}
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Draft Submissions
summary: Exporting Form Submissions to CSV via POST
description: Identical to [the non-Draft version](/central-api-submission-management/#exporting-form-submissions-to-csv-via-post)
of this endpoint.
operationId: Exporting Form(Draft) Submissions to CSV via POST
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
content: {}
400:
description: Bad Request
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
details:
type: object
properties: {}
description: a subobject that contains programmatically readable
details about this error
message:
type: string
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft/submissions/keys:
get:
tags:
- Draft Submissions
summary: Listing Encryption Keys
description: Identical to [the non-Draft version](/central-api-submission-management/#listing-encryption-keys)
of this endpoint.
operationId: Listing Encryption Keys (Draft Form)
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Key'
example:
- id: 1
public: bcFeKDF3Sg8W91Uf5uxaIlsuhzmjbgUnIyiLzIjrx4CAaf9Y9LG7TAu6wKPqfbH6ZAkJTFSfjLNovbKhpOQcmO5VZGGay6yvXrX1TFW6C6RLITy74erxfUAStdtpP4nraCYqQYqn5zD4/1OmgweJt5vzGXW2ch7lrROEQhXB9lK+bjEeWx8TFW/+6ha/oRLnl6a2RBRL6mhwy3PoByNTKndB2MP4TygCJ/Ini4ivk74iSqVnoeuNJR/xUcU+kaIpZEIjxpAS2VECJU9fZvS5Gt84e5wl/t7bUKu+dlh/cUgHfk6+6bwzqGQYOe5A==
managed: true
hint: it was a secret
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft/submissions/{instanceId}:
get:
tags:
- Draft Submissions
summary: Getting Submission details
description: Identical to [the non-Draft version](/central-api-submission-management/#getting-submission-metadata)
of this endpoint.
operationId: Getting Submission details
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: 'This is the Extended Metadata response, if requested via the
appropriate header:'
content:
application/json; extended:
schema:
required:
- createdAt
- instanceId
- submitter
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission`, given by the
Submission XML.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or `Public
Link`) that originally submitted this `Submission`.
deviceId:
type: string
description: The self-identified `deviceId` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `deviceId` will be returned here.
userAgent:
type: string
description: The self-identified `userAgent` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `userAgent` will be returned here.
reviewState:
type: string
description: The current review state of the submission.
enum:
- null
- edited
- hasIssues
- rejected
- approved
- approved
createdAt:
type: string
description: ISO date format. The time that the server received
the Submission.
updatedAt:
type: string
description: ISO date format. `null` when the Submission is first
created, then updated when the Submission's XML data or metadata
is updated.
currentVersion:
required:
- createdAt
- current
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission` version,
given by the Submission XML.
instanceName:
type: string
description: The `instanceName`, if any, given by the Submission
XML in the metadata section.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or
`Public Link`) that submitted this `Submission` version.
deviceId:
type: string
description: The self-identified `deviceId` of the device
that submitted the `Submission` version.
userAgent:
type: string
description: The self-identified `userAgent` of the device
that submitted the `Submission` version.
createdAt:
type: string
description: ISO date format. The time that the server received
the `Submission` version.
current:
type: boolean
description: Whether the version is current or not.
description: The current version of the `Submission`.
submitter:
required:
- createdAt
- displayName
- id
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be
`user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
description: The full details of the `Actor` that submitted this
`Submission`.
example:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
reviewState: approved
createdAt: 2018-01-19T23:58:03.395Z
updatedAt: 2018-03-21T12:45:02.312Z
currentVersion:
instanceId: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
instanceName: village third house
submitterId: 23
deviceId: imei:123456
userAgent: Enketo/3.0.4
createdAt: 2018-01-19T23:58:03.395Z
current: true
submitter:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
application/json:
schema:
required:
- createdAt
- instanceId
- submitter
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission`, given by the
Submission XML.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or `Public
Link`) that originally submitted this `Submission`.
deviceId:
type: string
description: The self-identified `deviceId` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `deviceId` will be returned here.
userAgent:
type: string
description: The self-identified `userAgent` of the device that
collected the data, sent by it upon submission to the server.
The initial submission `userAgent` will be returned here.
reviewState:
type: string
description: The current review state of the submission.
enum:
- null
- edited
- hasIssues
- rejected
- approved
- approved
createdAt:
type: string
description: ISO date format. The time that the server received
the Submission.
updatedAt:
type: string
description: ISO date format. `null` when the Submission is first
created, then updated when the Submission's XML data or metadata
is updated.
currentVersion:
required:
- createdAt
- current
- instanceId
- submitterId
type: object
properties:
instanceId:
type: string
description: The `instanceId` of the `Submission` version,
given by the Submission XML.
instanceName:
type: string
description: The `instanceName`, if any, given by the Submission
XML in the metadata section.
submitterId:
type: number
description: The ID of the `Actor` (`App User`, `User`, or
`Public Link`) that submitted this `Submission` version.
deviceId:
type: string
description: The self-identified `deviceId` of the device
that submitted the `Submission` version.
userAgent:
type: string
description: The self-identified `userAgent` of the device
that submitted the `Submission` version.
createdAt:
type: string
description: ISO date format. The time that the server received
the `Submission` version.
current:
type: boolean
description: Whether the version is current or not.
description: The current version of the `Submission`.
submitter:
required:
- createdAt
- displayName
- id
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
displayName:
type: string
description: All `Actor`s, regardless of type, have a display
name
id:
type: number
type:
type: string
description: the Type of this Actor; typically this will be
`user`.
enum:
- user
- field_key
- public_link
- singleUse
updatedAt:
type: string
description: ISO date format
deletedAt:
type: string
description: ISO date format
description: The full details of the `Actor` that submitted this
`Submission`.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}/draft/submissions/{instanceId}.xml:
get:
tags:
- Draft Submissions
summary: Retrieving Submission XML
description: Identical to [the non-Draft version](/central-api-submission-management/#retrieving-submission-xml)
of this endpoint.
operationId: Retrieving Submission XML (Draft Form)
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/xml:
example: |
uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44Alice32
/v1/projects/{projectId}/forms/{xmlFormId}/draft/submissions/{instanceId}/attachments:
get:
tags:
- Draft Submissions
summary: Listing expected Submission Attachments
description: Identical to [the non-Draft version](/central-api-submission-management/#listing-expected-submission-attachments)
of this endpoint.
operationId: Listing expected Submission Attachments (Draft Form)
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/SubmissionAttachment"
example:
- name: file1.jpg
exists: true
- name: file2.jpg
exists: false
- name: file3.jpg
exists: true
403:
description: Forbidden
content:
application/json:
schema:
$ref: "#/components/schemas/Error403"
/v1/projects/{projectId}/forms/{xmlFormId}/draft/submissions/{instanceId}/attachments/{filename}:
get:
tags:
- Draft Submissions
summary: Downloading an Attachment
description: Identical to [the non-Draft version](/central-api-submission-management/#downloading-an-attachment)
of this endpoint.
operationId: Downloading an Attachment (Draft Form)
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
content:
'{the MIME type of the attachment file itself}':
example: |
(binary data)
403:
description: Forbidden
content:
'{the MIME type of the attachment file itself}':
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Draft Submissions
summary: Uploading an Attachment
description: Identical to [the non-Draft version](/central-api-submission-management/#uploading-an-attachment)
of this endpoint.
operationId: Uploading an Attachment (Form Draft)
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Draft Submissions
summary: Clearing a Submission Attachment
description: Identical to [the non-Draft version](/central-api-submission-management/#clearing-a-submission-attachment)
of this endpoint.
operationId: Clearing a Submission Attachment (Form Draft)
parameters:
- name: projectId
in: path
description: The `id` of the project this form belongs to.
required: true
schema:
type: number
example: "1"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/projects/{projectId}/datasets:
get:
tags:
- Dataset Management
summary: Listing Datasets
description: The Dataset listing endpoint returns all published Datasets in a Project. If a Draft Form defines a new Dataset, that Dataset will not be included in this list until the Form is published.
operationId: Listing Datasets
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Dataset'
example:
- name: people
createdAt: '2018-01-19T23:58:03.395Z'
projectId: 1
approvalRequired: true
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedDataset'
example:
- name: people
createdAt: '2018-01-19T23:58:03.395Z'
projectId: 1
approvalRequired: true
lastEntity: '2018-04-18T03:04:51.695Z'
entities: 10
conflicts: 2
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Dataset Management
summary: Creating Datasets
description: |-
You can create a Dataset with a specific `name` within a Project. This Dataset can then be populated with Entities via the API or via Forms and Submissions, and then used by other Forms. This endpoint allows a Dataset to be created programatically without an input form.
The name of a Dataset is case-sensitive in that it will keep the capitalization provided (e.g. "Trees"). But Central will not allow a second Dataset with the same name but different capitalization to be created (e.g. "trees" when "Trees" already exists).
By default, the Dataset will have no properties, but each Entity will have a `label` and a unique ID (`uuid`). You can add additional properties with this [related endpoint](/central-api-dataset-management/#adding-properties).
The Dataset name must follow the the same rules as XML identifiers and not start with `.` or `__`. See the [Entities XForms Specification](https://getodk.github.io/xforms-spec/entities.html#declaring-that-a-form-creates-entities) for more information.
operationId: Creating Datasets
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
requestBody:
content:
'*/*':
schema:
required:
- name
type: object
properties:
name:
type: string
description: The desired name of the Dataset. Must be a valid
approvalRequired:
type: boolean
description: Control whether a Submission should be approved before an Entity is created from it.
required: false
example:
name: Trees
approvalRequired: false
required: false
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DatasetMetadata'
example:
name: people
createdAt: '2018-01-19T23:58:03.395Z'
projectId: 1
approvalRequired: false
sourceForms: []
linkedForms: []
properties: []
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
409:
description: Conflict
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: number
message:
type: string
example:
code: 409.3
message: A resource already exists with name,projectId value(s) of trees,1.
/projects/{projectId}/datasets/{name}:
get:
tags:
- Dataset Management
summary: Dataset Metadata
description: Returns the metadata of a published Dataset including properties and forms
that create and consume the Dataset.
operationId: Dataset Metadata
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DatasetMetadata'
example:
name: people
createdAt: '2018-01-19T23:58:03.395Z'
projectId: 1
approvalRequired: true
sourceForms:
- xmlFormId: treeRegistration
name: Tree Registration
linkedForms:
- xmlFormId: simple
name: Simple
properties:
- name: the.age
odataName: the_age
publishedAt: '2018-01-21T00:04:11.153Z'
forms:
- xmlFormId: simple
name: Simple
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
patch:
tags:
- Dataset Management
summary: Update Dataset Metadata
operationId: Update Dataset Metadata
description: |-
You can only update `approvalRequired` using this endpoint. `approvalRequired` flag controls the Entity creation flow; if it is `true` then the Submission must be approved before an Entity can be created from it and if it is `false` then an Entity is created as soon as the Submission is received by the ODK Central.
By default `approvalRequired` is `false` for the Datasets created after v2023.3. Datasets created prior to that will have `approvalRequired` set to `true`.
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
requestBody:
content:
'application/json':
schema:
type: object
properties:
approvalRequired:
type: boolean
description: Control whether a Submission should be approved before an Entity is created from it.
example: true
example:
approvalRequired: true
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DatasetMetadata'
example:
name: people
createdAt: '2018-01-19T23:58:03.395Z'
projectId: 1
approvalRequired: true
sourceForms:
- xmlFormId: treeRegistration
name: Tree Registration
linkedForms:
- xmlFormId: simple
name: Simple
properties:
- name: the.age
odataName: the_age
publishedAt: '2018-01-21T00:04:11.153Z'
forms:
- xmlFormId: simple
name: Simple
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/projects/{projectId}/datasets/{name}/properties:
post:
tags:
- Dataset Management
summary: Adding Properties
description: |-
Creates a new Property with a specified name in the Dataset.
Property names follow the same rules as form field names (valid XML identifiers) and cannot use the reserved names of `name` or `label`, or begin with the reserved prefix `__`.
operationId: Adding Properties
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
requestBody:
content:
'*/*':
schema:
required:
- name
type: object
properties:
name:
type: string
description: The desired name of the Property.
example:
name: circumference
required: false
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/projects/{projectId}/datasets/{name}/entities.csv:
get:
tags:
- Dataset Management
summary: Download Dataset
description: |-
Datasets (collections of Entities) can be used as Attachments in other Forms, but they can also be downloaded directly as a CSV file.
The CSV format closely matches the [OData Dataset Service](/central-api-odata-endpoints/#odata-dataset-service) format, with columns for system properties such as `__id` (the Entity UUID), `__createdAt`, `__creatorName`, etc., the Entity Label `label`, and the Dataset/Entity Properties themselves. If any Property for an given Entity is blank (e.g. it was not captured by that Form or was left blank), that field of the CSV is blank.
The `$filter` querystring parameter can be used to filter on system-level properties, similar to how filtering in the [OData Dataset Service](/central-api-odata-endpoints/#odata-dataset-service) works.
This endpoint supports `ETag` header, which can be used to avoid downloading the same content more than once. When an API consumer calls this endpoint, the endpoint returns a value in the ETag header. If you pass that value in the If-None-Match header of a subsequent request, then if the Dataset has not been changed since the previous request, you will receive `304 Not Modified` response; otherwise you'll get the new data.
operationId: Download Dataset
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: $filter
in: query
description: If provided, will filter responses to those matching the query. Only system-level Entity fields are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`, `gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`, `year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: __system/conflict eq \'hard\'
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
ETag:
schema:
type: string
description: content version identifier
content:
text/csv:
example: |
__id,label,geometry,species,circumference_cm,__createdAt,__creatorId,__creatorName,__updates,__updatedAt,__version
2c1ee90b-dde8-434b-9985-2eefd8465339,666cm purpleheart,-29.281608 -67.624883 0 0,purpleheart,667,2023-05-31T19:49:28.902Z,22,Alice,1,2023-05-31T19:52:34.467Z,1
84ac3a03-9980-4098-93a5-b81fdc6ea749,555cm wallaba,18.921876 77.309451 0 0,wallaba,555,2023-05-31T19:49:20.152Z,22,Alice,0,,1
403:
description: Forbidden
content:
text/csv:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/projects/{projectId}/datasets/{name}/entities:
get:
tags:
- Entity Management
summary: Entities Metadata
description: |-
This endpoint returns a list of the Entities of a Dataset. Please note that this endpoint only returns metadata of the entities not the data. If you want to get the data of all entities then please refer to [OData Dataset Service](/central-api-odata-endpoints/#odata-form-service)
You can provide `?deleted=true` to get only deleted entities.
operationId: Entities Metadata
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
responses:
200:
description: OK
content:
application/json:
schema:
type: array
description: Standard Response
items:
$ref: '#/components/schemas/EntitySummary'
example:
- uuid: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
createdAt: '2018-01-19T23:58:03.395Z'
updatedAt: '2018-03-21T12:45:02.312Z'
deletedAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
currentVersion:
label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
version: 1
baseVersion: null
conflictingProperties: null
application/json; extended:
schema:
type: array
description: Extended Response
items:
$ref: '#/components/schemas/ExtendedEntitySummary'
example:
- uuid: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
createdAt: '2018-01-19T23:58:03.395Z'
updatedAt: '2018-03-21T12:45:02.312Z'
deletedAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
conflict: null
creator:
createdAt: '2018-04-18T23:19:14.802Z'
displayName: My Display Name
id: 115
type: user
updatedAt: '2018-04-18T23:42:11.406Z'
deletedAt: '2018-04-18T23:42:11.406Z'
currentVersion:
label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
version: 1
baseVersion: null
conflictingProperties: null
creator:
createdAt: '2018-04-18T23:19:14.802Z'
displayName: My Display Name
id: 115
type: user
updatedAt: '2018-04-18T23:42:11.406Z'
deletedAt: '2018-04-18T23:42:11.406Z'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
post:
tags:
- Entity Management
summary: Creating Entities
description: |-
Creates one or more Entities in the Dataset.
For creating **a single Entity**, the request body takes a JSON representation of the Entity, which has the following properties:
1. A `data` object containing values for the user-defined Dataset properties. (Not all properties have to have values.)
2. A `label` property, which cannot be blank or an empty string. (This is used as a human-readable label in Forms that consume Entities.)
3. An optional `uuid` property. If the `uuid` is not specified, Central will generate a UUID for an Entity with the provided data and label.
`
{
"label": "John Doe",
"data": {
"firstName": "John",
"age": "22"
}
}
`
The value type of all properties is `string`.
For creating **multiple Entities** in bulk, the request body takes an array `entities` containing a list of Entity objects as described above. The bulk entity version also takes a `source` property with a required `name` field and optional `size`, for example to capture the filename and size of a bulk upload source.
`
{
"entities": [...], "source": {"name": "file.csv", "size": 100}
}
`
You can provide header `X-Action-Notes` to store the metadata about the request. The metadata can retrieved using [Entity Audit Log](/central-api-entity-management/#entity-audit-log)
operationId: Creating an Entity
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
requestBody:
content:
'*/*':
schema:
oneOf:
- $ref: '#/components/schemas/EntityCreateSingle'
- $ref: '#/components/schemas/EntityCreateBulk'
example:
entities:
-
uuid: 54a405a0-53ce-4748-9788-d23a30cc3afa
label: John Doe (22)
data:
firstName: John
age: '22'
-
uuid: 0c3a7922-b611-42ca-a961-944e09fa9aa2
label: Amy Jane (38)
data:
firstName: Amy
age: '38'
source:
name: my_dataset.csv
size: 100
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Entity'
example:
uuid: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
createdAt: '2018-01-19T23:58:03.395Z'
updatedAt: '2018-03-21T12:45:02.312Z'
deletedAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
conflict: null
currentVersion:
label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
conflictingProperties: null
version: 1
baseVersion: null
data:
firstName: John
age: '88'
dataReceived:
label: John (88)
firstName: John
age: '88'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/projects/{projectId}/datasets/{name}/entities/{uuid}:
get:
tags:
- Entity Management
summary: Getting Entity Details
description: |-
This returns the metadata and current data of an Entity.
The data and label of an Entity are found in the `currentVersion` object under `data` and `label` respectively. The `currentVersion` object also contains version-specific metadata fields such as `version`, `baseVersion`, details about conflicts that version introduced, etc. See the [versions](/central-api-entity-management/#listing-versions) endpoint for more details.
The Entity also contains top-level system metadata such as `uuid`, `createdAt` and `updatedAt` timestamps, and `creatorId` (or full `creator` if extended metadata is requested).
**Conflicts**
An Entity's metadata also has a `conflict` field, which indicates the current conflict status of the Entity. The value of a conflict can either be:
* `null`. The Entity does not have conflicting versions.
* `soft`. The Entity has a version that was based on a version other than the version immediately prior to it. (The specified `baseVerson` was not the latest version on the server.)
* `hard`. The Entity has a version that was based on a version other than the version immediately prior to it. Further, that version updated the same property as another update.
If an Entity has a conflict, it can be marked as resolved. After that, the conflict field will be null until a new conflicting version is received.
operationId: Getting Entity Details
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: uuid
in: path
description: UUID of the Entity
required: true
schema:
type: string
example: 54a405a0-53ce-4748-9788-d23a30cc3afa
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Entity'
example:
uuid: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
createdAt: '2018-01-19T23:58:03.395Z'
updatedAt: '2018-03-21T12:45:02.312Z'
deletedAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
conflict: null
currentVersion:
label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
conflictingProperties: null
version: 1
baseVersion: null
data:
firstName: John
age: '88'
dataReceived:
firstName: John
age: '88'
label: John (88)
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedEntity'
example:
uuid: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
createdAt: '2018-01-19T23:58:03.395Z'
updatedAt: '2018-03-21T12:45:02.312Z'
deletedAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
conflict: null
creator:
createdAt: '2018-04-18T23:19:14.802Z'
displayName: My Display Name
id: 115
type: user
updatedAt: '2018-04-18T23:42:11.406Z'
deletedAt: '2018-04-18T23:42:11.406Z'
currentVersion:
label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
conflictingProperties: null
version: 1
baseVersion: null
data:
firstName: John
age: '88'
dataReceived:
firstName: John
age: '88'
label: John (88)
creator:
createdAt: '2018-04-18T23:19:14.802Z'
displayName: My Display Name
id: 115
type: user
updatedAt: '2018-04-18T23:42:11.406Z'
deletedAt: '2018-04-18T23:42:11.406Z'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
delete:
tags:
- Entity Management
summary: Deleting an Entity
description: Use this API to delete an Entity. With this API, Entity is soft-deleted,
which means it is still in the database and you can retreive it by passing
`?deleted=true` to [GET /projects/:id/datasets/:name/entities](/central-api-entity-management/#entities-metadata).
In the future, we will provide a way to restore deleted entities and purge
deleted entities.
operationId: Deleting an Entity
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: uuid
in: path
description: UUID of the Entity
required: true
schema:
type: string
example: 54a405a0-53ce-4748-9788-d23a30cc3afa
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
patch:
tags:
- Entity Management
summary: Updating an Entity
description: |-
This endpoint is used to update the label or the properties (passed as JSON in the request body) of an Entity. You only need to include the properties you wish to update. To unset the value of any property, you can set it to empty string (""). The label must be a non-empty string. Setting a property to `null` will throw an error. Attempting to update a property that doesn't exist in the Dataset will throw an error.
**Specifying a base version**
You must either provide the query parameter `baseVersion` or use the `force=true` query parameter. The specified `baseVersion` must match the current version of the Entity on the server or the request will be rejected. This acts as a check to ensure you are not trying to update based on stale data. To update an Entity regardless of its current state, use the `force` flag with value `true`.
**Resolving a conflict**
You can also use this endpoint to resolve an Entity conflict by passing the `resolve=true` query parameter, in which case providing data in the request body is optional. When not providing new data, only the `conflict` status from the Entity will be cleared and no new version will be created. When providing data, the `conflict` will be cleared and an updated version of the Entity will be added.
operationId: Updating an Entity
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: uuid
in: path
description: UUID of the Entity
required: true
schema:
type: string
example: 54a405a0-53ce-4748-9788-d23a30cc3afa
- name: baseVersion
in: query
description: The base version of the Entity you are applying the update to (must match the latest version on the server)
required: false
schema:
type: integer
example: 2
- name: force
in: query
description: Flag to forcefully update the Entity
required: false
schema:
type: boolean
example: true
- name: resolve
in: query
description: Flag to resolve the conflict
required: false
schema:
type: boolean
example: true
requestBody:
content:
'*/*':
schema:
type: object
properties:
label:
type: string
description: Label of the Entity
data:
$ref: '#/components/schemas/DataExample'
example:
label: John Doe (88)
data:
firstName: John
age: '88'
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Entity'
example:
uuid: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
createdAt: '2018-01-19T23:58:03.395Z'
updatedAt: '2018-03-21T12:45:02.312Z'
deletedAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
conflict: null
currentVersion:
label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
conflictingProperties: null
version: 1
baseVersion: null
data:
firstName: John
age: '88'
dataReceived:
firstName: John
age: '88'
label: John (88)
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
/projects/{projectId}/datasets/{name}/entities/{uuid}/versions:
get:
tags:
- Entity Management
summary: Listing Versions
description: |-
This returns the Entity metadata and data for every version of this Entity, in ascending creation order.
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to return a `creator` data object alongside the `creatorId` Actor ID reference.
There is an optional query flag `relevantToConflict` that returns the subset of past versions of an Entity that are relevant to the Entity's current conflict. This includes the latest version, the base version, the previous server version, and any other versions since the last time the Entity was in a conflict-free state. If the Entity is not in conflict, zero versions are returned.
operationId: Listing Entity Versions
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: uuid
in: path
description: UUID of the Entity
required: true
schema:
type: string
example: 54a405a0-53ce-4748-9788-d23a30cc3afa
- name: relevantToConflict
in: query
description: Flag to return only the versions of the entity that are relevant to the current conflict.
schema:
type: boolean
example: true
responses:
200:
description: OK
content:
application/json:
schema:
type: array
description: Standard Response
items:
$ref: '#/components/schemas/EntityVersionFull'
example:
- label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
version: 1
baseVersion: null
conflict: null
resolved: false
lastGoodVersion: true
relevantToConflict: false
conflictingProperties: null
baseDiff: []
serverDiff: []
source: "// Similar to Audit.details. This property is experimental and may change in the future."
data:
firstName: John
age: '88'
dataReceived:
firstName: John
age: '88'
label: John (88)
application/json; extended:
schema:
type: array
description: Extended Response
items:
$ref: '#/components/schemas/ExtendedEntityVersionFull'
example:
- label: John (88)
current: true
createdAt: '2018-03-21T12:45:02.312Z'
creatorId: 1
userAgent: Enketo/3.0.4
version: 1
baseVersion: null
conflict: null
resolved: false
lastGoodVersion: true
relevantToConflict: false
conflictingProperties: null
baseDiff: []
serverDiff: []
source: "// Similar to Audit.details. This property is experimental and may change in the future."
data:
firstName: John
age: '88'
dataReceived:
firstName: John
age: '88'
label: John (88)
creator:
createdAt: '2018-04-18T23:19:14.802Z'
displayName: My Display Name
id: 115
type: user
updatedAt: '2018-04-18T23:42:11.406Z'
deletedAt: '2018-04-18T23:42:11.406Z'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/projects/{projectId}/datasets/{name}/entities/{uuid}/diffs:
get:
tags:
- Entity Management
summary: Getting changes between Versions
description: This returns the changes, or edits, between different versions
of an Entity. These changes are returned as an array of arrays. Between two
Entities, there is an array of objects representing how each property changed.
This change object contains the old and new values, as well as the property
name.
operationId: Getting changes between Entity Versions
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: uuid
in: path
description: UUID of the Entity
required: true
schema:
type: string
example: 54a405a0-53ce-4748-9788-d23a30cc3afa
responses:
200:
description: + Response 200
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/EntityDiffValue'
example:
- - new: John
old: Dana
propertyName: firstName
- new: Doe
old: Roe
propertyName: lastName
- new: John Doe
old: Jane Roe
propertyName: label
- - new: Robert
old: Doe
propertyName: firstName
- new: Robert Doe
old: Doe Doe
propertyName: label
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/projects/{projectId}/datasets/{name}/entities/{uuid}/audits:
get:
tags:
- Entity Management
summary: Entity Audit Log
description: Returns [Server Audit Logs](/central-api-system-endpoints/#server-audit-logs)
relating to an Entity. They will be returned most recent first.
operationId: Entity Audit Log
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: uuid
in: path
description: UUID of the Entity
required: true
schema:
type: string
example: 54a405a0-53ce-4748-9788-d23a30cc3afa
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Audit'
example:
- actorId: 42
action: entity.create
acteeId: 85cb9aff-005e-4edd-9739-dc9c1a829c44
loggedAt: 2018-04-18T23:19:14.802Z
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/formList:
get:
tags:
- OpenRosa Endpoints
summary: OpenRosa Form Listing API
description: |-
This is the mostly standards-compliant implementation of the [OpenRosa Form Discovery (Listing) API](https://bitbucket.org/javarosa/javarosa/wiki/FormListAPI). We will not attempt to redocument the standard here.
The following aspects of the standard are _not_ supported by ODK Central:
* The `deviceID` may be provided with the request, but it will be ignored.
* The `Accept-Language` header may be provided with the request, but it will be ignored.
* The `?formID=` querystring parameter is not supported and will be ignored.
* The `?verbose` querystring parameter is not supported and will be ignored.
* The `?listAllVersions` querystring is not supported and will be ignored. Central does not yet support multiple active versions of the same Form.
* No `` will ever be provided, as Central does not yet support this feature.
By default, the given `` in the Form Listing response is the friendly name associated with the `Form` (`` in the XML and `name` on the API resource). If no such value can be found, then the `xmlFormId` will be given as the `` instead.
A `` property will be given per `` if and only if that form is expected to have media or data file attachments associated with it, based on its XForms definition. It will appear even if no attachments have actually been uploaded to the server to fulfill those expectations.
This resource always requires authentication. If a valid Actor is authenticated at all, a form list will always be returned, filtered by what that Actor is allowed to access.
If you haven't already, please take a look at the **HTTP Request API** notes above on the required OpenRosa headers.
operationId: OpenRosa Form Listing API
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: X-OpenRosa-Version
in: header
description: e.g. 1.0
schema:
type: string
example: "1.0"
responses:
200:
description: OK
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
basicbasicmd5:a64817a5688dd7c17563e32d4eb1cab2https://your.odk.server/v1/projects/7/forms/basic.xmlhttps://your.odk.server/v1/projects/7/forms/basic/manifestsimpleSimplemd5:https://your.odk.server/v1/projects/7/forms/simple.xml
/v1/projects/{projectId}/submission:
post:
tags:
- OpenRosa Endpoints
summary: OpenRosa Form Submission API
description: |-
This is the fully standards-compliant implementation of the [OpenRosa Form Submission API](https://bitbucket.org/javarosa/javarosa/wiki/FormSubmissionAPI). We will not attempt to redocument the submission part of the standard here, but please read further for information about _updating_ submissions with new data.
Some things to understand when using this API for any reason:
* ODK Central will always provide an `X-OpenRosa-Accept-Content-Length` of 100 megabytes. In reality, this number depends on how the server has been deployed. The default Docker-based installation, for example, is limited to 100MB at the nginx layer.
* The `xml_submission_file` may have a Content Type of either `text/xml` _or_ `application/xml`.
* Central supports the `HEAD` request preflighting recommended by the specification, but does not require it. Because our supported authentication methods do not follow the try/retry pattern, only preflight your request if you want to read the `X-OpenRosa-Accept-Content-Length` header or are concerned about the other issues listed in the standards document, like proxies.
* As stated in the standards document, it is possible to submit multimedia attachments with the `Submission` across multiple `POST` requests to this API. _However_, we impose the additional restriction that the Submission XML (`xml_submission_file`) _may not change_ between requests. If Central sees a Submission with an `instanceId` it already knows about but the XML has changed in any way, it will respond with a `409 Conflict` error and reject the submission.
* Central will never return a `202` in any response from this API.
* If you haven't already, please take a look at the **HTTP Request API** notes above on the required OpenRosa headers.
You can use this endpoint to submit _updates_ to an existing submission. To do so, provide additionally a [`deprecatedID` metadata XML node](https://getodk.github.io/xforms-spec/#metadata) with the `instanceID` of the submission you are replacing. Some things to understand when submitting updates:
* The new XML entirely replaces the old XML. No merging will be performed. So your new submission must contain exactly the current data.
* If the `deprecatedID` you provide has already been deprecated, your request will be rejected with a `409 Conflict` and a useful error message.
* If the submission you are deprecating had media files uploaded for it, any of those that are still relevant will be carried over to the new version by filename reference. Any files you provide will overwrite these carryovers.
* Just as with initial submission, you can send multiple requests to this endpoint to submit additional media files if they do not comfortably fit in a single request. Also the same as initial submission, you'll need to provide exactly the same XML to make this happen. For updates, this will need to include the `deprecatedID`.
operationId: OpenRosa Form Submission API
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: X-OpenRosa-Version
in: header
description: e.g. 1.0
schema:
type: string
example: "1.0"
responses:
201:
description: Created
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
full submission upload was successful!
400:
description: 'This is one of several possible `400` failures the API might
return:'
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
A resource already exists with a attachment file name of attachment1.jpg.
403:
description: Forbidden
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
The authenticated actor does not have rights to perform that action.
409:
description: Conflict
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
A submission already exists with this ID, but with different XML. Resubmissions to attach additional multimedia must resubmit an identical xml_submission_file.
/v1/projects/{projectId}/forms/{xmlFormId}/manifest:
get:
tags:
- OpenRosa Endpoints
summary: OpenRosa Form Manifest API
description: |-
_(introduced: version 0.2)_
This is the fully standards-compliant implementation of the [OpenRosa Form Manifest API](https://bitbucket.org/javarosa/javarosa/wiki/FormListAPI#!the-manifest-document). We will not attempt to redocument the standard here.
A Manifest document is available at this resource path for any form in the system. However:
* A link to this document will not be given in the [Form Listing API](/central-api-openrosa-endpoints/#openrosa-form-listing-api) unless we expect the form to have media or data file attachments based on the XForms definition of the form.
* The Manifest will only output information for files the server actually has in its possession. Any missing expected files will be omitted, as we cannot provide a `hash` or `downloadUrl` for them.
* For Attachments that are linked to a Dataset, the value of `hash` is calculated using the MD5 of the last updated timestamp of the Dataset, instead of the content of the Dataset.
operationId: OpenRosa Form Manifest API
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: X-OpenRosa-Version
in: header
description: e.g. 1.0
schema:
type: string
example: "1.0"
responses:
200:
description: OK
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
question1.jpgmd5:a64817a5688dd7c17563e32d4eb1cab2https://your.odk.server/v1/projects/7/forms/basic/attachments/question1.jpgquestion2.jpgmd5:a6fdc426037143cf71cced68e2532e3chttps://your.odk.server/v1/projects/7/forms/basic/attachments/question2.jpg
403:
description: Forbidden
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
The authenticated actor does not have rights to perform that action.
/v1/test/{token}/projects/{projectId}/forms/{xmlFormId}/draft/formList:
get:
tags:
- Draft Testing Endpoints
summary: OpenRosa Form Listing API
description: Identical to the [non-Draft version](/central-api-openrosa-endpoints/#openrosa-form-listing-api),
but will only list the Draft Form to be tested.
operationId: OpenRosa Form Listing API (Draft Form)
parameters:
- name: token
in: path
description: The authentication Draft Token associated with the Draft Form in question.
required: true
schema:
type: string
example: "IeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QP"
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: X-OpenRosa-Version
in: header
description: e.g. 1.0
schema:
type: string
example: "1.0"
responses:
200:
description: OK
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
basicbasicmd5:a64817a5688dd7c17563e32d4eb1cab2https://your.odk.server/v1/test/IeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QP/projects/7/forms/basic/draft.xmlhttps://your.odk.server/v1/test/IeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QP/projects/7/forms/basic/draft/manifest
/v1/test/{token}/projects/{projectId}/forms/{xmlFormId}/draft/submission:
post:
tags:
- Draft Testing Endpoints
summary: OpenRosa Form Submission API
description: Identical to the [non-Draft version](/central-api-openrosa-endpoints/#openrosa-form-submission-api),
but will only submit to (and allow submissions to) the Draft Form to be tested.
operationId: OpenRosa Form Submission API (Draft Form)
parameters:
- name: token
in: path
description: The authentication Draft Token associated with the Draft Form in question.
required: true
schema:
type: string
example: "IeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QP"
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: X-OpenRosa-Version
in: header
description: e.g. 1.0
schema:
type: string
example: "1.0"
responses:
201:
description: Created
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
full submission upload was successful!
400:
description: 'This is one of several possible `400` failures the API might
return:'
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
A resource already exists with a attachment file name of attachment1.jpg.
403:
description: Forbidden
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
The authenticated actor does not have rights to perform that action.
409:
description: Conflict
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
A submission already exists with this ID, but with different XML. Resubmissions to attach additional multimedia must resubmit an identical xml_submission_file.
/v1/test/{token}/projects/{projectId}/forms/{xmlFormId}/draft/manifest:
get:
tags:
- Draft Testing Endpoints
summary: OpenRosa Form Manifest API
description: Identical to the [non-Draft version](/central-api-openrosa-endpoints/#openrosa-form-manifest-api).
operationId: OpenRosa Form Manifest API (Draft Form)
parameters:
- name: token
in: path
description: The authentication Draft Token associated with the Draft Form in question.
required: true
schema:
type: string
example: "IeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QP"
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: X-OpenRosa-Version
in: header
description: e.g. 1.0
schema:
type: string
example: "1.0"
responses:
200:
description: OK
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
question.jpgmd5:a64817a5688dd7c17563e32d4eb1cab2https://your.odk.server/v1/test/IeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QP/projects/7/forms/basic/draft/attachments/question.jpg
403:
description: Forbidden
headers:
X-OpenRosa-Version:
schema:
type: string
content:
text/xml:
example: |
The authenticated actor does not have rights to perform that action.
/v1/test/{token}/projects/{projectId}/forms/{xmlFormId}/draft/attachments/{filename}:
get:
tags:
- Draft Testing Endpoints
summary: Downloading a Form Attachment
description: Identical to the [non-Draft version](/central-api-form-management/#downloading-a-form-attachment).
operationId: Downloading a Form Attachment (Draft Form)
parameters:
- name: token
in: path
description: The authentication Draft Token associated with the Draft Form in question.
required: true
schema:
type: string
example: "IeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QP"
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the Form being referenced.
required: true
schema:
type: string
example: simple
- name: filename
in: path
description: The name of the file as given by the Attachments listing resource.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
content:
'{the MIME type of the attachment file itself}':
example: |
(binary data)
403:
description: Forbidden
content:
'{the MIME type of the attachment file itself}':
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/projects/{projectId}/forms/{xmlFormId}.svc:
get:
tags:
- OData Form Service
summary: Service Document
description: |-
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.
operationId: Service Document
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the `Form` whose OData service you wish to
access.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json; charset=utf-8; odata.metadata=minimal:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- kind
- name
- url
type: object
properties:
kind:
type: string
name:
type: string
url:
type: string
example:
'@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
example:
'@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
application/json:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- kind
- name
- url
type: object
properties:
kind:
type: string
name:
type: string
url:
type: string
example:
'@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
403:
description: Forbidden
content:
application/json; charset=utf-8; odata.metadata=minimal:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/json; charset=utf-8; odata.metadata=minimal:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
/v1/projects/{projectId}/forms/{xmlFormId}.svc/$metadata:
get:
tags:
- OData Form Service
summary: Metadata Document
description: |-
The Metadata Document describes, in [EDMX CSDL](http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html), the schema of all the data you can retrieve from the OData Form Service in question. This is essentially the XForms form schema translated into the OData format. EDMX/CSDL defines schemas in terms of objects, their properties, and 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. 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](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Capabilities.V1.md). 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.
operationId: Metadata Document
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the `Form` whose OData service you wish to
access.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/xml:
example: |2
eqmetanameage
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
/v1/projects/{projectId}/forms/{xmlFormId}.svc/{table}:
get:
tags:
- OData Form Service
summary: Data Document
description: |-
The data documents are JSON representations of each table of `Submission` data. They follow the [corresponding specification](http://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html), but apart from the representation of geospatial data as GeoJSON rather than the ODK proprietary format, the output here should not be 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. As of ODK Central v2023.4, `@odata.nextLink` contains a `$skiptoken` (an opaque cursor), which allows you to page through Submissions with a consistent offset, even while new Submissions are being created.
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](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358948) is partially supported. In OData, you can use `$filter` to filter by certain data fields 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](https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC).
Please see the [OData documentation](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358948) on `$filter` [operations](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_BuiltinFilterOperations) and [functions](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_BuiltinQueryFunctions) 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](https://en.wikipedia.org/wiki/Well-known_text) 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](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358942) is supported with some limitations:
+ `$select` and `$expand` can't be used together.
+ Child properties of repeats can't be requested using `$select`
As of ODK Central v2024.1, the [`$orderby` query parameter](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358952) is now supported, and can sort on the same fields as `$filter`, noted above. The order can be specified as `ASC` (ascending) or `DESC` (descending), which are case-insensitive. Multiple sort expressions can be used together, separated by commas, e.g. `$orderby=__system/submitterId ASC, __system/reviewState DESC`.
As the vast majority of clients only support the JSON OData format, that is the only format ODK Central offers.
operationId: Data Document
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the `Form` whose OData service you wish to
access.
required: true
schema:
type: string
example: simple
- name: table
in: path
description: The name of the table to be returned. These names can be found
in the output of the [Service Document](/central-api-odata-endpoints/#service-document).
required: true
schema:
type: string
example: Submissions
- name: '%24skip'
in: query
description: If supplied, the first `$skip` rows will be omitted from the
results.
schema:
type: number
example: "10"
- name: '%24top'
in: query
description: If supplied, only up to `$top` rows will be returned in the results.
schema:
type: number
example: "5"
- name: '%24count'
in: query
description: If set to `true`, an `@odata.count` property will be added to
the result indicating the total number of rows, ignoring the above paging
parameters.
schema:
type: boolean
example: "true"
- name: '%24wkt'
in: query
description: If set to `true`, geospatial data will be returned as Well-Known
Text (WKT) strings rather than GeoJSON structures.
schema:
type: boolean
example: "true"
- name: '%24filter'
in: query
description: If provided, will filter responses to those matching the query.
Only [certain fields](/central-api-odata-endpoints/#data-document)
are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`,
`gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`,
`year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: year(__system/submissionDate) lt year(now())
- name: '%24orderby'
in: query
description: If provided, will sort responses according to specified order expression. Only the same fields as `$filter` above can be used to sort. Multiple expressions can be used together.
schema:
type: string
example: __system/submitterId asc, __system/updatedAt desc
- name: '%24expand'
in: query
description: Repetitions, which should get expanded. Currently, only `*` is
implemented, which expands all repetitions.
schema:
type: string
example: '*'
- name: '%24select'
in: query
description: If provided, will return only the selected fields.
schema:
type: string
example: __id, age, name, meta/instanceID
- name: '%24skiptoken'
in: query
description: Opaque cursor from `@odata.nextLink` used for paging.
schema:
type: string
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- __id
- age
- meta
- name
type: object
properties:
__id:
type: string
age:
type: number
meta:
type: object
properties:
instanceID:
type: string
name:
type: string
example:
'@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
example:
'@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
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
501:
description: Not Implemented
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "501.1"
message: The requested feature $unsupported is not supported by this
server.
/#/dl/projects{projectId}/forms/{xmlFormId}/submissions/{instanceId}/attachments/{filename}:
get:
tags:
- OData Form Service
summary: Data Download Path
description: |-
_(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 `` tag.
operationId: Data Download Path
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the `Form` whose OData service you wish to
access.
required: true
schema:
type: string
example: simple
- name: instanceId
in: path
description: The `instanceId` of the Submission being referenced.
required: true
schema:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
- name: filename
in: path
description: The name of the file to be retrieved.
required: true
schema:
type: string
example: file1.jpg
responses:
200:
description: OK
content:
text/html:
example: |
(html markup data)
/v1/projects/{projectId}/datasets/{name}.svc:
get:
tags:
- OData Dataset Service
summary: Service Document
description: |-
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.
operationId: Service Document for Datasets
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: name
in: path
description: The `name` of the `Dataset` whose OData service you wish to access.
required: true
schema:
type: string
example: trees
responses:
200:
description: OK
content:
application/json; charset=utf-8; odata.metadata=minimal:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- kind
- name
- url
type: object
properties:
kind:
type: string
name:
type: string
url:
type: string
example:
'@odata.context': https://your.odk.server/v1/projects/7/datasets/sample.svc/$metadata
value:
- kind: EntitySet
name: Entities
url: Entities
- kind: EntitySet
name: Entities.children.child
url: Entities.children.child
example:
'@odata.context': https://your.odk.server/v1/projects/7/datasets/sample.svc/$metadata
value:
- kind: EntitySet
name: Entities
url: Entities
- kind: EntitySet
name: Entities.children.child
url: Entities.children.child
application/json:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- kind
- name
- url
type: object
properties:
kind:
type: string
name:
type: string
url:
type: string
example:
'@odata.context': https://your.odk.server/v1/projects/7/datasets/sample.svc/$metadata
value:
- kind: EntitySet
name: Entities
url: Entities
- kind: EntitySet
name: Entities.children.child
url: Entities.children.child
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
/v1/projects/{projectId}/datasets/{name}.svc/$metadata:
get:
tags:
- OData Dataset Service
summary: Metadata Document
description: The Metadata Document describes, in [EDMX CSDL](http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html),
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.
operationId: Metadata Document for Dataset
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
responses:
200:
description: OK
content:
application/xml:
example: |
eqgeometryspeciescircumference_cm
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
/v1/projects/{projectId}/datasets/{name}.svc/Entities:
get:
tags:
- OData Dataset Service
summary: Data Document
description: |-
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. As of ODK Central v2023.4, `@odata.nextLink` contains a `$skiptoken` (an opaque cursor) to better paginate around deleted Entities.
The [`$filter` querystring parameter](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358948) can be used to filter certain data fields 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 Creator Actor ID | `__system/creatorId` |
| Entity Timestamp | `__system/createdAt` |
| Entity Update Timestamp | `__system/updatedAt` |
| Entity Conflict | `__system/conflict` |
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](https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC).
Please see the [OData documentation](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358948) on `$filter` [operations](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_BuiltinFilterOperations) and [functions](http://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_BuiltinQueryFunctions) for more information.
The [`$select` query parameter](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358942) 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.
The [`$orderby` query parameter](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358952) will return Entities sorted by different fields, which come from the same list used by `$filter`, as noted above. The order can be specified as `ASC` (ascending) or `DESC` (descending), which are case-insensitive. Multiple sort expressions can be used together, separated by commas, e.g. `$orderby=__system/creatorId ASC, __system/conflict DESC`.
As the vast majority of clients only support the JSON OData format, that is the only format ODK Central offers.
operationId: Data Document for Dataset
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: name
in: path
description: Name of the Dataset
required: true
schema:
type: string
example: people
- name: '%24skip'
in: query
description: If supplied, the first `$skip` rows will be omitted from the
results.
schema:
type: number
example: "10"
- name: '%24top'
in: query
description: If supplied, only up to `$top` rows will be returned in the results.
schema:
type: number
example: "5"
- name: '%24count'
in: query
description: If set to `true`, an `@odata.count` property will be added to
the result indicating the total number of rows, ignoring the above paging
parameters.
schema:
type: boolean
example: "true"
- name: '%24filter'
in: query
description: If provided, will filter responses to those matching the query.
Only [certain fields](/central-api-odata-endpoints/#data-document)
are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`,
`gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`,
`year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: year(__system/createdAt) lt year(now())
- name: '%24orderby'
in: query
description: If provided, will sort responses according to specified order expression. Only the same fields as `$filter` above can be used to sort. Multiple expressions can be used together.
schema:
type: string
example: __system/creatorId asc, __system/updatedAt desc
- name: '%24select'
in: query
description: If provided, will return only the selected fields.
schema:
type: string
example: __id, label, name
- name: '%24skiptoken'
in: query
description: Opaque cursor from `@odata.nextLink` used for paging.
schema:
type: string
responses:
200:
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/EntityOdata'
example:
'@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
conflict: null
- __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
conflict: null
geometry: 47.722581 18.562111 0 0,
species: mora,
circumference_cm: 345
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
501:
description: Not Implemented
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "501.1"
message: The requested feature $unsupported is not supported by this
server.
/v1/projects/{projectId}/forms/{xmlFormId}/draft.svc:
get:
tags:
- Draft Testing
summary: Service Document
description: Identical to [the non-Draft version](/central-api-odata-endpoints/#service-document)
of this endpoint.
operationId: Service Document for Dataset
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "7"
- name: xmlFormId
in: path
description: The `xmlFormId` of the `Form` whose OData service you wish to
access.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/json; charset=utf-8; odata.metadata=minimal:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- kind
- name
- url
type: object
properties:
kind:
type: string
name:
type: string
url:
type: string
example:
'@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
example:
'@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
application/json:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- kind
- name
- url
type: object
properties:
kind:
type: string
name:
type: string
url:
type: string
example:
'@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
403:
description: Forbidden
content:
application/json; charset=utf-8; odata.metadata=minimal:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/json; charset=utf-8; odata.metadata=minimal:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
/v1/projects/{projectId}/forms/{xmlFormId}/draft.svc/$metadata:
get:
tags:
- Draft Testing
summary: Metadata Document
description: Identical to [the non-Draft version](/central-api-odata-endpoints/#metadata-document)
of this endpoint.
operationId: Metadata Document (Draft Form)
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the `Form` whose OData service you wish to
access.
required: true
schema:
type: string
example: simple
responses:
200:
description: OK
content:
application/xml:
example: |2
eqmetanameage
403:
description: Forbidden
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/xml:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
/v1/projects/{projectId}/forms/{xmlFormId}/draft.svc/{table}:
get:
tags:
- Draft Testing
summary: Data Document
description: Identical to [the non-Draft version](/central-api-odata-endpoints/#data-document)
of this endpoint.
operationId: Data Document (Draft Form)
parameters:
- name: projectId
in: path
description: The numeric ID of the Project
required: true
schema:
type: number
example: "16"
- name: xmlFormId
in: path
description: The `xmlFormId` of the `Form` whose OData service you wish to
access.
required: true
schema:
type: string
example: simple
- name: table
in: path
description: The name of the table to be returned. These names can be found
in the output of the [Service Document](/central-api-odata-endpoints/#service-document).
required: true
schema:
type: string
example: Submissions
- name: '%24skip'
in: query
description: If supplied, the first `$skip` rows will be omitted from the
results.
schema:
type: number
example: "10"
- name: '%24top'
in: query
description: If supplied, only up to `$top` rows will be returned in the results.
schema:
type: number
example: "5"
- name: '%24count'
in: query
description: If set to `true`, an `@odata.count` property will be added to
the result indicating the total number of rows, ignoring the above paging
parameters.
schema:
type: boolean
example: "true"
- name: '%24wkt'
in: query
description: If set to `true`, geospatial data will be returned as Well-Known
Text (WKT) strings rather than GeoJSON structures.
schema:
type: boolean
example: "true"
- name: '%24filter'
in: query
description: If provided, will filter responses to those matching the query.
Only [certain fields](/central-api-odata-endpoints/#data-document)
are available to reference. The operators `lt`, `le`, `eq`, `neq`, `ge`,
`gt`, `not`, `and`, and `or` are supported, and the built-in functions `now`,
`year`, `month`, `day`, `hour`, `minute`, `second`.
schema:
type: string
example: year(__system/submissionDate) lt year(now())
- name: '%24expand'
in: query
description: Repetitions, which should get expanded. Currently, only `*` is
implemented, which expands all repetitions.
schema:
type: string
example: '*'
- name: '%24select'
in: query
description: If provided, will return only the selected fields.
schema:
type: string
example: __id, age, name, meta/instanceID
responses:
200:
description: OK
content:
application/json:
schema:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
required:
- __id
- age
- meta
- name
type: object
properties:
__id:
type: string
age:
type: number
meta:
type: object
properties:
instanceID:
type: string
name:
type: string
example:
'@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
example:
'@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
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
406:
description: Not Acceptable
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "406.1"
message: 'Requested format not acceptable; this resource allows: (application/json,
json).'
501:
description: Not Implemented
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "501.1"
message: The requested feature $unsupported is not supported by this
server.
/v1/config/analytics:
get:
tags:
- Usage Reporting Configuration
summary: Getting the current configuration
description: If the Usage Reporting configuration is not set, this endpoint
will return a `404`. Once the configuration is set, this endpoint will indicate
whether the server will share usage data with the Central team. If the server
will share usage data, and contact information was provided, this endpoint
will also return the provided work email address and organization name.
operationId: Getting the current configuration
responses:
200:
description: OK
content:
application/json:
schema:
required:
- key
- setAt
- value
type: object
properties:
key:
type: string
description: The type of system configuration.
setAt:
type: string
description: ISO date format. The last time this system configuration
was set.
value:
required:
- enabled
type: object
properties:
enabled:
type: boolean
description: '`true` if the server will share usage data with
the Central team and `false` if not.'
email:
type: string
description: The work email address to include with the metrics
report.
organization:
type: string
description: The organization name to include with the metrics
report.
description: Details about the Usage Reporting configuration.
example:
key: some_type
setAt: 2018-01-06T00:32:52.787Z
value:
enabled: true
email: my.email.address@getodk.org
organization: Organization Name
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
404:
description: Not Found
content:
application/json:
schema:
required:
- code
type: object
properties:
code:
type: string
message:
type: string
example:
code: "404.1"
message: Could not find the resource you were looking for.
post:
tags:
- Usage Reporting Configuration
summary: Setting a new configuration
description: |-
An Administrator can use this endpoint to choose whether the server will share anonymous usage data with the Central team. This configuration affects the entire server. Until the Usage Reporting configuration is set, Administrators will see a message on the Central administration website that provides further information.
If an Administrator specifies `true` for `enabled`, the server will share anonymous usage data monthly with the Central team. By specifying `true`, the Administrator accepts the [Terms of Service](https://getodk.org/legal/tos) and [Privacy Policy](https://getodk.org/legal/privacy). The Administrator can also share contact information to include with the report.
If an Administrator specifies `false` for `enabled`, the server will not share anonymous usage data with the Central team. Administrators will no longer see the message on the administration website.
If the Usage Reporting configuration is already set, the current configuration will be overwritten with the new one.
operationId: Setting a new configuration
requestBody:
content:
'*/*':
schema:
required:
- enabled
type: object
properties:
enabled:
type: boolean
description: See above.
email:
type: string
description: A work email address to include with the metrics report.
organization:
type: string
description: An organization name to include with the metrics report.
example:
enabled: true
email: my.email.address@getodk.org
organization: Organization Name
required: false
responses:
200:
description: OK
content:
application/json:
schema:
required:
- key
- setAt
- value
type: object
properties:
key:
type: string
description: The type of system configuration.
setAt:
type: string
description: ISO date format. The last time this system configuration
was set.
value:
required:
- enabled
type: object
properties:
enabled:
type: boolean
description: '`true` if the server will share usage data with
the Central team and `false` if not.'
email:
type: string
description: The work email address to include with the metrics
report.
organization:
type: string
description: The organization name to include with the metrics
report.
description: Details about the Usage Reporting configuration.
example:
key: some_type
setAt: 2018-01-06T00:32:52.787Z
value:
enabled: true
email: my.email.address@getodk.org
organization: Organization Name
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
delete:
tags:
- Usage Reporting Configuration
summary: Unsetting the current configuration
description: If the Usage Reporting configuration is unset, Administrators will
once again see a message on the the Central administration website.
operationId: Unsetting the current configuration
responses:
200:
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Success'
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/analytics/preview:
get:
tags:
- Usage Report Preview
summary: Getting the Usage Report preview
description: An Administrator can use this endpoint to preview the metrics being
sent. The preview is computed on the fly and represents what the report would
look like if sent at that time. This endpoint does not directly submit the
Usage Report; that is handled internally as a scheduled Central task.
operationId: Getting the Usage Report preview
responses:
200:
description: OK
content: {}
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/audits:
get:
tags:
- Server Audit Logs
summary: Getting Audit Log Entries
description: |-
This resource allows access to those log entries, with some paging and filtering options. These are provided by querystring parameters: `action` allows filtering by the action types listed above, `start` and `end` allow filtering by log timestamp (see below), and `limit` and `offset` control paging. If no paging parameters are given, the server will attempt to return every audit log entry that it has.
The `start` and `end` parameters work based on exact timestamps, given in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. It is possible to provide just a datestring (eg `2000-01-01`), in which case midnight will be inferred. But this value alone leaves the timezone unspecified. When no timezone is given, the server's local time will be used: the standard [Docker deployment](https://docs.getodk.org/central-install/) will always set server local time to UTC, but installations may have been customized, and there is no guarantee the UTC default hasn't been overridden.
For this reason, **we recommend always setting a timezone** when querying based on `start` and `end`: either by appending a `z` to indicate UTC (eg `2000-01-01z`) or by explicitly specifying a timezone per ISO 8601 (eg `2000-01-01+08`). The same applies for full timestamps (eg `2000-01-01T12:12:12z`, `2000-01-01T12:12:12+08`).
`start` may be given without `end`, and vice versa, in which case the timestamp filter will only be bounded on the specified side. They are both inclusive (`>=` and `<=`, respectively).
This endpoint supports retrieving extended metadata; provide a header `X-Extended-Metadata: true` to additionally expand the `actorId` into full `actor` details, and `acteeId` into full `actee` details. The `actor` will always be an Actor, but the `actee` may be an Actor, a Project, a Form, or some other type of object depending on the type of action.
operationId: Getting Audit Log Entries
parameters:
- name: action
in: query
description: The name of the `action` to filter by.
schema:
type: string
example: form.create
- name: start
in: query
description: The timestamp before which log entries are to be filtered out.
schema:
type: string
example: 2000-01-01z
- name: end
in: query
description: The timestamp after which log entries are to be filtered out.
schema:
type: string
example: 2000-12-31T23:59.999z
- name: limit
in: query
description: The maximum number of entries to return.
schema:
type: number
example: "100"
- name: offset
in: query
description: The zero-indexed number of entries to skip from the result.
schema:
type: number
example: "200"
responses:
200:
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Audit'
example:
- actorId: 42
action: user.session.create
details:
userAgent: Mozilla/5.0
acteeId: 85cb9aff-005e-4edd-9739-dc9c1a829c44
loggedAt: 2018-04-18T23:19:14.802Z
application/json; extended:
schema:
type: array
items:
$ref: '#/components/schemas/ExtendedAudit'
example:
- actorId: 42
action: form.create
details:
userAgent: Mozilla/5.0
acteeId: 85cb9aff-005e-4edd-9739-dc9c1a829c44
loggedAt: 2018-04-18T23:19:14.802Z
actor:
createdAt: 2018-04-18T23:19:14.802Z
displayName: My Display Name
id: 115
type: user
updatedAt: 2018-04-18T23:42:11.406Z
deletedAt: 2018-04-18T23:42:11.406Z
400:
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/Error400'
example:
code: "400"
message: Could not parse the given data (2 chars) as json.
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
/v1/backup:
post:
tags:
- Direct Backup
summary: Using an Encryption Passphrase
description: |-
Use the `POST` verb to start a direct download ad-hoc backup. You will want to supply a `passphrase` with your chosen encryption passphrase. It is possible to omit this, in which case the backup will still be encrypted, but it will decrypt given an empty passphrase.
Please see the section notes above about the long-running nature of this endpoint.
operationId: Using an Encryption Passphrase
requestBody:
content:
'*/*':
schema:
type: object
properties:
passphrase:
type: string
description: The passphrase with which to encrypt the backup.
example:
passphrase: my-password
required: false
responses:
200:
description: OK
headers:
Content-Disposition:
schema:
type: string
content: {}
403:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error403'
x-codegen-request-body-name: body
components:
schemas:
Actor:
required:
- createdAt
- displayName
- id
- type
type: object
properties:
createdAt:
type: string
description: ISO date format
example: 2018-04-18T23:19:14.802Z
displayName:
type: string
description: All `Actor`s, regardless of type, have a display name
example: My Display Name
id:
type: number
example: 115.0
type:
$ref: '#/components/schemas/ActorType'
updatedAt:
type: string
description: ISO date format
example: 2018-04-18T23:42:11.406Z
deletedAt:
type: string
description: ISO date format
example: 2018-04-18T23:42:11.406Z
ActorType:
type: string
description: The type of actor
enum:
- user
- field_key
- public_link
- singleUse
User:
allOf:
- $ref: '#/components/schemas/Actor'
- type: object
properties:
email:
type: string
description: The email address of the user
example:
AppUser:
allOf:
- $ref: '#/components/schemas/Actor'
- type: object
properties:
token:
type: string
description: If present, this is the Token that can be used to authenticate a request as this `App User`. If not present, this `App User`'s access has been revoked.
example: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
projectId:
type: number
description: The ID of the `Project` that this `App User` is bound to.
example: 1
ExtendedAppUser:
allOf:
- $ref: '#/components/schemas/AppUser'
- type: object
properties:
createdBy:
allOf:
- $ref: '#/components/schemas/Actor'
description: The `Actor` that created this `App User`
lastUsed:
type: string
description: ISO date format. The last time this `App User` was used to authenticate a request.
example: 2018-04-14T08:34:21.633Z
Role:
type: object
properties:
id:
type: number
example: 4
description: The numerical ID of the Role.
name:
type: string
example: Project Manager
description: The human-readable name for the Role.
system:
type: string
example: manager
description: The system name of the Role. Roles that have system names may not be modified.
verbs:
type: array
items:
type: string
example:
- project.update
- project.delete
description: The array of string verbs this Role confers.
createdAt:
type: string
description: ISO date format
example: 2018-04-18T23:42:11.406Z
updatedAt:
type: string
description: ISO date format
example: 2018-09-18T23:42:11.406Z
Assignment:
type: object
properties:
actorId:
type: number
example: 42
description: The numeric Actor ID being assigned.
roleId:
type: number
example: 4
description: The numeric Role ID being assigned.
ExtendedAssignment:
type: object
properties:
actor:
allOf:
- $ref: '#/components/schemas/Actor'
description: The full Actor data for this assignment.
roleId:
type: number
example: 4
description: The numeric Role ID being assigned.
FormSummaryAssignment:
type: object
required:
- actorId
- xmlFormId
- roleId
properties:
actorId:
type: number
example: 42
description: The numeric Actor ID being assigned.
xmlFormId:
type: string
example: simple
description: The `id` of the assigned form as given in its XForms XML definition
roleId:
type: number
example: 4
description: The numeric Role ID being assigned.
ExtendedFormSummaryAssignment:
type: object
required:
- actor
- xmlFormId
- roleId
properties:
actor:
$ref: '#/components/schemas/Actor'
description: The full Actor data for this assignment.
xmlFormId:
type: string
example: simple
description: The `id` of the assigned form as given in its XForms XML definition
roleId:
type: number
example: 4
description: The numeric Role ID being assigned.
Project:
type: object
required:
- name
properties:
id:
type: number
example: 1
description: The numerical ID of the Project.
name:
type: string
example: Default Project
description: The name of the Project.
description:
type: string
example: Description of this Project to show on Central.
description: The description of the Project, which is rendered as Markdown on Frontend.
keyId:
type: number
example: 3
description: If managed encryption is enabled on the project, the numeric ID of the encryption key as tracked by Central is given here.
archived:
type: boolean
description: Whether the Project is archived or not. `null` is equivalent to `false`. All this does is sort the Project to the bottom of the list and disable management features in the web management application.
ExtendedProject:
allOf:
- $ref: '#/components/schemas/Project'
- type: object
required:
- appUsers
- forms
- datasets
properties:
appUsers:
type: number
example: 4
description: The number of App Users created within this Project.
forms:
type: number
example: 7
description: The number of forms within this Project.
lastSubmission:
type: string
example: '2018-04-18T03:04:51.695Z'
description: ISO date format. The timestamp of the most recent submission to any form in this project, if any.
datasets:
type: number
example: 2
description: The number of Datasets within this Project.
ExtendedProjectWithVerbs:
allOf:
- $ref: '#/components/schemas/ExtendedProject'
- type: object
properties:
verbs:
type: array
items:
type: string
example:
- "form.create"
- "form.delete"
description: The array of string verbs the authenticated Actor may perform on and within this Project.
EntitySummaryFields:
type: object
properties:
uuid:
type: string
description: The `uuid` of the Entity that uniquely identifies the Entity.
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
createdAt:
type: string
description: ISO date format. The time that the server received the Entity.
example: 2018-04-18T23:42:11.406Z
updatedAt:
type: string
description: Timestamp of the last update in ISO date format. `null` when there is only one version of the Entity.
example: 2018-04-18T23:42:11.406Z
deletedAt:
type: string
description: Timestamp of the deletion in ISO date format. `null` if the Entity is not deleted.
example: 2018-04-18T23:42:11.406Z
creatorId:
type: number
description: The ID of the Actor (App User, User, or Public Link) that originally created the Entity.
example: 1
conflict:
type: string
description: |-
Type of the conflict.
`hard`: baseVersion conflicts and multiple versions update the same property
`soft`: baseVersion conflicts but data updates are independent
enum:
- soft
- hard
EntityVersionFields:
type: object
properties:
label:
type: string
description: Label of the Entity
example: John (88)
current:
type: boolean
description: if the version is the latest one
example: true
creatorId:
type: number
description: The ID of the Actor (App User, User, or Public Link) that originally created the Entity.
example: 1
userAgent:
type: string
description: The self-identified `userAgent` of the device that created the `Entity` version.
example: Enketo/3.0.4
conflictingProperties:
type: array
description: list of properties updated offline simultaneously.
items:
type: string
version:
type: number
description: The version number of the Entity. Each update increments this number.
example: 2
baseVersion:
type: number
description: The version number of the version that was the "base version" of this version. The base version is the version that was shown to the data collector when they made their update.
example: 1
EntitySummary:
allOf:
- $ref: '#/components/schemas/EntitySummaryFields'
- type: object
properties:
currentVersion:
$ref: '#/components/schemas/EntityVersionFields'
ExtendedEntityVersionSummary:
allOf:
- $ref: '#/components/schemas/EntityVersionFields'
- type: object
properties:
creator:
$ref: '#/components/schemas/Actor'
ExtendedEntitySummary:
allOf:
- $ref: '#/components/schemas/EntitySummaryFields'
- type: object
properties:
currentVersion:
$ref: '#/components/schemas/EntityVersionFields'
creator:
$ref: '#/components/schemas/Actor'
Entity:
allOf:
- $ref: '#/components/schemas/EntitySummaryFields'
- type: object
properties:
currentVersion:
$ref: '#/components/schemas/EntityVersion'
ExtendedEntity:
allOf:
- $ref: '#/components/schemas/EntitySummaryFields'
- type: object
properties:
creator:
$ref: '#/components/schemas/Actor'
currentVersion:
$ref: '#/components/schemas/EntityVersion'
EntityVersion:
allOf:
- $ref: '#/components/schemas/EntityVersionFields'
- type: object
properties:
data:
$ref: '#/components/schemas/DataExample'
dataReceived:
$ref: '#/components/schemas/DataReceivedExample'
ExtendedEntityVersion:
allOf:
- $ref: '#/components/schemas/EntityVersion'
- type: object
properties:
creator:
$ref: '#/components/schemas/Actor'
EntityVersionFull:
allOf:
- $ref: '#/components/schemas/EntityVersion'
- type: object
properties:
source:
type: object
description: The source of the Entity version, such as a Submission or an API request. This property is experimental and may change in the future.
example: {event: {}, submission: {}}
baseDiff:
type: array
description: List of properties that are different between this version and its base version. Includes the label if it differs between the two versions.
example: ['name', 'age']
serverDiff:
type: array
description: List of properties that are different between this version and the previous version on the server. Includes the label if it differs between the two versions.
example: ['name', 'age']
conflict:
type: string
description: Type of the conflict if this version causes a conflict; otherwise `null`
enum:
- soft
- hard
resolved:
type: boolean
description: Is the conflict resolved? Note that this is also false for the version which didn't cause a conflict
example: false
lastGoodVersion:
type: boolean
description: Indicates whether this version is the last known good version. Currently, the last known good version is defined as the version immediately prior to the first unresolved conflict. If there is no conflict, or if all conflicts are resolved, then the current version is the last known good version. This property is experimental, as the definition of the last known good version may change in the future.
example: false
relevantToConflict:
type: boolean
description: Indicates whether this version includes information relevant to resolving a conflict. If so, it will be shown to the user during conflict resolution. This property is experimental, as we may redefine conflict relevance in the future.
example: false
ExtendedEntityVersionFull:
allOf:
- $ref: '#/components/schemas/EntityVersionFull'
- type: object
properties:
creator:
$ref: '#/components/schemas/Actor'
EntityDiffValue:
type: array
items:
$ref: '#/components/schemas/EntityDiffValueItems'
EntityDiffValueItems:
type: object
properties:
new:
type: string
description: The new value of this property.
example: John
old:
type: string
description: The old value of this property.
example: Jane
propertyName:
type: string
description: The name of the property that is changed.
example: name
EntityBulkSource:
type: object
properties:
name:
type: string
description: A name to identify the bulk source, filename or API run
example: myfile.csv
size:
type: number
description: Optional, meant to indicate filesize (in MB)
example: 100
description: An object describing the source of this bulk create action.
EntityOdata:
type: object
properties:
'@odata.context':
type: string
value:
type: array
items:
type: object
properties:
__id:
type: string
label:
type: string
__system:
type: object
properties:
createdAt:
type: string
creatorId:
type: string
creatorName:
type: string
updates:
type: string
updatedAt:
type: string
geometry:
type: string
species:
type: string
circumference_cm:
type: string
EntityCreateSingle:
type: object
properties:
uuid:
type: string
description: (Optional) The `uuid` of the Entity that uniquely identifies the Entity.
label:
type: string
description: Label of the Entity
data:
$ref: '#/components/schemas/DataExample'
EntityCreateBulk:
type: object
properties:
entities:
type: array
items:
$ref: '#/components/schemas/EntityCreateSingle'
description: A list of Entities
source:
$ref: '#/components/schemas/EntityBulkSource'
DataExample:
type: object
properties:
firstName:
type: string
example: John
age:
type: string
example: '88'
DataReceivedExample:
allOf:
- $ref: '#/components/schemas/DataExample'
- type: object
properties:
label:
type: string
example: John (88)
Form:
required:
- createdAt
- hash
- projectId
- state
- version
- xmlFormId
type: object
properties:
projectId:
type: number
description: The `id` of the project this form belongs to.
example: 1.0
xmlFormId:
type: string
description: The `id` of this form as given in its XForms XML definition
example: simple
name:
type: string
description: The friendly name of this form. It is given by the ``
in the XForms XML definition.
example: Simple
version:
type: string
description: The `version` of this form as given in its XForms XML definition.
If no `version` was specified in the Form, a blank string will be given.
example: "2.1"
enketoId:
type: string
description: If it exists, this is the survey ID of this Form on Enketo
at `/-`. This will be the ID of the published version if it exists, otherwise
it will be the draft ID. Only a cookie-authenticated user may access the
preview through Enketo.
example: abcdef
hash:
type: string
description: An MD5 sum automatically computed based on the XForms XML definition.
This is required for OpenRosa compliance.
example: 51a93eab3a1974dbffc4c7913fa5a16a
keyId:
type: number
description: If a public encryption key is present on the form, its numeric
ID as tracked by Central is given here.
example: 3.0
state:
$ref: '#/components/schemas/FormState'
publishedAt:
type: string
description: Indicates when a draft has most recently been published for
this Form. If this value is `null`, this Form has never been published
yet, and contains only a draft.
example: 2018-01-21T00:04:11.153Z
createdAt:
type: string
description: ISO date format
example: 2018-01-19T23:58:03.395Z
updatedAt:
type: string
description: ISO date format
example: 2018-03-21T12:45:02.312Z
ExtendedForm:
allOf:
- $ref: '#/components/schemas/Form'
- type: object
required:
- submissions
- reviewStates
- entityRelated
properties:
submissions:
type: number
example: 10
description: The number of `Submission`s that have been submitted to this `Form`.
reviewStates:
$ref: '#/components/schemas/ReviewStateCounts'
description: Additional counts of the number of submissions in various states of review.
lastSubmission:
type: string
example: '2018-04-18T03:04:51.695Z'
description: ISO date format. The timestamp of the most recent submission, if any.
createdBy:
$ref: '#/components/schemas/Actor'
description: The full information of the Actor who created this Form.
excelContentType:
type: string
description: If the Form was created by uploading an Excel file, this field contains the MIME type of that file.
entityRelated:
type: boolean
description: True only if this Form is related to a Dataset. In v2022.3, this means the Form's Submissions create Entities in a Dataset. In a future version, Submissions will also be able to update existing Entities.
ExtendedFormVersion:
allOf:
- $ref: '#/components/schemas/Form'
- type: object
properties:
publishedBy:
$ref: '#/components/schemas/Actor'
description: The full information of the Actor who published this version of the Form.
excelContentType:
type: string
description: If the Form was created by uploading an Excel file, this field contains the MIME type of that file.
FormAttachment:
type: object
required:
- name
- type
- exists
- blobExists
- datasetExists
properties:
name:
type: string
example: myfile.mp3
description: The name of the file as specified in the XForm.
type:
$ref: '#/components/schemas/FormAttachmentType'
description: The expected type of file as specified in the XForm.
exists:
type: boolean
example: true
description: True if the server has the file or the Attachment is linked to a Dataset, otherwise false.
blobExists:
type: boolean
example: true
description: Whether the server has the file or not.
datasetExists:
type: boolean
example: true
description: Whether attachment is linked to a Dataset.
updatedAt:
type: string
example: '2018-03-21T12:45:02.312Z'
description: ISO date format. The last time this file's binary content was set (POST) or cleared (DELETE).
FormAttachmentType:
type: string
enum:
- image
- audio
- video
- file
FormState:
type: string
enum:
- open
- closing
- closed
Forms:
type: object
DraftForm:
allOf:
- $ref: '#/components/schemas/Form'
- required:
- draftToken
type: object
properties:
draftToken:
type: string
description: The test token to use to submit to this draft form. See [Draft
Testing Endpoints](/central-api-submission-management/#draft-submissions).
example: lSpAIeksRu1CNZs7!qjAot2T17dPzkrw9B4iTtpj7OoIJBmXvnHM8z8Ka4QPEjR7
enketoId:
type: string
description: If it exists, this is the survey ID of this draft Form on
Enketo at `/-`. Authentication is not needed to access the draft form
through Enketo.
example: abcdef
FormKeyValue:
properties:
xmlFormId:
type: string
description: The `id` of this form as given in its XForms XML definition
example: simple
name:
type: string
description: The friendly name of this form. It is given by the `` in the XForms XML definition. Returns `xmlFormId` if there is no title in the form definition.
example: Simple
Dataset:
required:
- createdAt
- name
- projectId
type: object
properties:
name:
type: string
description: The name of the Dataset
example: people
createdAt:
type: string
description: ISO date format.
example: 2018-01-19T23:58:03.395Z
projectId:
type: number
description: The numerical ID of the Project that the Dataset belongs to.
example: 1
approvalRequired:
type: boolean
description: Control whether a Submission should be approved before an Entity is created from it.
example: true
ExtendedDataset:
allOf:
- $ref: '#/components/schemas/Dataset'
- required:
- entities
type: object
properties:
lastEntity:
type: string
description: ISO date format. The timestamp of the most recent entity,
if any.
example: 2018-04-18T03:04:51.695Z
entities:
type: number
description: The number of Entities in the Dataset.
example: 10
conflicts:
type: number
description: The number of Entities that have conflicts.
example: 10.0
PatchAttachment:
required:
- dataset
type: object
properties:
dataset:
type: boolean
description: true for linking Dataset and false for unlinking Dataset.
example: true
PublicLink:
allOf:
- $ref: '#/components/schemas/Actor'
- type: object
properties:
token:
type: string
example: d1!E2GVHgpr4h9bpxxtqUJ7EVJ1Q$Dusm2RBXg8XyVJMCBCbvyE8cGacxUx3bcUT
description: If present, this is the Token to include as the `st` query parameter for this `Public Link`. If not present, this `Public Link` has been revoked.
once:
type: boolean
description: If set to `true`, an Enketo [single submission survey](https://blog.enketo.org/single-submission-surveys/) will be created instead of a standard one, limiting respondents to a single submission each.
ExtendedPublicLink:
allOf:
- $ref: '#/components/schemas/PublicLink'
- type: object
required:
- createdBy
properties:
createdBy:
$ref: '#/components/schemas/Actor'
description: The full details about the `Actor` that created this `Public Link`.
Key:
type: object
required:
- id
- public
properties:
id:
type: number
example: 1
description: The numerical ID of the Key.
public:
type: string
example: bcFeKDF3Sg8W91Uf5uxaIlM2uK0cUN9tBSGoASbC4LeIPqx65+6zmjbgUnIyiLzIjrx4CAaf9Y9LG7TAu6wKPqfbH6ZAkJTFSfjLNovbKhpOQcmO5VZGGay6yvXrX1TFW6C6RLITy74erxfUAStdtpP4nraCYqQYqn5zD4/1OmgweJt5vzGXW2ch7lrROEQhXB9lK+bjEeWx8TFW/+6ha/oRLnl6a2RBRL6mhwy3PoByNTKndB2MP4TygCJ/Ini4ivk74iSqVnoeuNJR/xUcU+kaIpZEIjxpAS2VECJU9fZvS5Gt84e5wl/t7bUKu+dlh/cUgHfk6+6bwzqGQYOe5A==
description: The base64-encoded public key, with PEM envelope removed.
managed:
type: boolean
example: true
description: If true, this is a key generated by Project managed encryption. If not, this key is self-supplied.
hint:
type: string
example: it was a secret
description: The hint, if given, related to a managed encryption key.
DatasetDiff:
type: object
required:
- name
properties:
name:
type: string
example: people
description: The name of the Dataset.
properties:
type: array
items: {}
description: All properties of the Dataset.
DraftDatasetDiff:
type: object
required:
- name
- isNew
properties:
name:
type: string
example: people
description: The name of the Dataset.
isNew:
type: boolean
example: true
description: Whether or not this Dataset is new (will be created by publishing the Draft Form).
properties:
type: array
items: {}
description: All properties of the Dataset.
Property:
type: object
required:
- name
- inForm
properties:
name:
type: string
example: first_name
description: The name of the Property.
inForm:
type: boolean
example: true
description: Whether or not this Property is affected by the Form.
DraftProperty:
type: object
required:
- name
- inForm
- isNew
properties:
name:
type: string
example: first_name
description: The name of the Property.
inForm:
type: boolean
example: true
description: Whether or not this Property is affected by the form.
isNew:
type: boolean
example: true
description: Whether or not this Property is new (will be created by publishing the Draft Form).
PropertyDetailed:
type: object
required:
- name
- publishedAt
properties:
name:
type: string
example: the.age
description: The name of the Property.
odataName:
type: string
example: the_age
description: The name of the property as it will appear in OData. OData property names can only contain alphanumeric characters and underscores.
publishedAt:
type: string
example: '2018-01-21T00:04:11.153Z'
description: Publishing timestamp of the form that defined this property for the first time.
forms:
type: array
description: List of forms that create the property
items:
$ref: '#/components/schemas/FormKeyValue'
DatasetMetadata:
properties:
linkedForms:
type: array
items:
$ref: '#/components/schemas/FormKeyValue'
description: Forms that consume data from the Dataset
sourceForms:
type: array
items:
$ref: '#/components/schemas/FormKeyValue'
description: Forms that create Entities in the Dataset
properties:
type: array
description: All properties of the Dataset
items:
$ref: '#/components/schemas/PropertyDetailed'
Submission:
type: object
required:
- instanceId
- submitterId
- createdAt
properties:
instanceId:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
description: The `instanceId` of the `Submission`, given by the Submission XML.
submitterId:
type: number
example: 23
description: The ID of the `Actor` (`App User`, `User`, or `Public Link`) that originally submitted this `Submission`.
deviceId:
type: string
example: imei:123456
description: The self-identified `deviceId` of the device that collected the data, sent by it upon submission to the server. The initial submission `deviceId` will be returned here.
userAgent:
type: string
example: Enketo/3.0.4
description: The self-identified `userAgent` of the device that collected the data, sent by it upon submission to the server. The initial submission `userAgent` will be returned here.
reviewState:
allOf:
- $ref: '#/components/schemas/SubmissionReviewState'
- type: object
properties: {}
description: The current review state of the submission.
createdAt:
type: string
example: '2018-01-19T23:58:03.395Z'
description: ISO date format. The time that the server received the Submission.
updatedAt:
type: string
example: '2018-03-21T12:45:02.312Z'
description: ISO date format. `null` when the Submission is first created, then updated when the Submission's XML data or metadata is updated.
currentVersion:
$ref: '#/components/schemas/SubmissionVersion'
description: The current version of the `Submission`.
SubmissionVersion:
type: object
required:
- instanceId
- submitterId
- createdAt
- current
properties:
instanceId:
type: string
example: uuid:85cb9aff-005e-4edd-9739-dc9c1a829c44
description: The `instanceId` of the `Submission` version, given by the Submission XML.
instanceName:
type: string
example: village third house
description: The `instanceName`, if any, given by the Submission XML in the metadata section.
submitterId:
type: number
example: 23
description: The ID of the `Actor` (`App User`, `User`, or `Public Link`) that submitted this `Submission` version.
deviceId:
type: string
example: imei:123456
description: The self-identified `deviceId` of the device that submitted the `Submission` version.
userAgent:
type: string
example: Enketo/3.0.4
description: The self-identified `userAgent` of the device that submitted the `Submission` version.
createdAt:
type: string
example: '2018-01-19T23:58:03.395Z'
description: ISO date format. The time that the server received the `Submission` version.
current:
type: boolean
example: true
description: Whether the version is current or not.
ExtendedSubmission:
allOf:
- $ref: '#/components/schemas/Submission'
- type: object
required:
- submitter
properties:
submitter:
$ref: '#/components/schemas/Actor'
description: The full details of the `Actor` that submitted this `Submission`.
ExtendedSubmissionVersion:
allOf:
- $ref: '#/components/schemas/SubmissionVersion'
- type: object
required:
- submitter
properties:
submitter:
$ref: '#/components/schemas/Actor'
description: The full details of the `Actor` that submitted this version of the `Submission`.
formVersion:
type: string
example: '1.0'
description: The version of the form the submission version was created against. Only returned with specific Submission Version requests.
ReviewStateCounts:
type: object
required:
- received
- hasIssues
- edited
properties:
received:
type: number
example: 3
description: The number of submissions receieved with no other review state.
hasIssues:
type: number
example: 2
description: The number of submissions marked as having issues.
edited:
type: number
example: 1
description: The number of edited submissions.
SubmissionAttachment:
type: object
required:
- name
- exists
properties:
name:
type: string
example: myfile.mp3
description: The name of the file as specified in the Submission XML.
exists:
type: boolean
example: true
description: Whether the server has the file or not.
SubmissionReviewState:
type: string
enum:
- 'null'
- edited
- hasIssues
- rejected
- approved
SubmissionDiffValue:
type: object
properties:
new:
type: string
description: The new value of this node, which can either be a simple string, or JSON string representing a larger structural change to the Submission XML. It can also be null if this field no longer exists in the Submission.
old:
type: string
description: The old value of this node, with similar properties to `new`. It can be null if this field did not exist previously.
path:
type: array
items: {}
description: An array representing the path (XPath) in the Submission tree for this node. It does not include the outermost path `data`. For elements that are part of repeat groups, the path element is the node name and the index (starting at 0), e.g. ['child', 2] is the third child.
Audit:
type: object
required:
- action
- loggedAt
properties:
actorId:
type: number
example: 42
description: The ID of the actor, if any, that initiated the action.
action:
type: string
example: form.create
description: The action that was taken.
acteeId:
type: string
example: 85cb9aff-005e-4edd-9739-dc9c1a829c44
description: The ID of the permissioning object against which the action was taken.
details:
type: object
properties: {}
description: Additional details about the action that vary according to the type of action.
loggedAt:
type: string
example: '2018-04-18T23:19:14.802Z'
description: ISO date format
ExtendedAudit:
allOf:
- $ref: '#/components/schemas/Audit'
- type: object
properties:
actor:
$ref: '#/components/schemas/Actor'
description: The details of the actor given by `actorId`.
actee:
type: object
properties: {}
description: The details of the actee given by `acteeId`. Depending on the action type, this could be a number of object types, including an `Actor`, a `Project`, or a `Form`.
Comment:
type: object
required:
- body
- actorId
properties:
body:
type: string
example: this is my comment
description: The text of the comment.
actorId:
type: number
example: 42
description: The ID of the Actor that made the comment.
ExtendedComment:
allOf:
- $ref: '#/components/schemas/Comment'
- type: object
properties:
actor:
$ref: '#/components/schemas/Actor'
description: The details of the actor given by `actorId`.
Success:
type: object
required:
- success
properties:
success:
type: boolean
example:
success: true
Error400:
type: object
required:
- code
properties:
code:
type: number
example: 400
details:
type: object
properties: {}
description: a subobject that contains programmatically readable details about this error
message:
type: string
example: Could not parse the given data (2 chars) as json.
Error401:
type: object
required:
- code
properties:
code:
type: number
example: 401.2
message:
type: string
example: Could not authenticate with the provided credentials.
Error403:
type: object
required:
- code
properties:
code:
type: number
example: 403.1
message:
type: string
example: The authenticated actor does not have rights to perform that action.
Error404:
type: object
required:
- code
properties:
code:
type: number
example: 404.1
message:
type: string
example: Could not find the resource you were looking for.
Error406:
type: object
required:
- code
properties:
code:
type: number
example: 406.1
message:
type: string
example: 'Requested format not acceptable; this resource allows: (application/json, json).'
Error409:
type: object
required:
- code
properties:
code:
type: number
example: 409.1
message:
type: string
example: A resource already exists with id value(s) of 1.
Error501:
type: object
required:
- code
properties:
code:
type: number
example: 501.1
message:
type: string
example: The requested feature $unsupported is not supported by this server.