All paths on this page are appended to the tenant's base URL:
https://<tenant>.stp-cloud.de/documents/dms-cloud-api/api
The base URL does not include a version number — that appears at the beginning of each path. The full URL for the case file search is therefore
https://<tenant>.stp-cloud.de/documents/dms-cloud-api/api/v1/dms/documents/container.
The advantage of this structure: URLs returned by the API itself — such as the statusUrl of an operation — can be appended to the base URL without modification.
Every request requires two scopes in the token: the tenant's license scope
(dms.cloud.api.standalone or the partner-specific equivalent) and the endpoint's capability scope listed in the Required Scope column.
"Scope" refers to exactly what is present in the access token — the same strings that can be selected in the client registration under allowed scopes. If either one is missing, the request will be rejected; the error code indicates which one is absent (
403 LICENSE_MISSINGor403 INSUFFICIENT_SCOPE). For details, see Licenses and Permissions.
Case Files, Folders, and Documents
| Method and Path | Purpose | Required Scope | Response |
|---|---|---|---|
GET /v1/dms/documents/container |
Search or browse case files and folders; when browsing, a single type is selected | dms.cloud.api.documents.read |
200 |
GET /v1/dms/documents/container/{containerId}/documents |
All documents in a case file or folder | dms.cloud.api.documents.read |
200 |
GET /v1/dms/documents/container/{containerId}/filing-tray |
Sections of a case file or folder | dms.cloud.api.documents.read |
200 |
GET /v1/dms/documents/container/{containerId}/filing-tray/{trayId}/documents |
Documents in a single section; with ?recursive=true, includes documents in all subsections;
trayId=0 returns documents stored directly in the case file, outside any section |
dms.cloud.api.documents.read |
200 |
GET /v1/dms/documents/{documentId} |
Master data for a document (including storage location, origin, and lock state) | dms.cloud.api.documents.read |
200 |
GET /v1/dms/documents/{documentId}/versions |
Version history of a document | dms.cloud.api.documents.read |
200 |
GET /v1/dms/documents/{documentId}/versions/{version} |
A single version | dms.cloud.api.documents.read |
200 |
GET /v1/dms/documents/{documentId}/renditions |
Renditions of a version | dms.cloud.api.documents.read |
200 |
POST /v1/dms/documents |
Import a staged document | dms.cloud.api.documents.write |
202 |
GET /v1/dms/documents/{documentId}/content |
Export a document | dms.cloud.api.documents.read |
202 |
POST /v1/dms/documents/{documentId}/versions |
Upload a new version of an existing document | dms.cloud.api.documents.write |
202 |
POST /v1/dms/documents/{documentId}/move |
Move a document to a different case file or folder | dms.cloud.api.documents.write |
200 |
When moving a document, the target case file and target section are validated upfront: if the case file does not exist or does not contain the specified section, the response is 404 NOT_FOUND with a message identifying what is missing. targetTrayId may be 0 — this places the document directly in the case file, outside any section.
Sections and Section Structure in Detail
The document list for a case file is flat — it does not indicate which section a document belongs to. The section breakdown is provided by .../filing-tray, which returns the complete section structure of the case file in a single response, not just the top level.
Each entry includes trayId, name, and displayText, along with three fields that define the structure:
| Field | Meaning |
|---|---|
parentTrayId |
The parent section. 0 means the section is directly attached to the case file; any other value is the trayId of the section one level above. This is used to build the section tree. |
position |
The order among sibling sections, as displayed in the document management system. Sorting is based on this field — not on trayId or name. |
documentCount |
The number of documents directly in this section, excluding those in any subsections. |
Sections can be nested, and the API fully represents this hierarchy. An individual section is retrieved via .../filing-tray/{trayId}/documents; with ?recursive=true, the response also includes documents from all subsections below it. This allows you to retrieve a specific subtree of the case file rather than fetching all documents and filtering afterward.
trayId=0 is not a section — it refers to documents stored directly in the case file, outside any section. It therefore does not appear in the section list, and recursive has no effect there.
When importing or moving a document, trayId or targetTrayId specifies the target section; 0 places the document directly in the case file. The section a document belongs to is shown in its master data under filing.
Versions and Renditions in Detail
A document can have multiple versions — each version is a distinct snapshot of its content, with the most recent being the current one. Each version can also have renditions: alternative representations of the same content, such as a PDF preview or a plain-text extract.
| What you want to do | Request |
|---|---|
| Read a document's master data | GET …/{documentId} |
| List existing versions | GET …/{documentId}/versions |
| Read a specific version | GET …/{documentId}/versions/3 |
| List existing renditions | GET …/{documentId}/renditions |
| Download the current version in its original format | GET …/{documentId}/content |
| Download a specific version | GET …/{documentId}/content?version=3 |
| Download a rendition | GET …/{documentId}/content?rendition=stp.doc.preview |
| Upload a new version | Stage the file, then
POST …/{documentId}/versions
|
The master data includes not only the title, comment, and document class, but also how the document entered the document management system (source, e.g. bea or scan), whether it is inbound or outbound (mailRoute), the document date — and whether a modification would currently be rejected (lockState). It is worth checking this before staging a file: a locked document will not accept a new version.
Who created or last modified a document is deliberately not returned. The document management system stores firm user accounts there; the API returns timestamps, not names.
When uploading a new version, only the content changes: the case file, section, title, and document class remain unchanged. The comment field describes the new version — unlike when importing a new document, it does not become the document's title. If comment is omitted, the comment from the previous version is carried over.
If the document is currently being edited by someone else, has been modified in the meantime, is frozen, or is marked for deletion, the operation will fail with errorCode: "CONFLICT". In that case, re-fetch the document and retry the request.
Please note:
-
Renditions can only be retrieved, not uploaded. This API provides no way to store or delete a rendition; renditions are generated within the document management system itself. Known names are
stp.doc.preview(PDF preview) andstp.doc.fulltext.txt(full text). -
Without a
versionparameter, the latest version is used. Which version that was is included in the operation result. -
The API tells you which versions and renditions are available. The version history lists version numbers; the renditions list provides names — these are exactly what
?version=and?rendition=expect when making a request. If a version number or rendition name does not exist, the API responds with404. - The version history includes only the count of renditions per version, not their names — this keeps the response compact even when there are many versions. Rendition names are returned by
GET …/{documentId}/renditions.
Searching for Case Files and Folders in Detail
GET /v1/dms/documents/container supports four modes of operation. At most one of the three search parameters may be set at a time:
| Parameter | Behavior |
|---|---|
name |
Exact search by case file name (case files only, not folders) |
fileReference |
Exact search by file reference number (case files only, not folders) |
searchTerm |
Prefix search across name and file reference — always for case files, and for folders only if the case file search returns fewer than 1,000 results |
| (none) | Paginated browsing — without any additional parameter, browses all case files; with containerType=folder, browses all personal folders
|
containerType |
For browsing only: dossier (case files, default) or folder (folders). Cannot be combined with name, fileReference, or searchTerm
|
pageSize |
Number of results per page, 1 to 25, default 15 |
continuationToken |
The value from nextContinuationToken in the previous page's response |
A search parameter that is included but empty or contains only whitespace will be rejected with 400 VALIDATION_FAILED. To browse all case files, simply omit it — otherwise there would be no way to distinguish between no results found and a search with no criteria.
When browsing, exactly one type is always listed: case files and folders are stored in separate collections within the document management system, each with their own numbering, so a mixed list of both types is not possible. To retrieve both, browse twice — once without containerType and once with containerType=folder. Any value other than dossier or folder is rejected with 400 VALIDATION_FAILED, as is combining containerType with any of the three search parameters: name and fileReference search exclusively within case files, and for searchTerm, the document management system determines the types itself.
containerType=folder requires an updated connector. A connector that does not yet support this parameter will still return 200 — but will silently browse case files instead of folders, with no error message. If results returned for containerType=folder are unexpectedly of type case file, check the installed connector version before suspecting your own integration.
The continuationToken is tied to the exact query that produced it: to the mode of operation and the search criteria, including containerType when browsing. Using it with different criteria returns 400 VALIDATION_FAILED — not a page from the wrong result set. A token from a folder browsing session cannot be used to continue a case file browsing session. The same applies to the two document lists — the cursor is bound to the case file and, for sections, also to the section and the recursive flag. Page size for both document lists ranges from 1 to 200, with a default of 50.
Each result includes an ID, display name, the firm's internal file reference, the court file reference, and the type (case file or folder) — along with accessLevel, indicating what the calling user is permitted to do with that case file (none, read, write, full). This allows you to identify a read-only result before a write attempt fails. If the field is absent, the document management system has reported a permission level that this API does not recognize — in that case, only the actual request will reveal what is permitted.
Each entry in the two document lists includes an ID, name, title, documentType, sizeBytes, modifiedAt, and letterDate. name and title answer two different questions, which is why both are returned:
| Field | Meaning |
|---|---|
name |
The filename of the current version. Often a scanner or system-generated name — and it changes if a new version is stored under a different filename |
title |
The title as entered in the document management system — what a user assigned and will recognize in a list. The title of the current version takes precedence, since any rename is recorded there |
modifiedAt |
When the document was last modified in the document management system |
letterDate |
The date the document itself bears (e.g., the date of a letter). Empty if none has been recorded — it is not replaced by any other date |
For a document list view, title is the right column to display and letterDate is the appropriate sort field from a business perspective; modifiedAt is a technical timestamp and says nothing about when a document was written.
title and letterDate require an updated connector. A connector that does not yet support these fields will still return 200 — but title will carry the same value as name, and letterDate will be empty for all documents. If a document list consistently shows filenames and the date column is always empty, check the installed connector version before suspecting your own integration.
If no title has been entered in the document management system, title will contain the document's ID — the same value as documentId, and therefore the same value returned by an individual document request. A display that does not account for this will show a long string of characters in such rows.
Parties associated with a case file — such as the client, opposing party, or case handler — are deliberately not returned by this API. This data is personal information, and no function of this API requires it.
File Staging
These endpoints belong to the platform and are independent of the document management system. They generate time-limited, signed URLs; the file bytes do not pass through the API.
| Method and Path | Purpose | Required Scope |
|---|---|---|
POST /v1/platform/uploads/single |
Generate an upload URL for a single file | dms.cloud.api.uploads |
DELETE /v1/platform/uploads/{objectKey} |
Delete a staged object that is no longer needed | dms.cloud.api.uploads |
POST /v1/platform/multipart/initiate |
Start a multipart upload and generate URLs for each part | dms.cloud.api.uploads |
POST /v1/platform/multipart/complete |
Assemble a multipart upload from its parts | dms.cloud.api.uploads |
DELETE /v1/platform/multipart/abort |
Abort a multipart upload and discard all parts | dms.cloud.api.uploads |
GET /v1/platform/multipart/refresh |
Regenerate expired part URLs | dms.cloud.api.uploads |
GET /v1/platform/multipart/parts |
List already uploaded parts to resume an upload | dms.cloud.api.uploads |
The multipart option is intended for large files. For anything that can be transferred in a single request, uploads/single is sufficient.
Operations and System Status
| Method and Path | Purpose | Required Scope |
|---|---|---|
GET /v1/platform/operations/{operationId} |
Status and result of an operation accepted with 202
|
Same as the triggering request |
GET /v1/platform/connector/heartbeat |
Connection status of the firm's connector | dms.cloud.api.connector.read |
Querying an operation's status requires exactly the same scope as the request that triggered it. A status query therefore never reveals more than the original request was authorized to access.
Checking the connector status requires its own scope (
dms.cloud.api.connector.read), which is intentionally separate from file staging: someone who only needs to know whether the connector is running should not need write permissions to find out. This scope must be explicitly assigned to the role — without it, the endpoint returns403 INSUFFICIENT_SCOPE, even if all other requests are working correctly.
Operation Status Values
status |
Meaning |
|---|---|
pending |
Still in progress. Check again later. |
succeeded |
Completed. result contains the response from the triggering request. |
failed |
Rejected — the operation did not take place. reason and errorCode provide the details. |
ambiguous |
Ended, but inconclusive: it cannot be determined whether the DMS executed the operation (OPERATION_TIMEOUT, OPERATION_RESULT_UNREADABLE, OPERATION_OUTCOME_UNKNOWN). Check the DMS before retrying — otherwise you risk creating a duplicate document. |
(404) |
Unknown ID, or the seven-day retrieval window has expired. |
Synchronous vs. Asynchronous Requests
| Type | Endpoints | Reason |
|---|---|---|
Synchronous (200) |
All searches, listings, master data requests, and move operations | Response in a fraction of a second |
Asynchronous (202 and polling) |
Document import and export, new versions | May take longer than the API's timeout allows for large files |
A 202 means accepted, not completed. The request is still validated immediately: a malformed request returns 400 on that call and will never result in a failed operation.
Recommended Headers
| Header | Purpose |
|---|---|
Authorization: Bearer … |
Required on every request |
X-Correlation-Id |
Your own operation identifier, included in the response and logs |
Idempotency-Key |
For write requests — see Idempotency and Retries |
There is no header for the tenant. The tenant is determined exclusively from the token.
Further Reading
This article has been automatically translated by an AI and may therefore contain errors.
Related to