openapi: 3.0.0 servers: - url: '/api/v3' info: version: 3.0.4 title: Nightscout API contact: name: NS development discussion channel url: https://gitter.im/nightscout/public license: name: AGPL 3 url: 'https://www.gnu.org/licenses/agpl.txt' description: Nightscout API v3 is a component of cgm-remote-monitor project. It aims to provide lightweight, secured and HTTP REST compliant interface for your T1D treatment data exchange. API v3 uses these environment variables, among other things: - Security switch (optional, default = `true`)
API3_SECURITY_ENABLE=trueYou can turn the whole security mechanism off, e.g. for debugging or development purposes, but this should never be set to false in production. - Maximum limit count of documents retrieved from single query
API3_MAX_LIMIT=1000- Autopruning of obsolete documents (optional, default is only `DEVICESTATUS`=60)
API3_AUTOPRUNE_DEVICESTATUS=60
API3_AUTOPRUNE_ENTRIES=365
API3_AUTOPRUNE_TREATMENTS=120
You can specify for which collections autopruning will be activated and length of retention period in days, e.g. "Hold 60 days of devicestatus, automatically delete older documents, hold 365 days of treatments and entries, automatically delete older documents."
- Fallback deduplication switch (optional, default = true)
API3_DEDUP_FALLBACK_ENABLED=trueAPI3 uses the `identifier` field for document identification and mutual distinction within a single collection. There is automatic deduplication implemented matching the equal `identifier` field. E.g. `CREATE` operation for document having the same `identifier` as another one existing in the database is automatically transformed into `UPDATE` operation of the document found in the database. Documents not created via API v3 usually does not have any `identifier` field, but we would like to have some form of deduplication for them, too. This fallback deduplication is turned on by having set `API3_DEDUP_FALLBACK_ENABLED` to `true`. When searching the collection in database, the document is found to be a duplicate only when either he has equal `identifier` or he has no `identifier` and meets:
`devicestatus` collection: equal combination of `created_at` and `device`
`entries` collection: equal combination of `date` and `type`
`food` collection: equal `created_at`
`profile` collection: equal `created_at`
`treatments` collection: equal combination of `created_at` and `eventType`
- Fallback switch for adding `created_at` field along the `date` field (optional, default = true)
API3_CREATED_AT_FALLBACK_ENABLED=trueStandard APIv3 document model uses only `date` field for storing a timestamp of the event recorded by the document. But there is a fallback option to fill `created_at` field as well automatically on each insert/update, just to keep all older components working. tags: - name: generic description: Generic operations with each database collection (devicestatus, entries, food, profile, settings, treatments) - name: other description: All other various operations paths: /{collection}: parameters: - in: path name: collection description: Collection to which the operation is targeted required: true schema: $ref: '#/components/schemas/paramCollection' ###################################################################################### get: tags: - generic summary: 'SEARCH: Search documents from the collection' operationId: SEARCH description: General search operation through documents of one collection, matching the specified filtering criteria. You can apply: 1) filtering - combining any number of filtering parameters 2) ordering - using `sort` or `sort$desc` parameter 3) paging - using `limit` and `skip` parameters If successful, HTTP 200 code is returned with JSON array of matching documents as a response content (it may be empty). This operation requires `read` permission for the API and the collection (e.g. `*:*:read`, `api:*:read`, `*:treatments:read`, `api:treatments:read`). The only exception is the `settings` collection which requires `admin` permission (`api:settings:admin`), because the settings of each application should be isolated and kept secret. You need to know the concrete identifier to access the app's settings. parameters: - $ref: '#/components/parameters/filterParams' - $ref: '#/components/parameters/sortParam' - $ref: '#/components/parameters/sortDescParam' - $ref: '#/components/parameters/limitParam' - $ref: '#/components/parameters/skipParam' - $ref: '#/components/parameters/fieldsParam' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/search200' 400: $ref: '#/components/responses/400BadRequest' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 406: $ref: '#/components/responses/406NotAcceptable' ###################################################################################### post: tags: - generic summary: 'CREATE: Inserts a new document into the collection' description: Using this operation you can insert new documents into collection. Normally the operation ends with 201 HTTP status code, `Last-Modified` and `Location` headers specified. `identifier` is included in response body or it can be parsed from the `Location` response header. When the document to post is marked as a duplicate (using rules described at `API3_DEDUP_FALLBACK_ENABLED` switch), the update operation takes place instead of inserting. In this case the original document in the collection is found and it gets updated by the actual operation POST body. Finally the operation ends with 200 HTTP status code along with `Last-Modified` and correct `Location` headers. The response body then includes `isDeduplication`=`true` and `deduplicatedIdentifier` fields. This operation provides autopruning of the collection (if autopruning is enabled). This operation requires `create` (and/or `update` for deduplication) permission for the API and the collection (e.g. `api:treatments:create` and `api:treatments:update`) requestBody: description: JSON with new document to insert required: true content: application/json: schema: $ref: '#/components/schemas/DocumentToPost' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/200Deduplication' 201: $ref: '#/components/responses/201CreatedLocation' 400: $ref: '#/components/responses/400BadRequest' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 422: $ref: '#/components/responses/422UnprocessableEntity' #return HTTP STATUS 400 for all other verbs (PUT, PATCH, DELETE,...) /{collection}/{identifier}: parameters: - in: path name: collection description: Collection to which the operation is targeted required: true schema: $ref: '#/components/schemas/paramCollection' - in: path name: identifier description: Identifier of the document to which the operation is targeted required: true schema: $ref: '#/components/schemas/paramIdentifier' ###################################################################################### get: tags: - generic summary: 'READ: Retrieves a single document from the collection' description: Basically this operation looks for a document matching the `identifier` field returning 200 or 404 HTTP status code. If the document has been found in the collection but it had already been deleted, 410 HTTP status code is to be returned. When `If-Modified-Since` header is used and its value is greater than the timestamp of the document in the collection, 304 HTTP status code with empty response content is returned. It means that the document has not been modified on server since the last retrieval to client side. With `If-Modified-Since` header and less or equal timestamp `srvModified` a normal 200 HTTP status with full response is returned. This operation requires `read` permission for the API and the collection (e.g. `api:treatments:read`) parameters: - $ref: '#/components/parameters/ifModifiedSinceHeader' - $ref: '#/components/parameters/fieldsParam' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/read200' 304: $ref: '#/components/responses/304NotModified' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 406: $ref: '#/components/responses/406NotAcceptable' 410: $ref: '#/components/responses/410Gone' ###################################################################################### put: tags: - generic summary: 'UPDATE: Updates a document in the collection' description: Normally the document with the matching `identifier` will be replaced in the collection by the whole JSON request body and 200 HTTP status code will be returned. If the document has been found in the collection but it had already been deleted, 410 HTTP status code is to be returned. When no document with `identifier` has been found in the collection, then an insert operation takes place instead of updating. Finally 201 HTTP status code is returned with only `Last-Modified` header (`identifier` is already known from the path parameter). You can also specify `If-Unmodified-Since` request header including your timestamp of document's last modification. If the document has been modified by somebody else on the server afterwards (and you do not know about it), the 412 HTTP status code is returned cancelling the update operation. You can use this feature to prevent race condition problems. This operation provides autopruning of the collection (if autopruning is enabled). This operation requires `update` (and/or `create`) permission for the API and the collection (e.g. `api:treatments:update` and `api:treatments:create`) parameters: - $ref: '#/components/parameters/ifUnmodifiedSinceHeader' requestBody: description: JSON of new version of document (`identifier` in JSON is ignored if present) required: true content: application/json: schema: $ref: '#/components/schemas/DocumentToPost' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/200Ok' 201: $ref: '#/components/responses/201Created' 400: $ref: '#/components/responses/400BadRequest' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 412: $ref: '#/components/responses/412PreconditionFailed' 410: $ref: '#/components/responses/410Gone' 422: $ref: '#/components/responses/422UnprocessableEntity' ###################################################################################### patch: tags: - generic summary: 'PATCH: Partially updates document in the collection' description: Normally the document with the matching `identifier` will be retrieved from the collection and it will be patched by all specified fields from the JSON request body. Finally 200 HTTP status code will be returned. If the document has been found in the collection but it had already been deleted, 410 HTTP status code is to be returned. When no document with `identifier` has been found in the collection, then the operation ends with 404 HTTP status code. You can also specify `If-Unmodified-Since` request header including your timestamp of document's last modification. If the document has been modified by somebody else on the server afterwards (and you do not know about it), the 412 HTTP status code is returned cancelling the update operation. You can use this feature to prevent race condition problems. `PATCH` operation can save some bandwidth for incremental document updates in comparison with `GET` - `UPDATE` operation sequence. While patching the document, the field `modifiedBy` is automatically set to the authorized subject's name. This operation provides autopruning of the collection (if autopruning is enabled). This operation requires `update` permission for the API and the collection (e.g. `api:treatments:update`) parameters: - $ref: '#/components/parameters/ifUnmodifiedSinceHeader' requestBody: description: JSON of new version of document (`identifier` in JSON is ignored if present) required: true content: application/json: schema: $ref: '#/components/schemas/DocumentToPost' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/200Ok' 400: $ref: '#/components/responses/400BadRequest' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 410: $ref: '#/components/responses/410Gone' 412: $ref: '#/components/responses/412PreconditionFailed' 422: $ref: '#/components/responses/422UnprocessableEntity' ###################################################################################### delete: tags: - generic summary: 'DELETE: Deletes a document from the collection' description: If the document has already been deleted, the operation will succeed anyway. Normally, documents are not really deleted from the collection but they are only marked as deleted. For special cases the deletion can be irreversible using `permanent` parameter. This operation provides autopruning of the collection (if autopruning is enabled). This operation requires `delete` permission for the API and the collection (e.g. `api:treatments:delete`) parameters: - $ref: '#/components/parameters/permanentParam' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/200Ok' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 422: $ref: '#/components/responses/422UnprocessableEntity' ###################################################################################### /{collection}/history: parameters: - in: path name: collection description: Collection to which the operation is targeted required: true schema: $ref: '#/components/schemas/paramCollection' get: tags: - generic summary: 'HISTORY: Retrieves incremental changes since timestamp' operationId: HISTORY description: HISTORY operation is intended for continuous data synchronization with other systems. Every insertion, update and deletion will be included in the resulting JSON array of documents (since timestamp in `Last-Modified` request header value). All changes are listed chronologically in response with 200 HTTP status code. The maximum listed `srvModified` timestamp is also stored in `Last-Modified` and `ETag` response headers that you can use for future, directly following synchronization. You can also limit the array's length using `limit` parameter. Deleted documents will appear with `isValid` = `false` field. HISTORY operation has a fallback mechanism in place for documents, which were not created by API v3. For such documents `srvModified` is virtually assigned from the `date` field (for `entries` collection) or from the `created_at` field (for other collections). This operation requires `read` permission for the API and the collection (e.g. `api:treatments:read`) The only exception is the `settings` collection which requires `admin` permission (`api:settings:admin`), because the settings of each application should be isolated and kept secret. You need to know the concrete identifier to access the app's settings. parameters: - $ref: '#/components/parameters/lastModifiedRequiredHeader' - $ref: '#/components/parameters/limitParam' - $ref: '#/components/parameters/fieldsParam' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/history200' 400: $ref: '#/components/responses/400BadRequest' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 406: $ref: '#/components/responses/406NotAcceptable' ###################################################################################### /{collection}/history/{lastModified}: parameters: - in: path name: collection description: Collection to which the operation is targeted required: true schema: $ref: '#/components/schemas/paramCollection' - in: path name: lastModified description: Starting timestamp (in UNIX epoch format, defined with respect to server's clock) since which the changes in documents are to be listed. Query for modified documents is made using "greater than" operator (not including equal timestamps). required: true schema: type: integer format: int64 get: tags: - generic summary: 'HISTORY: Retrieves incremental changes since timestamp' operationId: HISTORY2 description: This HISTORY operation variant is more precise than the previous one with `Last-Modified` request HTTP header), because it does not loose milliseconds precision. Since this variant queries for changed documents by timestamp precisely and exclusively, the last modified document does not repeat itself in following calls. That is the reason why is this variant more suitable for continuous synchronization with other systems. This variant behaves quite the same as the previous one in all other aspects. parameters: - $ref: '#/components/parameters/limitParam' - $ref: '#/components/parameters/fieldsParam' security: - jwtoken: [] responses: 200: $ref: '#/components/responses/history200' 400: $ref: '#/components/responses/400BadRequest' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' 404: $ref: '#/components/responses/404NotFound' 406: $ref: '#/components/responses/406NotAcceptable' ###################################################################################### /version: get: tags: - other summary: 'VERSION: Returns actual version information' description: No authentication is needed for this commnad (it is public) responses: 200: description: Successful response content: application/json: schema: $ref: '#/components/schemas/Version' ###################################################################################### /status: get: tags: - other summary: 'STATUS: Returns actual version information and all permissions granted for API' description: This operation requires authorization in contrast with VERSION operation. security: - jwtoken: [] responses: 200: description: Successful response content: application/json: schema: $ref: '#/components/schemas/Status' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' ###################################################################################### /lastModified: get: tags: - other summary: 'LAST MODIFIED: Retrieves timestamp of the last modification of every collection' operationId: LAST-MODIFIED description: LAST MODIFIED operation inspects collections separately (in parallel) and for each of them it finds the date of any last modification (insertion, update, deletion). Not only `srvModified`, but also `date` and `created_at` fields are inspected (as a fallback to previous API). This operation requires `read` permission for the API and the collections (e.g. `api:treatments:read`). For each collection the permission is checked separately, you will get timestamps only for those collections that you have access to. security: - jwtoken: [] responses: 200: $ref: '#/components/responses/lastModified200' 401: $ref: '#/components/responses/401Unauthorized' 403: $ref: '#/components/responses/403Forbidden' ###################################################################################### components: parameters: limitParam: in: query name: limit schema: type: integer minimum: 1 default: stored in API3_MAX_LIMIT environment variable (usually 1000) example: 100 description: Maximum number of documents to get in result array skipParam: in: query name: skip schema: type: integer minimum: 0 default: 0 example: 0 description: Number of documents to skip from collection query before loading them into result array (used for pagination) sortParam: in: query name: sort schema: type: string required: false description: Field name by which the sorting of documents is performed. This parameter cannot be combined with `sort$desc` parameter. sortDescParam: in: query name: sort$desc schema: type: string required: false description: Field name by which the descending (reverse) sorting of documents is performed. This parameter cannot be combined with `sort` parameter. permanentParam: in: query name: permanent schema: type: boolean required: false description: If true, the deletion will be irreversible and it will not appear in `HISTORY` operation. Normally there is no reason for setting this flag. fieldsParam: in: query name: fields schema: type: string default: '_all' required: false examples: all: value: '_all' summary: All fields will be returned (default behaviour) customSet: value: 'date,insulin' summary: Only fields date and insulin will be returned description: A chosen set of fields to return in response. Either you can enumerate specific fields of interest or use the predefined set. Sample parameter values: _all: All fields will be returned (default value) date,insulin: Only fields `date` and `insulin` will be returned filterParams: in: query name: filter_parameters schema: type: string description: Any number of filtering operators. Each filtering operator has name like `
Last-Modified: Wed, 17 Oct 2018 05:13:00 GMTifModifiedSinceHeader: in: header name: If-Modified-Since schema: type: string required: false description: Timestamp (defined with respect to server's clock) of the last document modification formatted as: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT If this header is present, the operation will compare its value with the srvModified timestamp of the document at first and the operation result then may differ. The srvModified timestamp was defined by server's clock. Example:
If-Modified-Since: Wed, 17 Oct 2018 05:13:00 GMTifUnmodifiedSinceHeader: in: header name: If-Unmodified-Since schema: type: string required: false description: Timestamp (defined with respect to server's clock) of the last document modification formatted as: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT If this header is present, the operation will compare its value with the srvModified timestamp of the document at first and the operation result then may differ. The srvModified timestamp was defined by server's clock. Example:
If-Unmodified-Since: Wed, 17 Oct 2018 05:13:00 GMT###################################################################################### responses: 200Ok: description: The request was successfully processed content: application/json: schema: properties: status: type: integer example: 200 200Deduplication: description: Successfully updated a duplicate document in the collection headers: 'Last-Modified': $ref: '#/components/schemas/headerLastModified' 'Location': $ref: '#/components/schemas/headerLocation' content: application/json: schema: properties: status: type: integer example: 200 identifier: $ref: '#/components/schemas/identifierField' isDeduplication: $ref: '#/components/schemas/isDeduplicationField' deduplicatedIdentifier: $ref: '#/components/schemas/deduplicatedIdentifierField' 201Created: description: Successfully created a new document in collection headers: 'Last-Modified': $ref: '#/components/schemas/headerLastModified' content: application/json: schema: properties: status: type: integer example: 201 identifier: $ref: '#/components/schemas/identifierField' lastModified: $ref: '#/components/schemas/lastModifiedField' 201CreatedLocation: description: Successfully created a new document in collection headers: 'Last-Modified': $ref: '#/components/schemas/headerLastModified' 'Location': $ref: '#/components/schemas/headerLocation' content: application/json: schema: properties: status: type: integer example: 201 identifier: $ref: '#/components/schemas/identifierField' lastModified: $ref: '#/components/schemas/lastModifiedField' 304NotModified: description: The document has not been modified on the server since timestamp specified in If-Modified-Since header headers: 'Last-Modified': $ref: '#/components/schemas/headerLastModified' 400BadRequest: description: The request is malformed. There may be some required parameters missing or there are unrecognized parameters present. content: application/json: schema: properties: status: type: integer example: 400 401Unauthorized: description: The request was not successfully authenticated using JWT, so that the request cannot continue due to the security policy. content: application/json: schema: properties: status: type: integer example: 401 403Forbidden: description: Insecure HTTP scheme used or the request has been successfully authenticated, but the security subject is not authorized for the operation. content: application/json: schema: properties: status: type: integer example: 403 404NotFound: description: The collection or document specified was not found. content: application/json: schema: properties: status: type: integer example: 404 406NotAcceptable: description: The requested content type (in `Accept` header) is not supported. content: application/json: schema: properties: status: type: integer example: 406 412PreconditionFailed: description: The document has already been modified on the server since specified timestamp (in If-Unmodified-Since header). content: application/json: schema: properties: status: type: integer example: 412 410Gone: description: The requested document has already been deleted. content: application/json: schema: properties: status: type: integer example: 410 422UnprocessableEntity: description: The client request is well formed but a server validation error occured. Eg. when trying to modify or delete a read-only document (having `isReadOnly=true`). content: application/json: schema: properties: status: type: integer example: 422 search200: description: Successful operation returning array of documents matching the filtering criteria content: application/json: schema: properties: status: type: integer example: 200 result: $ref: '#/components/schemas/DocumentArray' text/csv: schema: $ref: '#/components/schemas/DocumentArray' application/xml: schema: $ref: '#/components/schemas/DocumentArray' read200: description: The document has been succesfully found and its JSON form returned in the response content. content: application/json: schema: properties: status: type: integer example: 200 result: $ref: '#/components/schemas/Document' text/csv: schema: $ref: '#/components/schemas/Document' application/xml: schema: $ref: '#/components/schemas/Document' headers: 'Last-Modified': $ref: '#/components/schemas/headerLastModified' history200: description: Changed documents since specified timestamp content: application/json: schema: properties: status: type: integer example: 200 result: $ref: '#/components/schemas/DocumentArray' text/csv: schema: $ref: '#/components/schemas/DocumentArray' application/xml: schema: $ref: '#/components/schemas/DocumentArray' headers: 'Last-Modified': $ref: '#/components/schemas/headerLastModifiedMaximum' 'ETag': $ref: '#/components/schemas/headerEtagLastModifiedMaximum' lastModified200: description: Successful operation returning the timestamps content: application/json: schema: properties: status: type: integer example: 200 result: $ref: '#/components/schemas/LastModifiedResult' ###################################################################################### schemas: headerLocation: type: string description: Location of document - the relative part of URL. This can be used to parse the identifier of just created document. Example=/api/v3/treatments/53409478-105f-11e9-ab14-d663bd873d93 headerLastModified: type: string description: Timestamp of the last document modification on the server, formatted as '