From d5c7dbaf3d9b6618b5fed9fc06a18b2566799f06 Mon Sep 17 00:00:00 2001 From: Thomas Ghysbrecht Date: Fri, 15 May 2026 12:41:21 +0200 Subject: [PATCH 1/4] Added rate limit info to the User-Defined API docs --- .../Objects/UD_APIs_ApiToken.md | 50 +++++++++++++++++-- .../UD_APIs_Triggering_an_API.md | 1 + 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md index 2f1030f753..19905696b4 100644 --- a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md +++ b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md @@ -19,6 +19,7 @@ The table below lists the properties of the `ApiToken` object. For each property |CreatedAt |DateTime |Yes |The UTC date and time when the token was created.| |LastModifiedBy |string |Yes |The name of the last user who modified the token.| |LastModified |DateTime |Yes |The UTC date and time when the token was last modified.| +|RateLimit |RateLimit |No |Optional rate limit that controls how frequently the token can be used to trigger APIs on a per endpoint basis. See [RateLimit](#ratelimit). Available from DataMiner 10.6.7/10.7.0 onwards.| ### Secret @@ -51,6 +52,42 @@ var secret = ApiTokenSecretGenerator.GenerateSecret(); > [!WARNING] > Once a token has been created with a specific secret, **it is not possible to retrieve that secret again**. The value is stored securely in the database with a non-reversible hashing function. Make sure to save it somewhere secure or pass it to the API user in a secure way. +### RateLimit + +From DataMiner 10.6.7/10.7.0 onwards, an `ApiToken` can be configured with a rate limit to control how frequently it can be used to trigger user-defined APIs. This rate is evaluated on a per endpoint basis. + +A rate limit consists of the following properties: + +| Property | Type | Description | +|----------|----------|-------------| +| Limit | int | The maximum number of requests allowed within the configured time window. Supported range: 1 to 100. | +| Window | TimeSpan | The time span during which the configured number of requests are allowed. Supported range: 1 second to 1 day. | + +> [!IMPORTANT] +> Currently, rate limits cannot be configured in the UI and must be configured via the C# API. If an API token with a configured rate limit is updated through the UI, the rate limit will be cleared. + +#### Behavior when the limit is exceeded + +When the rate limit is exceeded, the *UserDefinableApiEndpoint* DxM returns an HTTP 429 *Too Many Requests* response. In this case, the API trigger is not forwarded to SLNet, and the API script is therefore not executed. The response message indicates that the rate limit was exceeded and includes internal error code 1014. See [Errors](xref:UD_APIs_Triggering_an_API#errors). + +Every request that can be linked to a token counts toward that token's rate limit, regardless of whether the request results in a successful API script trigger. + +#### Sliding window behavior + +Rate limiting uses a sliding window. When a request is received, the system checks how many requests were made with the same token during the preceding configured window. If the configured limit has already been reached within that period, the request is blocked. + +For example, with a limit of 5 requests per 1 minute, a client using the token can trigger the API up to 5 times within any rolling 1-minute period. + +Keep in mind that different limit/window combinations can result in different behavior, even when they allow the same average number of requests. For example: + +- *Limit* 10, *Window* 60 seconds allows bursts of up to 10 requests in a short time, after which the client must wait until requests fall outside the 60-second window. +- *Limit* 1, *Window* 6 seconds spreads the requests more evenly, allowing one new request every 6 seconds. + +> [!NOTE] +> +> - Configuring a high rate limit, such as 100 requests per second, does not guarantee that DataMiner can process that number of API triggers. The actual throughput depends on factors such as API script runtime, server hardware, current system load, the number of agents in the cluster, and other system-specific conditions. +> - When an existing rate limit is changed, the updated limit is only applied after a next trigger both starts and finishes after the update has been applied. If a long window was configured and the limit has already been reached, the client may need to wait until the window has passed before another trigger can be executed and the updated limit can take effect. + ## Requirements - **Create**: The `Secret` property must contain a secret that meets the requirements mentioned under [Secret](#secret). @@ -62,11 +99,14 @@ var secret = ApiTokenSecretGenerator.GenerateSecret(); When something goes wrong during the CRUD actions, the `TraceData` can contain one or more `ApiTokenErrors`. Below is a list of all possible `ErrorReasons`. The `Id` property of the `ApiTokenError` object will always contain the ID of the API token that could not be created, updated or deleted. -|Reason |Description| -|--------------|-----------| -|InvalidName |The specified name was null or whitespace.| -|InvalidSecret |The specified secret did not meet the requirements or is already used by another token.| -|TokenInUse |The token is in use by one or multiple `ApiDefinitions`. The *ApiDefinitionIdLinks* property will contain a list of IDs of the definitions using the token.| +From DataMiner 10.6.7/10.7.0 onwards, the `ApiTokenError` object also has a `Message` property that contains an English description of the error. + +|Reason |Description| +|------------------|-----------| +|InvalidName |The specified name was null or whitespace.| +|InvalidSecret |The specified secret did not meet the requirements or is already used by another token.| +|TokenInUse |The token is in use by one or multiple `ApiDefinitions`. The *ApiDefinitionIdLinks* property will contain a list of IDs of the definitions using the token.| +|InvalidRateLimit |The configured `RateLimit` is invalid. The `Message` property contains an English description of the invalid configuration. Available from DataMiner 10.6.7/10.7.0 onwards.| ## Security diff --git a/dataminer/Functions/User-Defined_APIs/UD_APIs_Triggering_an_API.md b/dataminer/Functions/User-Defined_APIs/UD_APIs_Triggering_an_API.md index f1d0786e64..56df17b4c3 100644 --- a/dataminer/Functions/User-Defined_APIs/UD_APIs_Triggering_an_API.md +++ b/dataminer/Functions/User-Defined_APIs/UD_APIs_Triggering_an_API.md @@ -153,6 +153,7 @@ The *errorCode* field of an error contains an error code that can be used by the | QueryStringTooLarge | 1011 | 414 | The query string size is limited to 2 KB. This error will be thrown if the size is larger than that. | | ResponseHeadersNotAllowed | 1012 | 500 | The response header or headers you are trying to return are not allowed. Check the DxM logging for more info. See [ResponseHeaders](xref:UD_APIs_Define_New_API#responseheaders). | | ResponseHeadersInvalid | 1013 | 500 | The response header or headers you are trying to return are invalid. Header names and values cannot contain whitespace, colons (":"), commas (","), or ASCII control characters. Check the DxM logging for the exact error. | +| RateLimitExceeded | 1014 | 429 | The rate limit configured on the API token used to trigger the API has been exceeded. See [RateLimit](xref:UD_APIs_Objects_ApiToken#ratelimit). | > [!NOTE] > For some of these errors, more information will also be logged in the *UserDefinableApiEndpoint.txt* log file. The location of this log file depends on the [UserDefinableApiEndpoint configuration](xref:UD_APIs_UserDefinableApiEndpoint#consulting-logging-for-the-dxm). From 984f79c0d69072004f7e9d12464d411bf9d66c9c Mon Sep 17 00:00:00 2001 From: Thomas Ghysbrecht <114983161+Skyline-ThomasGH@users.noreply.github.com> Date: Fri, 15 May 2026 12:43:53 +0200 Subject: [PATCH 2/4] Update ApiTokenErrors section in documentation Removed note about ApiTokenError Message property from DataMiner versions. --- .../Defining_an_API/Objects/UD_APIs_ApiToken.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md index 19905696b4..bb86eec27a 100644 --- a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md +++ b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md @@ -99,8 +99,6 @@ Keep in mind that different limit/window combinations can result in different be When something goes wrong during the CRUD actions, the `TraceData` can contain one or more `ApiTokenErrors`. Below is a list of all possible `ErrorReasons`. The `Id` property of the `ApiTokenError` object will always contain the ID of the API token that could not be created, updated or deleted. -From DataMiner 10.6.7/10.7.0 onwards, the `ApiTokenError` object also has a `Message` property that contains an English description of the error. - |Reason |Description| |------------------|-----------| |InvalidName |The specified name was null or whitespace.| From 2805cfd9c2fc95f111c5dc38d494d185c55ca06d Mon Sep 17 00:00:00 2001 From: Marieke Goethals Date: Wed, 20 May 2026 15:02:05 +0200 Subject: [PATCH 3/4] Review --- .../Defining_an_API/Objects/UD_APIs_ApiToken.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md index bb86eec27a..6826081ea8 100644 --- a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md +++ b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md @@ -19,7 +19,7 @@ The table below lists the properties of the `ApiToken` object. For each property |CreatedAt |DateTime |Yes |The UTC date and time when the token was created.| |LastModifiedBy |string |Yes |The name of the last user who modified the token.| |LastModified |DateTime |Yes |The UTC date and time when the token was last modified.| -|RateLimit |RateLimit |No |Optional rate limit that controls how frequently the token can be used to trigger APIs on a per endpoint basis. See [RateLimit](#ratelimit). Available from DataMiner 10.6.7/10.7.0 onwards.| +|RateLimit |RateLimit |No |Optional rate limit that controls how frequently the token can be used to trigger APIs on a per-endpoint basis. See [RateLimit](#ratelimit). Available from DataMiner 10.6.7/10.7.0 onwards.| ### Secret @@ -54,7 +54,7 @@ var secret = ApiTokenSecretGenerator.GenerateSecret(); ### RateLimit -From DataMiner 10.6.7/10.7.0 onwards, an `ApiToken` can be configured with a rate limit to control how frequently it can be used to trigger user-defined APIs. This rate is evaluated on a per endpoint basis. +From DataMiner 10.6.7/10.7.0 onwards, an `ApiToken` can be configured with a rate limit to control how frequently it can be used to trigger user-defined APIs. This rate is evaluated on a per-endpoint basis. A rate limit consists of the following properties: @@ -76,16 +76,16 @@ Every request that can be linked to a token counts toward that token's rate limi Rate limiting uses a sliding window. When a request is received, the system checks how many requests were made with the same token during the preceding configured window. If the configured limit has already been reached within that period, the request is blocked. -For example, with a limit of 5 requests per 1 minute, a client using the token can trigger the API up to 5 times within any rolling 1-minute period. +For example, with a limit of 5 requests per minute, a client using the token can trigger the API up to 5 times within any rolling 1-minute period. Keep in mind that different limit/window combinations can result in different behavior, even when they allow the same average number of requests. For example: -- *Limit* 10, *Window* 60 seconds allows bursts of up to 10 requests in a short time, after which the client must wait until requests fall outside the 60-second window. -- *Limit* 1, *Window* 6 seconds spreads the requests more evenly, allowing one new request every 6 seconds. +- If *Limit* is 10 and *Window* 60 seconds, bursts of up to 10 requests are allowed in a short time, after which the client must wait until requests fall outside the 60-second window. +- If *Limit* is 1 and *Window* 6 seconds, requests are spread more evenly, as one new request is allowed every 6 seconds. > [!NOTE] > -> - Configuring a high rate limit, such as 100 requests per second, does not guarantee that DataMiner can process that number of API triggers. The actual throughput depends on factors such as API script runtime, server hardware, current system load, the number of agents in the cluster, and other system-specific conditions. +> - Configuring a high rate limit, such as 100 requests per second, does not guarantee that DataMiner can process that number of API triggers. The actual throughput depends on factors such as API script runtime, server hardware, current system load, the number of Agents in the cluster, and other system-specific conditions. > - When an existing rate limit is changed, the updated limit is only applied after a next trigger both starts and finishes after the update has been applied. If a long window was configured and the limit has already been reached, the client may need to wait until the window has passed before another trigger can be executed and the updated limit can take effect. ## Requirements From e8fe5610d4e35f747a6cac0e95294980512b9b2f Mon Sep 17 00:00:00 2001 From: Thomas Ghysbrecht <114983161+Skyline-ThomasGH@users.noreply.github.com> Date: Thu, 21 May 2026 09:54:46 +0200 Subject: [PATCH 4/4] Update RateLimit RN number in API token documentation --- .../Defining_an_API/Objects/UD_APIs_ApiToken.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md index 6826081ea8..03bad281cc 100644 --- a/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md +++ b/dataminer/Functions/User-Defined_APIs/Defining_an_API/Objects/UD_APIs_ApiToken.md @@ -19,7 +19,7 @@ The table below lists the properties of the `ApiToken` object. For each property |CreatedAt |DateTime |Yes |The UTC date and time when the token was created.| |LastModifiedBy |string |Yes |The name of the last user who modified the token.| |LastModified |DateTime |Yes |The UTC date and time when the token was last modified.| -|RateLimit |RateLimit |No |Optional rate limit that controls how frequently the token can be used to trigger APIs on a per-endpoint basis. See [RateLimit](#ratelimit). Available from DataMiner 10.6.7/10.7.0 onwards.| +|RateLimit |RateLimit |No |Optional rate limit that controls how frequently the token can be used to trigger APIs on a per-endpoint basis. See [RateLimit](#ratelimit). Available from DataMiner 10.6.7/10.7.0 onwards.| ### Secret @@ -54,7 +54,7 @@ var secret = ApiTokenSecretGenerator.GenerateSecret(); ### RateLimit -From DataMiner 10.6.7/10.7.0 onwards, an `ApiToken` can be configured with a rate limit to control how frequently it can be used to trigger user-defined APIs. This rate is evaluated on a per-endpoint basis. +From DataMiner 10.6.7/10.7.0 onwards, an `ApiToken` can be configured with a rate limit to control how frequently it can be used to trigger user-defined APIs. This rate is evaluated on a per-endpoint basis. A rate limit consists of the following properties: @@ -104,7 +104,7 @@ When something goes wrong during the CRUD actions, the `TraceData` can contain o |InvalidName |The specified name was null or whitespace.| |InvalidSecret |The specified secret did not meet the requirements or is already used by another token.| |TokenInUse |The token is in use by one or multiple `ApiDefinitions`. The *ApiDefinitionIdLinks* property will contain a list of IDs of the definitions using the token.| -|InvalidRateLimit |The configured `RateLimit` is invalid. The `Message` property contains an English description of the invalid configuration. Available from DataMiner 10.6.7/10.7.0 onwards.| +|InvalidRateLimit |The configured `RateLimit` is invalid. The `Message` property contains an English description of the invalid configuration. Available from DataMiner 10.6.7/10.7.0 onwards.| ## Security