OpenAPI

All calls to OpenAPI are subject to rate limiting. Limits are put in place to protect our system against excessive load and to make OpenAPI available to as wide an audience as possible.

Default Limits

Per default the following limits are in place:

  • Max number of requests per application across all users and sessions: 10.000.000/day.
  • Max number of requests per session per service group: 120/minute.
  • Max number of orders per session: 1/second.
    • A single request including an entry order and two related orders counts as one request.
    • A single request to create a standalone order, immediately followed by a request to add a related order will count as 2 requests and will be rejected.

The above limits are in effect whether you place the requests individually or as part of a batch request. I.e. a batch request including 10 requests, will count as 11 requests.

Rate Limit Headers

You will receive rate limit information in the response headers of all calls to endpoints which are rate limited.

Currently you will receive these for every call. To limit bandwidth usage we are considering only returning these headers, when a limit is close to being reached. The following information is returned:

  • X-RateLimit-<dimension>-Limit: The total number of requests allowed (per dimension).
  • X-RateLimit-<dimension>-Remaining: The total number of requests remaining (per dimension).
  • X-RateLimit-<dimension>-Reset.Number of seconds until the quota is reset.

Below is an example of response headers, including rate limit information. Not all headers are returned for all endpoints. 

X-RateLimit-AppDay-Limit:10000000
X-RateLimit-AppDay-Remaining:9999999
X-RateLimit-AppDay-Reset:82332
X-RateLimit-Session-Limit:120
X-RateLimit-Session-Remaining:75
X-RateLimit-Session-Reset:60
X-RateLimit-SessionOrders-Limit:1
X-RateLimit-SessionOrders-Remaining:1
X-RateLimit-SessionOrders-Reset:1

Exceeding Limits

If any of the above limits are exceeded, the request will be rejected with an HttpStatus code 429 - Too Many Requests. In the example below, the caller has tried to place two orders in rapid succession.

HTTP/1.1 429
....
X-RateLimit-AppDay-Limit: 10000000
X-RateLimit-AppDay-Remaining: 9999994
X-RateLimit-AppDay-Reset: 82119
X-RateLimit-SessionOrders-Limit: 1
X-RateLimit-SessionOrders-Remaining: 0
X-RateLimit-SessionOrders-Reset: 1

Preventing duplicate order operations

In order to avoid accidental duplication of order operations due to message re-transmission, OpenAPI rejects such identical operations within a rolling 15 second window. In this case the request will be rejected with an HttpStatus code 409 - Conflict.

This restriction applies to POST (create new orders) and PATCH (modify existing orders) requests to the /trade/v1/orders and /trade/v2/orders endpoint, with identical urls and request bodies.

If an application deliberately wishes to perform two identical order operations on the same account within a 15 second time frame, it must include an 'x-request-id' header, and the value of the 'x-request-id' must be different for each of the requests.


Akamai Network Security

At Saxo we use Akamai as a tool not only to accelerate network latency, but also as one part of our network security infrastructure.

Akamai calculates Client Reputation IP scores based on client IP behavior across all Akamai-serviced wnetworks, not just Saxo's OpenAPI. Akamai uses this score to reject requests from IP addresses which it deems untrustworthy or potentially dangerous. This rejection occurs before the request reaches our OpenAPI servers.

Depending on the severity of the reputation classification, the IP can be blocked anywhere from several minutes, to permanently.

Requests blocked due to low Client Reputation score will result in a `403` status code, with the accompanying response body:


<html>
  <head>
    <title>Access Denied</title>
  </head>
  <body>
    <h1>Access Denied</h1>
    You don\'t have permission to access http://live.logonvalidation.net/token
    on this server.
    <p>Reference #18.xxxxxxxx.xxxxxxxxxx.xxxxxxxx</p>
    <p>https://errors.edgesuite.net/18.xxxxxxxx.xxxxxxxxxx.xxxxxxxx</p>
  </body>
</html>


The above returned schema is not defined in our reference documents, as it occurs outside the scope of OpenAPI.

What should I do if my IP has been blocked?

If you believe the IP used by your OpenAPI application has been blocked in error, we request that
you review your application's access patterns. Has the application...

- Been making excessive duplicate, similar, or erroring requests?
- Been consistently hitting the defined rate limits?
- Recently introduced new functionality, which could newly introduced either of the above?


Shared IP addresses are more likely to be blocked than fully-dedicated ones. When using a shared IP to access OpenAPI, other users of that IP may influence the Client Reputation, and result in your IP being blocked!


If after this review is complete, there is still no clear cause for the Client Reputation to cause rejected requests, you can reach out to our support team so we can investigate further.

Please include your already completed review of access patterns, to assist our investigation!