Table of Contents

eConnect API Rate Limiting

1. Purpose

Rate Limiting limits the number of requests that can be made to eFacture APIs during a given period.

The mechanism is applied at the Azure API Management (APIM) level, before the request reaches the backend.

The main objectives are:

  • protect APIs from excessive request volumes;
  • prevent a customer or identity from monopolizing available resources;
  • apply a shared limit across multiple operations when they use the same counter key;
  • allow consumers to know their limit and the number of requests remaining;
  • return an HTTP 429 Too Many Requests response when the limit is exceeded.

Limits are configured in APIM through Named Values, allowing them to be adjusted without directly modifying the policies.

2. Applied Limits

Two Rate Limiting strategies are used depending on the API context.

Limit type Counter key Limit
Per CustomerId CustomerId 500 requests/minute
Per identity jwt.Issuer:jwt.Subject 20 requests/minute

3. Rate Limiting by CustomerId

For operations associated with a customer, the counter is based on the CustomerId.

The limit is:

500 requests per minute per CustomerId.

Depending on the API, the CustomerId may come from the header:

x-cegid-efacture-customer-identifier: 97809c40-b9af-4f57-a40f-c7172b38236f

or directly from the API path, for example:

/customers/{customerIdentifier}/delegate/{identityId}
/customers/{customerIdentifier}/info

In both cases, the same CustomerId must use the same counter key, so that the relevant operations share the same quota.

Example counter key:

customer:97809c40-b9af-4f57-a40f-c7172b38236f

Therefore, if several operations use this same key, their requests are accumulated within the global limit of 500 requests per minute for that customer.

4. Rate Limiting by Issuer:Subject

For APIs where no CustomerId is available, the counter is based on the identity carried by the JWT.

The limit is:

20 requests per minute per Issuer:Subject pair.

The key is built using:

jwt.Issuer:jwt.Subject

Example:

https://inte-oauth.cegid.com:55F0ED00F2ADA5BBD87D

Using the Issuer together with the Subject prevents collisions between different identity providers.

For example, the following identities have separate counters:

https://inte-oauth.cegid.com:123456
https://loginapps-dev.ebp.com:123456

Even if their Subject values are identical, their Issuer values are different.

This strategy also supports multi-authority authentication: the JWT issuer is identified, the token is validated against the corresponding authority, and Rate Limiting is then applied using the Issuer:Subject pair.

5. General Flow

APIM performs the processing before calling the backend:

API Request
    |
    v
APIM
    |
    +--> JWT validation
    |
    +--> Rate Limit key identification
    |       |
    |       +--> CustomerId: 500/min
    |       |
    |       +--> Issuer:Subject: 20/min
    |
    +--> Quota verification
    |
    +--> Backend call if quota is available

When the limit is exceeded, APIM blocks the request and returns:

HTTP/1.1 429 Too Many Requests

A request blocked by Rate Limiting is not forwarded to the backend.

6. Rate Limiting Response Headers

APIM exposes the Rate Limiting status through the following HTTP response headers:

X-RateLimit-Limit
X-RateLimit-Remaining
Retry-After

6.1. X-RateLimit-Limit

This header indicates the maximum number of requests allowed during the configured period.

For an API limited by CustomerId:

X-RateLimit-Limit: 500

This means 500 requests per minute for the relevant CustomerId.

For an API limited by Issuer:Subject:

X-RateLimit-Limit: 20

This means 20 requests per minute for the relevant identity.

6.2. X-RateLimit-Remaining

This header indicates the number of requests still available in the current Rate Limiting window.

Example:

HTTP/1.1 200 OK
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 327

The client still has requests available before reaching the limit.

For identity-based Rate Limiting, a response could for example be:

HTTP/1.1 200 OK
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 7

6.3. Retry-After

When the limit is exceeded, APIM returns:

HTTP/1.1 429 Too Many Requests

The Retry-After header indicates how long the consumer should wait before retrying the request.

Example:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
Retry-After: 38

The consumer should respect the Retry-After value and avoid immediately retrying requests in a loop.

7. 401 and 403 Responses for CustomerId Rate Limiting

The CustomerId policy uses an increment condition so that authorization responses 401 and 403 are not counted:

increment-condition="@(
    context.Response.StatusCode != 401 &&
    context.Response.StatusCode != 403
)"

Therefore:

  • 401 Unauthorized does not consume the CustomerId quota;
  • 403 Forbidden does not consume the CustomerId quota;
  • other responses handled by the policy consume the quota.

Because the increment depends on the backend response, APIM performs the increment at the end of processing. As a result, there may be a one-request offset between the value displayed in X-RateLimit-Remaining and the request on which the 429 response is triggered.

For example, with a theoretical limit of 10 requests:

Request 1  -> 200
...
Request 10 -> 200
Request 11 -> 200 / X-RateLimit-Remaining: 0
Request 12 -> 429 Too Many Requests

This behavior is related to the use of increment-condition based on context.Response.

8. Expected Consumer Behavior

Consumers should take the APIM response headers into account:

Header Meaning
X-RateLimit-Limit Maximum number of requests allowed during the period
X-RateLimit-Remaining Number of requests still available in the current window
Retry-After Delay to respect before making another request after a 429

During normal operation:

HTTP/1.1 200 OK
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 327

When the quota is exceeded:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
Retry-After: 38

After receiving a 429, the consumer should wait according to Retry-After before retrying the request.

9. Summary

                         API Request
                             |
                             v
                            APIM
                             |
                       JWT Validation
                             |
              +--------------+--------------+
              |                             |
       CustomerId available          No CustomerId
              |                             |
              v                             v
      key = CustomerId             key = Issuer:Subject
        500 req/min                   20 req/min
              |                             |
              +--------------+--------------+
                             |
                             v
                       Rate Limiting
                             |
                   +---------+---------+
                   |                   |
             Quota available      Quota exceeded
                   |                   |
                   v                   v
                Backend             HTTP 429
                                       |
                                       v
                                  Retry-After

Rate Limiting is therefore applied at two levels:

  • 500 requests per minute per CustomerId for APIs associated with a customer;
  • 20 requests per minute per Issuer:Subject for APIs whose limit is based on the JWT identity.

The X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers allow consumers to monitor their quota and adapt their behavior when a limit is reached.