Swagger / OpenAPI Specification. To view an interactive version of the Swagger specification, you can go to Swagger Hub.
The Documents API is designed to streamline the process of downloading and uploading files to a common data environment (CDE). This specification details the selection or discovery, download and upload of files. When supported by both client and server, it provides an easy to use and integrated way of syncing cloud stored documents from within local applications. For the purpose of this specification, a document consists of a file and its metadata. The scope of the Documents API includes all file types; the scope is not limited to building information models.
Get a quick overview of the Documents API in this video
The Open CDE workgroup develops the Documents API standard. The group meets every second Monday at 11am CET. To join the fortnightly meeting please email opencde@buildingsmart.org.
Documents API is a member of the OpenCDE API family. All OpenCDE APIs are united by a shared common API called OpenCDE Foundation API.
The foundation API specifies a small number of services and a few conventions that are common to all OpenCDE APIs. All Documents API implementations must implement the Foundation API and follow its conventions and guidelines. Implementers should start by implementing the Foundation API and only then continue to implement the Documents API.
Note: Other APIs built on top of the OpenCDE Foundation API include the BCF API for the BIM Collaboration Format.
The Documents API identifies the following actors:
The Documents API is designed to allow a User working with a compatible Client Applications to upload and download files from any compatible CDE. This is accomplished by a hand-shake that allows the Client Application to direct the User to the CDE's web interface when the User's interaction with the CDE is needed. The CDE retains the information entered by the User and communicates with the Client using a file-based API. For example: When commencing a document download the User would search and select Documents on the CDE's web interface. The Client Application performs the actual file download using a direct, file-based API call to the CDE.
The Documents API is designed to support the following use cases:
The User, using the Client Application searches for files on the CDE's web UI and selects files to download. The Client Application then downloads the files and makes them available to the User who performs their task in the Client Application.
The Client Application calls the CDE to query for new versions of documents previously downloaded and/or uploaded by the User. The CDE responds that new document versions are available to download. The Client Application obtains the User's approval and downloads the new versions and makes them available to the User.
The User, using the Client Application, selects local files to upload to the CDE. The Client Application directs the User to the CDE Web UI where the User enters, for each file, the document metadata as required by the CDE. The Client Application then uploads the files to the CDE. The CDE combines the files with the user-entered metadata and registers new document versions. The User can continue using the Client Application while the files are uploaded in the background.
Documents API and BCF API can be used together by a Client Application that has implemented both APIs. A User who is working with a Client Application that implements both APIs can download models directly from the CDE using the Documents API and manage issues relating to those models using the BCF API. A configuration, where documents are controlled by one CDE and BCF issues are controlled by another CDE is also supported.
BCF API compatible servers offer endpoints to list project model files, which are stored on a CDE. To indicate that models provided by BCF API file-references can be downloaded from the CDE using the Documents API, the reference
part of a file_GET
response from the BCF server will include the URL scheme (protocol) open-cde-documents
and a link to the document_version
URL on the CDE.
The actual URL scheme (protocol) that a Client Application should use to call the document_version
URL should be https
.
BCF API project_file_information
example:
{
"display_information": [
{
"field_display_name": "Model Name",
"field_value": "ARCH-Z100-051"
}
],
"file": {
"ifc_project": "0J$yPqHBD12v72y4qF6XcD",
"file_name": "OfficeBuilding_Architecture_0001.ifc",
"reference": "open-cde-documents://<document_version_url>"
}
}
In the example above, the CDE returns a value of open-cde-documents://<document_version_url>
for the file reference
part, indicating that a Documents API capable client can call https://<document_version_url>
to get the document version information. From there on, compatible clients can retrieve metadata and the binary content of the file.
The BCF API documentation about project file references can be found here: https://github.com/buildingSMART/BCF-API#331-get-project-files-information-service
This use case is not yet supported. It will be added in the future.
Documents API is specified using Open API. You can find the Open API specification here. The specification can be used to automatically generate client and server code, although most of the endpoints will not work directly, since the API is built with few fixed endpoints. Most of the endpoints are discovered and received in the returned payloads of the calls. The dynamic endpoints start with server-provided-path-
.
The reason for using dynamic endpoints is to make the implementation of the API on the server easy and efficient. For example, when a link to download a document is retrieved from the service, that link can point to an already existing API endpoint, or even to a third party storage or file hosting service.
The Open API specification is the single source of truth for implementing the Documents API. This documentation is supporting material that clarifies different workflows. If there are any contradictions between this document and the Open API specification, the latter prevails.
There is an open source example project available, which contains both a desktop based client app as well as a server implementation.
The client initiates the document selection by sending a POST request to the CDEs /select-documents endpoint.
In the callback
part the client passes a URL unto which to later redirect the user from the browser session. In this example, the client is listening locally on port 8080
and the callback URL will expire in 3600 seconds (one hour).
The client is using the optional server_context
in this example to provide a guid value which was obtained, from the CDE, in a previous document exchange. The server_context
informs the CDE of the user's previous activity (e.g. a "project" or a directory on the CDE). The CDE can use the server_context
to resume the document selection session from where the user has last left.
The supported_file_extensions
is an optional array where the client specifies that the CDE should limit the user to select only files with the extensions .ifc
or .ifczip
.
POST /select-documents
Body:
{
"server_context": "711c0744-0a92-489f-8ca1-13813aa2dee7",
"callback": {
"url": "http://localhost:8080/cde-callback-example",
"expires_in": 3600
},
"supported_file_extensions": [
".ifc",
".ifczip"
]
}
The server returns a response to inform the client about the select_documents_url
which should be opened in a local web browser. The expires_in
property specifies the URL's validity, in seconds.
{
"select_documents_url": "https://cde.example.com/document-selection?selection_session=7c41c859-c0c1-4914-ac6c-8fbd50fb8247",
"expires_in": 60
}
It is highly recommended for CDEs to ensure that select_documents_url
is a short-lived, single-use and random URL. The URL should expire after its first use and in close proximity to the CDE response. There should be no pattern that would allow an attacker to guess and exploit a valid URL.
The client has now opened the local browser with the URL https://cde.example.com/document-selection?selection_session=7c41c859-c0c1-4914-ac6c-8fbd50fb8247
.
Next, the user interacts with the native CDE UI to search and select documents.
After the user has completed the selection, the CDE redirects the user's browser to the client-provided callback.url
and appends the selected_documents_url
query parameter.
http://localhost:8080/cde-callback-example?selected_documents_url=https%3A%2F%2Fcde.example.com%2Fdownload-instructions%3Fsession_id%3Db59dab23-79a4-4e66-a1a7-8837871604fa
The value of the selected_documents_url
query parameter is a URL on the CDE. The client will call this URL to get the details about the documents the user has selected in this download session.
In the example above, the browser was redirected to the local callback URL provided by client and the value of the selected_documents_url
query parameter is https://cde.example.com/download-instructions?session_id=b59dab23-79a4-4e66-a1a7-8837871604fa
. Please note that the example is URL-encoded.
Note: It is recommended that CDEs provide a pre-authenticated URL with the
selected_documents_url
parameter, so that users can quickly select the documents they wish to download. The preauthenticated URL must retain the user identity associated with the OAuth2 token that was provided by the client when the download was initiated.
After having received the callback from the CDE UI, the client now sends a request to get the user selected documents from the CDE.
GET https://cde.example.com/download-instructions?session_id=b59dab23-79a4-4e66-a1a7-8837871604fa
Response:
{
"server_context": "5a0b9c95-481c-4eb0-b564-0d04837c669d",
"documents": [
{
"links": {
"document_version": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0"
},
"document_version_metadata": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0/metadata"
},
"document_version_download": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0/download"
},
"document_versions": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions"
},
"document_details": {
"url": "https://cde.example.com/ui/projects/12485/documents/bf546064-6b97-4730-a094-c21ab929c91a/v3.0"
}
},
"version_number": "v3.0",
"version_index": 3,
"creation_date": "2022-03-09T08:02:53.866Z",
"title": "Sample Document",
"file_description": {
"name": "model.ifc",
"size_in_bytes": 1048576
},
"document_id": "bf546064-6b97-4730-a094-c21ab929c91a"
}
]
}
The response returned from the server contains an optional server_context
property, which the client can use in future selection or upload sessions as discussed above.
The documents
array contains a list of the document versions that the user has selected. Each document version contain basic document metadata as well as links
which the client can use to obtain additional information.
Link | Description |
---|---|
document_version |
This url points to the object itself |
document_version_metadata |
The metadata for document versions is a list of key-value pairs |
document_version_download |
The url to download the binary content of this document version. May either directly return the result or redirect to a storage provider |
document_versions |
This url returns a list of all document versions for the parent document. The client can use this URL to monitor for new document versions |
document_details |
This optional url points to the CDE UI itself, meaning it can be opened by the local browser to show the document version in the native CDE UI |
The upload flow starts with the user selecting which files to upload to the CDE.
The client assigns each file a temporary unique id (session id) and then initiates the upload with the server providing the file names and session ids for each file.
After that, a local browser is launched and the user is presented with the web UI of the CDE, where they enter the document metadata as required by the CDE.
When the user is finished entering the metadata then the CDE, via a browser redirect, shares a callback URL with the client.
The client sends a POST to this URL with additional information (file sizes). The CDE responds with detailed upload instructions specifying the exact sequence of request the client should perform to upload each file to the CDE.
The client proceeds to upload the files as specified by the CDE. After all file parts are uploaded, the client will send the upload completion request. When the upload is complete, the CDE provides the client with the document version information.
It is highly recommended that for the upload completion request, the server periodically send a whitespace character back to the client to keep the connection from timing out, since upload completion call can take up to several minutes to respond depending on the size of the file uploaded.
The session_file_id
property used in the components (FileToUpload
, UploadFileDetails
, DocumentToUpload
) related to uploading files is a client-generated identifier that is only used during upload. It doesn't need to be persisted between upload sessions. It is used to relate the information given in different phases of the workflow to the individual files that are being processed.
The CDE requires the file size to generate a detailed request sequence for the client. The client sends the file size only after the user has entered the document metadata in the CDE web UI. This supports the case when the client doesn't yet have the local file available when the upload workflow starts.
For example, when a CAD tool exports an IFC file to the server, creating the IFC can take a long time. With the chosen workflow, the CAD tool can create the IFC while the user is entering document metadata using the CDE web UI.
The client initiates the document upload by sending a POST request to the CDEs /upload-documents endpoint.
In the callback
part the client passes a URL unto which to later redirect the user from the browser session. In this example, the client is listening locally on port 8080 and the callback URL will expire in 3600 seconds (one hour).
The client is using the optional server_context
in this example to provide a guid value which was obtained, from the CDE, in a previous document exchange. The server_context
informs the CDE of the user's previous activity (e.g. a "project" or a directory on the CDE). The CDE can use the server_context
to resume the document upload session from where the user has last left.
The files
array has a single element, and this file was assigned a client generated session_file_id
, see 3.3.1.2. Identifying Files During the Workflow.
POST /upload-documents
Body:
{
"server_context": "7188a2be-6c4e-4e3b-b7e7-cd27f0d4ad67",
"callback": {
"url": "http://localhost:8080/cde-callback-example",
"expires_in": 3600
},
"files": [
{
"file_name": "model.ifc",
"session_file_id": "76ec9d91-0731-4405-b3c4-9bf945f9955b"
}
]
}
The server returns a response to inform the client about the upload_ui_url
which should be opened in a local web browser. The expires_in
property specifies the URL's validity, in seconds, and the optional property max_size_in_bytes
can be used to indicate if there is a file size limit for uploading.
{
"upload_ui_url": "https://cde.example.com/document-upload?upload_session=7c41c859-c0c1-4914-ac6c-8fbd50fb8247",
"expires_in": 60,
"max_size_in_bytes": 1073741824
}
It is highly recommended for CDEs to ensure that upload_ui_url
is a short-lived, single-use and random URL. The URL should expire after its first use and in close proximity to the CDE response. There should be no pattern that would allow an attacker to guess and exploit a valid URL.
The client has now opened the local browser with the url https://cde.example.com/document-upload?upload_session=7c41c859-c0c1-4914-ac6c-8fbd50fb8247
.
Next, the user enters document metadata using the native CDE UI.
After the user has entered the document metadata, the CDE redirects the user's browser to the client-given callback.url
and appends the upload_documents_url
query parameter.
http://localhost:8080/cde-callback-example?upload_documents_url=https%3A%2F%2Fcde.example.com%2Fupload-instructions%3Fupload_session%3Dee56b8f3-8f93-4819-976e-46a45a5a996f
The value of the upload_documents_url
query parameter is a URL on the CDE. The client will call this URL to get upload instructions for each file.
In the example above, the browser was redirected to the local callback URL provided by client and the value of the upload_documents_url
query parameter is https://cde.example.com/upload-instructions?upload_session=ee56b8f3-8f93-4819-976e-46a45a5a996f
. Please note that the example is URL-encoded.
Note: It is recommended that CDEs provide a pre-authenticated URL for the
upload_ui_url
parameter, so that users can quickly enter the metadata for the documents they wish to upload. The preauthenticated URL must retain the user identity associated with the OAuth2 token that was provided by the client when the upload was initiated.
The client now sends a POST
request to the server provided upload_documents_url
to receive the instructions for how to upload the files.
POST https://cde.example.com/upload-instructions?upload_session=ee56b8f3-8f93-4819-976e-46a45a5a996f
Body:
{
"files": [
{
"size_in_bytes": "1048576",
"session_file_id": "76ec9d91-0731-4405-b3c4-9bf945f9955b"
}
]
}
In the response, the CDE returns the upload instructions.
{
"server_context": "ee56b8f3-8f93-4819-976e-46a45a5a996f",
"documents_to_upload": [
{
"session_file_id": "76ec9d91-0731-4405-b3c4-9bf945f9955b",
"upload_file_parts": [
{
"url": "https://cde-storage.example.com/8d9f94b5-125c-4f88-afbb-494bd9cd3356",
"http_method": "PUT",
"additional_headers": {
"values": [
{
"name": "Content-Length",
"value": "524288"
}
]
},
"multipart_form_data": {
"prefix": "U0VSVkVSX1NUQVJU",
"suffix": "U0VSVkVSX0VORA=="
},
"include_authorization": false,
"content_range_start": 0,
"content_range_end": 524287
},
{
"url": "https://cde-storage.example.com/2271db11-e24b-4b8c-9622-3ed63dc38e48",
"http_method": "PUT",
"additional_headers": {
"values": [
{
"name": "Content-Length",
"value": "524310"
}
]
},
"multipart_form_data": {
"prefix": "U0VSVkVSX1NUQVJU",
"suffix": "U0VSVkVSX0VORA=="
},
"include_authorization": false,
"content_range_start": 524288,
"content_range_end": 1048575
}
],
"upload_completion": {
"url": "https://cde.example.com/upload-completion?upload_session=ee56b8f3-8f93-4819-976e-46a45a5a996f"
},
"upload_cancellation": {
"url": "https://cde.example.com/upload-cancellation?upload_session=ee56b8f3-8f93-4819-976e-46a45a5a996f"
}
}
]
}
In this example, there is just a single document being uploaded. The server has, in the upload_file_parts
array, specified that this has to be uploaded in two chunks.
In the previous step, the client has received instructions how to upload the binary data of the files. The following actions must be performed for each document in the returned documents_to_upload
array and their upload_file_parts
elements.
A single upload file part looks like this:
{
"url": "https://cde-storage.example.com/8d9f94b5-125c-4f88-afbb-494bd9cd3356",
"http_method": "PUT",
"additional_headers": {
"values": [
{
"name": "Content-Length",
"value": "524310"
}
]
},
"multipart_form_data": {
"prefix": "U0VSVkVSX1NUQVJU",
"suffix": "U0VSVkVSX0VORA=="
},
"include_authorization": false,
"content_range_start": 0,
"content_range_end": 524287
}
The element above describes how the client should upload this part of the file.
Field | Value | Description |
---|---|---|
url |
https://cde-storage.example.com/8d9f94b5-125c-4f88-afbb-494bd9cd3356 |
The url where the binary data should be sent to. In this case, this is on a domain different than the CDE, which likely means that an external storage provider is used. This is common and should be expected by all clients. |
http_method |
PUT |
The http method to use when sending the binary data. |
additional_headers |
This optional object instructs the client to use specific headers when performing the request. In this case, the Content-Length header should be set. Note, in this example, the Content-Length value reflects the total bytes count of the body as well as the multipart_form_data.prefix and multipart_form_data.suffix . |
|
include_authorization |
false |
Whether or not to use the OAuth2 token in the request. Typically set to false for external storage providers. |
multipart_form_data |
This is an optional property. If this is present, this includes prefix and suffix data that should be sent verbatim in the request body before or after the actual payload. |
|
multipart_form_data.prefix |
U0VSVkVSX1NUQVJU |
This is a Base64 encoded string containing data that must be prepended to the request body |
multipart_form_data.suffix |
U0VSVkVSX0VORA== |
This is a Base64 encoded string containing data that must be appended to the request body |
content_range_start |
0 |
The inclusive, zero based start for the range of bytes to be sent in this part of the upload. |
content_range_end |
524287 |
The inclusive, zero based end for the range of bytes to be sent in this part of the upload. |
In this case, the upload request would look like this:
PUT https://cde-storage.example.com/8d9f94b5-125c-4f88-afbb-494bd9cd3356
Headers:
Content-Length: 524310
Body:
<Binary Data, from multipart_form_data.prefix>
<Binary Data, from byte index 0 to 524287>
<Binary Data, from multipart_form_data.suffix>
After the client has successfully uploaded all binary parts of the document, the server must be notified via the upload completion endpoint. In this example, the url for this endpoint was returned as https://cde.example.com/upload-completion?upload_session=ee56b8f3-8f93-4819-976e-46a45a5a996f
.
Note that for long running upload completion requests, the server may periodically send back a whitespace character to keep the connection from timing out.
The client just sends a POST
request without a body to this endpoint and receives a DocumentVersion
as response:
{
"links": {
"document_version": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0"
},
"document_version_metadata": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0/metadata"
},
"document_version_download": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0/download"
},
"document_versions": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions"
},
"document_details": {
"url": "https://cde.example.com/ui/projects/12485/documents/bf546064-6b97-4730-a094-c21ab929c91a/v3.0"
}
},
"version_number": "v3.0",
"version_index": 3,
"creation_date": "2022-03-09T08:02:53.866Z",
"title": "Sample Document",
"file_description": {
"name": "model.ifc",
"size_in_bytes": 1048576
},
"document_id": "bf546064-6b97-4730-a094-c21ab929c91a"
}
Field | Description |
---|---|
links.document_version.url |
This url should return exactly the same as the response above, it's a link to itself, the document version. |
links.document_version_metadata.url |
This url can be used to obtain metadata, a collection of key-value pairs, for this document version. |
links.document_version_download.url |
The url to download the content of the document version. |
links.document_versions.url |
This url returns an overview of all versions available for the parent document. |
links.document_details.url |
Optional, this url is to be opened in the browser. If this is given, it points to a location where the user can view the document details in the CDE UI. |
document_id |
This is the identifier of the parent document, under which this created version is attached. |
If the client or the user decide to cancel the upload, the server must be notified via the upload cancellation endpoint. In this example, the url for this endpoint was returned as https://cde.example.com/upload-cancellation?upload_session=ee56b8f3-8f93-4819-976e-46a45a5a996f
.
The client just sends a POST
request without a body and receives an empty response with status code 204 - No Content
.
Clients typically want to track changes to synced documents between the local versions and the latest state on the CDE. To prevent clients having to periodically poll multiple document version endpoints, the Document Query endpoint should be used instead.
There, the client can send a list of all tracked document_ids
and receive the latest DocumentVersion for each of those.
In this example, the client locally has synced two documents. To periodically query if any new versions are available, the client sends the following request to the CDE:
POST /document-versions
Body:
{
"document_ids": [
"bf546064-6b97-4730-a094-c21ab929c91a",
"07ac6f01-b996-4a56-b5bb-8a30c0eb53e3"
]
}
As a response, the CDE returns the latest DocumentVersion for both documents. There is no guarantee about how the entries in the response are ordered.
Headers:
ETag: f1899e079df28604c59ea51eb41a5bfd
Body:
{
"versions": [
{
"links": {
"document_version": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v4.0"
},
"document_version_metadata": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v4.0/metadata"
},
"document_version_download": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v4.0/download"
},
"document_versions": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions"
},
"document_details": {
"url": "https://cde.example.com/ui/projects/12485/documents/bf546064-6b97-4730-a094-c21ab929c91a/v4.0"
}
},
"version_number": "v4.0",
"version_index": 4,
"creation_date": "2022-03-19T08:02:53.866Z",
"title": "Sample Document",
"file_description": {
"name": "model.ifc",
"size_in_bytes": 1048576
},
"document_id": "bf546064-6b97-4730-a094-c21ab929c91a"
},
{
"links": {
"document_version": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0"
},
"document_version_metadata": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0/metadata"
},
"document_version_download": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions/v3.0/download"
},
"document_versions": {
"url": "https://cde.example.com/documents/bf546064-6b97-4730-a094-c21ab929c91a/versions"
},
"document_details": {
"url": "https://cde.example.com/ui/projects/12485/documents/bf546064-6b97-4730-a094-c21ab929c91a/v3.0"
}
},
"version_number": "v3.0",
"version_index": 3,
"creation_date": "2022-03-09T08:02:53.866Z",
"title": "Sample Document",
"file_description": {
"name": "model.ifc",
"size_in_bytes": 1048576
},
"document_id": "bf546064-6b97-4730-a094-c21ab929c91a"
},
{
"links": {
"document_version": {
"url": "https://cde.example.com/documents/07ac6f01-b996-4a56-b5bb-8a30c0eb53e3/versions/v3.0"
},
"document_version_metadata": {
"url": "https://cde.example.com/documents/07ac6f01-b996-4a56-b5bb-8a30c0eb53e3/versions/v3.0/metadata"
},
"document_version_download": {
"url": "https://cde.example.com/documents/07ac6f01-b996-4a56-b5bb-8a30c0eb53e3/versions/v3.0/download"
},
"document_versions": {
"url": "https://cde.example.com/documents/07ac6f01-b996-4a56-b5bb-8a30c0eb53e3/versions"
},
"document_details": {
"url": "https://cde.example.com/ui/projects/12485/documents/07ac6f01-b996-4a56-b5bb-8a30c0eb53e3/v1.0"
}
},
"version_number": "v1.0",
"version_index": 1,
"creation_date": "2022-03-28T15:41:42.136Z",
"title": "Additional Document",
"file_description": {
"name": "specs.pdf",
"size_in_bytes": 7548
},
"document_id": "07ac6f01-b996-4a56-b5bb-8a30c0eb53e3"
}
]
}
To reduce both bandwith and server load, it is strongly recommended to honor the ETag
header when accessing the query endpoint. The ETag
header is a value that is guaranteed to change once the response on the server changes. Clients that have done a successful polling may send the initially retrieved ETag
headers value in a header named If-None-Match
, where servers may then simply return 304 - Not Modified
as a response without any actual content present.
ETag
can generally be simply constructed. Many server side technologies already support this out of the box. Alternatively, an ETag
can simply be constructed by hashing e.g. the values of creation_date
for all queried documents, therefore allowing the CDE to quickly decide if all document data must be loaded and processed to serve the request.
More detailed information about the ETag
header is part of the Foundation API.
Frequent polling may result in high load on CDE servers. Clients therefore should not send queries more frequent than once every 5 minutes.