Every error response from the API carries a stable error code. This is the part of the response that an integration should program against — not the message text.
Structure of an Error Response
{
"error": {
"code": "CONNECTOR_OFFLINE",
"message": "The customer's connector is not currently connected; retry.",
"correlationId": "9f3a2b7c4d1e5081",
"supportCode": "STP-DMS-502-CONN-OFFLINE-9f3a2b7c",
"details": null,
"retryAfter": null
}
}| Field | Meaning |
|---|---|
code |
The stable error code. Program against this. |
message |
Explanatory text. May change at any time — do not parse. |
correlationId |
The correlation identifier. Matches the submitted
X-Correlation-Id if provided, otherwise newly generated. |
supportCode |
The code support needs to locate the request. Always include this when raising a support query. |
details |
Reserved for structured additional information. Currently always
null — the explanation is in
message. |
retryAfter |
Wait time in seconds before the next attempt. For
429 and 503 responses, this is also returned as a
Retry-After header. |
Every error response generated by the API itself follows this structure. A small number of rejections occur before the API's own error handling kicks in — in those cases, the status code is returned without a response body. Details are provided in the box under Retry Behavior.
The Support Code
It is structured so that the category is immediately recognizable at a glance:
STP-DMS-{HTTP-Status}-{short-code}-{start of correlation ID}
Example: STP-DMS-502-CONN-OFFLINE-9f3a2b7c
A partner application should pass this through to the end user. This gives STP Support a single identifier to locate the request in logs and trace recordings.
Retry Behavior
Every code carries one of two recommendations:
| Symbol | Meaning |
|---|---|
| 🔁 |
Retry — transient issue. Retry using the same
Idempotency-Key with increasing backoff. |
| ⛔ | Do not retry — permanent. Fix the request or configuration first. |
For full details, see Idempotency and Retries.
Two cases are returned without the standard error wrapper. Both are rejected before the API's own error handling ever runs:
401— the token is missing, has expired, or has an invalid signature. The same bare401is also returned for URLs that don't exist: without a valid token, it's impossible for an external caller to determine whether an endpoint exists at all. The correct response is always the same: obtain a new token.400or404for a malformed URL — if the URL contains a character that isn't allowed there, or a segment such as.., the request is rejected before it even reaches the API. The exact response (status code and whether a response body is included) is not part of the versioned contract for this API in these edge cases — unlike every other error in this table, an integration should not expect a specificcode, format, or status code here. In either case, check the URL being called. Standard percent-encoding is not affected — an invalid percent-encoded value is handled normally and returnsVALIDATION_FAILEDwith the standard error wrapper.An integration must not expect a response body in the
401case; the status code alone conveys the information.
Authentication and Authorization
| Code | Status | Meaning | |
|---|---|---|---|
| (no code) | 401 | ⛔ | Token is missing, has expired, or has an invalid signature. Returned without the error wrapper — see the box above. Obtain a new token and treat the call as a fresh attempt. |
INSUFFICIENT_SCOPE |
403 | ⛔ | The token is valid but does not carry the scope required by this endpoint. |
TENANT_MISMATCH |
403 | ⛔ | The request targets a tenant the caller is not authorized for. Also occurs when a storage key belonging to a different tenant is used. |
LICENSE_MISSING |
403 | ⛔ | The tenant has no license for this API, or the token does not include a license scope. |
CLIENT_NOT_LICENSED |
403 | ⛔ | The partner-bound license scope in the token was issued for a different application. |
SERVICE_USER_SUSPENDED |
403 | ⛔ | The service user has been suspended by the firm's administrator. |
TENANT_INACTIVE |
403 | ⛔ | The tenant has been decommissioned or the license has expired. |
CONNECTOR_DEACTIVATED |
403 | ⛔ | The firm's administrator has disabled the connector. This is not a platform outage. |
ON_PREM_PERMISSION_DENIED |
403 | ⛔ | The local document management system denied the action for the
requesting user. This only occurs when the document management system
explicitly reports the denial as a permissions issue — current features
do not do this; a permissions-based denial there appears as
404 NOT_FOUND. |
MISSING_USER_IDENTITY |
403 | ⛔ | The token does not carry a user identity on whose behalf actions could be performed in the document management system. Almost always a token from a flow with no user login — see Getting Started. |
Request Validation
| Code | Status | Meaning | |
|---|---|---|---|
VALIDATION_FAILED |
400 | ⛔ | The request does not match the expected structure. The affected
field is identified in message. |
ILLEGAL_FILENAME |
400 | ⛔ | The filename violates the document management system's naming rules. |
UPLOAD_INTEGRITY_FAILED |
400 | ⛔ | The uploaded file does not match the declared checksum or size. Retry the upload from the beginning. |
UNSUPPORTED_MEDIA_TYPE |
415 | ⛔ | The file extension is not permitted. |
NOT_FOUND |
404 | ⛔ | The requested resource does not exist — or the
requesting user does not have permission to view it in the document
management system. These two cases cannot be distinguished externally. An
unknown target case file or a register that doesn't exist there is also
reported this way; the message identifies what is missing. For move
operations this appears as the HTTP status; for imports it appears in the
job status query as status: failed with this
errorCode — the initial acceptance was successful with
202. Not to be confused with a URL that doesn't exist on
the API at all: that is returned without the error wrapper, as described
in the box above. |
MATTER_NOT_FOUND |
404 | ⛔ | The search for the case file or folder returned no results. |
MATTER_AMBIGUOUS |
409 | ⛔ | The name matches multiple case files or folders. Use the file reference or identifier to search instead. |
INTEGRITY_FAILED |
422 | 🔁 | Checksum error in transit between the cloud and the connector. Retry the full request. |
CONFLICT |
409 | ⛔ | The action conflicts with the current state of the object — a document belongs to exactly one case file or folder and will not be silently moved. |
Idempotency
| Code | Status | Meaning | |
|---|---|---|---|
IDEMPOTENCY_KEY_REUSED |
409 | ⛔ | The key belongs to a request that has already completed or failed. No result will be returned — use the job status query to determine the outcome instead. |
IDEMPOTENCY_KEY_INFLIGHT_TIMEOUT |
504 | 🔁 | An in-flight request with the same key did not complete in time. Try again later. |
Limits and Quotas
| Code | Status | Meaning | |
|---|---|---|---|
RATE_LIMIT_EXCEEDED |
429 | 🔁 | Too many requests. Observe Retry-After. |
PARTNER_CONCURRENCY_LIMIT |
429 | 🔁 | Too many concurrent jobs running. |
TENANT_BANDWIDTH_LIMIT |
429 | 🔁 | A volume limit for the tenant has been reached. Whether and which limits apply to your firm is governed by the contract with STP. |
QUOTA_EXCEEDED |
429 | ⛔ | A hard usage limit of the license has been reached. Retrying will not help; the applicable limits are governed by the firm's contract with STP. |
TENANT_OVERLOADED |
503 | 🔁 | Capacity on the firm's side is exhausted. Observe
Retry-After; the default value is 120 seconds. |
Platform and Connector Outages
| Code | Status | Meaning | |
|---|---|---|---|
CONNECTOR_OFFLINE |
502 | 🔁 | The firm's connector is not connected. If the issue persists,
involve the firm's administrator. If the connector service is confirmed
to be running, also ask them to check the connector server's system
clock: older connector versions report a drifting clock as this error
rather than CONNECTOR_DEADLINE_EXCEEDED. |
CONNECTOR_ERROR |
502 | 🔁 | The connector received the request but was unable to complete it. |
CONNECTOR_DECRYPT_FAILED |
502 | ⛔ | The connector could not decrypt the request — its receiving key
does not match. Unlike other 502 errors, retrying
will not help; the issue will persist until the key
configuration is corrected. Contact STP Support. |
CONNECTOR_DEADLINE_EXCEEDED |
502 | 🔁 | The connector received the request but rejected it
without processing it: according to the connector
server's clock, the deadline had already passed. The job was not
executed; retrying with the same Idempotency-Key is safe.
If this error occurs on every request, the connector
server's system clock is almost certainly wrong — in that case, retrying
won't help until the firm's administrator corrects the time. |
CAPABILITY_NOT_SUPPORTED |
502 | ⛔ | The firm's connector is connected but does not recognize this operation — its version predates the feature. Retrying will not help until the connector is updated; the firm's administrator must install the current connector version. |
IOT_UNAVAILABLE |
502 | 🔁 | The message broker is unreachable. |
IOT_THROTTLED |
502 | 🔁 | The message broker has applied throttling. |
IOT_PUBLISH_FAILED |
502 | 🔁 | The job could not be delivered even after retries. |
STORAGE_UNAVAILABLE |
502 | 🔁 | The object storage is reporting errors. |
IMPORT_TIMEOUT |
504 | 🔁 | The import into the document management system did not complete in time. |
IMPORT_FAILED |
502 | 🔁 | The import reported a transient error. |
TARGET_DMS_FAILURE |
502 | 🔁 | The local document management system reported an error that is not a permissions denial. |
TARGET_DMS_INTEGRITY_FAILED |
502 | ⛔ | The document management system is reporting an internal storage failure. Investigation on the firm's side is required. |
LICENSE_SERVICE_UNAVAILABLE |
503 | 🔁 | The license service is unreachable. |
IAM_UNAVAILABLE |
503 | 🔁 | The cloud was unable to exchange the user token for the connector
with STP authentication (STP-IAM) — for example because STP-IAM is
unreachable. The connector was not involved. If STP-IAM refuses the
exchange for this user, retrying will not help; if the error persists,
contact STP Support. Note for support: prior to October 2026, this case
appeared as CONNECTOR_OFFLINE. |
KMS_UNAVAILABLE |
503 | 🔁 | The key management service is unreachable. |
SERVICE_UNAVAILABLE |
503 | 🔁 | The API is shutting down, for example during an update. A retry will land on a different instance. |
KMS_KEY_NOT_FOUND |
502 | ⛔ | The tenant's key is no longer available. Contact STP Support. |
KMS_ACCESS_DENIED |
502 | ⛔ | The cloud does not have access to the tenant's key. Contact STP Support. |
Internal Errors
Some errors trigger an internal security or operations alert at STP. Their
internal designations are intentionally not exposed outside the platform;
externally, IMPORT_FAILED is always returned instead — a code
from the table above, with the retry recommendation listed there.
For a partner application, this changes nothing: it handles the code it receives according to the table above. If such an error recurs, the support code will help take things further.
Handling Unknown Codes
New codes may be added within a major version. An integration must therefore be able to handle an unknown code without crashing. The reliable fallback is the HTTP status:
| Status | Behavior |
|---|---|
4xx except 408, 425,
429
|
Do not retry |
408, 425, 429
|
Retry, observe Retry-After
|
5xx |
Retry with increasing backoff |
If the code is known, its recommendation from the tables above
takes precedence — not this fallback rule. That is why
INTEGRITY_FAILED carries a 🔁 even though it is a
422: the error occurs in transit and clears on the next attempt.
The fallback rule only applies to codes an integration does not yet
recognize.
For more details, see Versioning and Deprecation.
Further Reading
This article has been automatically translated by an AI and may therefore contain errors.
Related to