Simplify System Integration with Duett API

In today’s landscape, many systems are poorly integrated or not integrated at all. This results in duplicated efforts and inefficiencies as the same data must be registered across multiple systems. While many companies invest heavily in integration solutions to establish data flow between systems, the high complexity of these solutions often makes changes costly, leading to resistance and reduced flexibility.

Duett addresses these challenges by offering an API designed for creating efficient, future-ready integrations with Duett Economy. Our API enables integration partners to deliver solutions faster and more cost-effectively compared to traditional integration development methods.

Streamline Workflows and Focus on What Matters

By connecting your systems seamlessly, we reduce dependency on individual platforms and streamline daily operations. With Duett, your team can focus on value-creating tasks instead of managing disconnected systems.

General Information about Data in Duett

RowVersion

All entities in Duett have a RowVersion field. In cases of complex entities, the highest RowVersion is considered the valid version. This property can be used to track new and changed data.

Soft Deletes

Many entities include a Show property, which functions as a soft delete. This allows for entities to be hidden from the user interface without permanently deleting them.

Id and Key Fields

Several entities feature both Id and Key fields. For instance, an employee record contains both an employee Id and an employee number (key). While the key fields are theoretically changeable, there are instances where such modifications are not allowed.

Order and Voucher Numbers

Order numbers are not unique on their own, as they reset each year. Therefore, the combination of the order number and year forms a unique identifier. The same applies to voucher numbers, where both the voucher number and the year together are unique.

Get Started with Integration Development

If you're interested in developing an integration, simply reach out to us, and we’ll guide you through the process of becoming an integration partner.
Additionally, you can share your feedback, propose changes, or suggest new features in our discussion forum. Alternatively, send us an email at api@duett.no —we’d love to hear from you!

About the Integration-keys and Client-keys

The integration key is a key that follows the integration and it is the same throughout the development process until it is put into production. This key is obtained when the agreement with Duett AS has been agreed. Integration partners receive their own time-limited client keys that are used for development, testing and approval of the integration.

The clients that are used for development can to a certain extent contain data and layouts that are as similar as possible to the type of business that the Integration has as a target group. If the integration partner has several integration types, one key will be distributed per integration type.

For each activation of a developed integration through Duett Økonomi, the person who wants to use the integration will have a separate client key that is personally owned, and this key is entered into the integration to activate this.

Together, these keys are unique in telling what integration is used and against which client instance is used.


  curl -X 'GET' 'https://api.duett.no/article/v1' \
  -H 'accept: application/json' \
  -H 'X-Api-Integration-Key: 89ff1c42-9d90-435a-8a94-20207bc06e1a' \
  -H 'X-Api-Client-Key: 7896feb3-aaa2-4fd2-aaa2-c69de5fd1e5f'
                
Important: Never send any of the keys by email or store them in such a way that they end up in the wrong hands.

Rate limiting throttling

Rate limiting throttling is per company, not per integration. It is important that the integration can handle Rate limiting throttling in a good way so that errors do not occur.

You can make up to 2 500 requests per hour. If the rate limit is exceeded, the HTTP code 429 will be returned with body , and a “Retry-after” in header with number of seconds to wait:

{
    "message": "Quota exceeded!", 
    "detail": "Maximum allowed: 2500 per 1h. Please try again in 2 second(s)",
    "status": 429
}
Header Description
X-Rate-Limit-Limit The time window. Normally 1h (1 hour)
X-Rate-Limit-Remaining The number of requests remaining in the current rate limit window.
X-Rate-Limit-Reset The time at witch the current rate limit window resets in UTC date and time.

To handle the throttling you can use the Polly library like this (http://www.thepollyproject.org/):


private IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(int numRetries = 10, int delayInMilliseconds = 10000)
{
    var retryPolicy = Policy
        .Handle<HttpRequestException>()
        .OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.TooManyRequests ||
                                            r.StatusCode == HttpStatusCode.ServiceUnavailable)
        .WaitAndRetryAsync(numRetries,
            sleepDurationProvider: (retryCount, response, context) =>
            {
                var delay = TimeSpan.FromSeconds(0);

                // if an exception was thrown, this will be null
                if (response.Result != null)
                {
                    if (!response.Result.Headers.TryGetValues("Retry-After", out IEnumerable<string> values))
                        return delay;

                    if (int.TryParse(values.First(), out int delayInSeconds))
                        delay = TimeSpan.FromSeconds(delayInSeconds);
                }
                else
                {
                    var exponentialBackoff = Math.Pow(2, retryCount);
                    var delayInSeconds = exponentialBackoff * delayInMilliseconds;
                    delay = TimeSpan.FromMilliseconds(delayInSeconds);
                }

                return delay;
            },
            onRetryAsync: async (response, timespan, retryCount, context) =>
            {
                // add your logging and what you want to do
            }
        );

    return retryPolicy;
}

Duplicate call prevention on POST

It returns statuscode 409: Conflict.
The mechanism returns if the same payload is sent for a period shorter than 120 seconds. The correct course of action for this error is to check whether the entity has been created or not, as this is not necessarily an error on your side.

Use a code generator as to auto-generate api client

NSwagStudio
Visual studio add-in
Online code generator for many languages and versions