> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hub2.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Limites de flux

> Ce sont les limites appliquées sur notre API.

export const method_0 = "Méthode"

export const route_0 = "Route"

export const limit_0 = "Limite réelle"

export const rationalized_0 = "Limite convertie"

export const notes_0 = "Notes"

<Note>
  Cette documentation a été mise à jour le **21/11/23**.
</Note>

## Introduction

Puisque son API est le produit phare de HUB2, une qualité de service importante est nécessaire.

Afin d'assurer un temps de réponse correct et une continuité des services, certaines limites doivent être appliquées sur les points d'entrée les plus coûteux en ressources.

Cette limite est appliquée par adresse IP, elle est donc propre à chaque utilisateur de l'API et l'utilisation d'un client A n'impactera pas l'utilisation d'un client B.

C'est d'ailleurs en ce sens que ces limites sont établies.

## Limitations de l'API

Ci-après un tableau récapitulatif des limites en place. La limite globale s'applique à toutes les autres routes.

| {method_0} | {route_0}                              | {limit_0}       | {rationalized_0} | {notes_0}    |
| :--------- | :------------------------------------- | :-------------- | :--------------- | :----------- |
| `GET`      | `/transfers`                           | 1 req / 30 sec  | 2 req / min      |              |
| `POST`     | `/transfers`                           | 75 req / 10 sec | 400 req / min    |              |
| `GET`      | `/transfers/:id`                       | 1 req / 5 sec   | 12 req / min     | *\*per :id*  |
| `GET`      | `/transfers/:id/balance`               | 1 req / 10 sec  | 6 req / min      |              |
| `GET`      | `/transfers/:id/status`                | 5 req / 5 sec   | 60 req / min     | *\*per :id*  |
| `GET`      | `/payments`                            | 1 req / 30 sec  | 2 req / min      |              |
| `GET`      | `/payments_intents`                    | 1 req / 30 sec  | 2 req / min      |              |
| `POST`     | `/payments_intents`                    | 75 req / 10 sec | 400 req / min    |              |
| `GET`      | `/payments_intents/:id`                | 1 req / 5 sec   | 12 req / min     | *\*per :id*  |
| `POST`     | `/payments_intents/:id/authentication` | 30 req / 5 sec  | 360 req / min    |              |
| `POST`     | `/payments_intents/:id/payments`       | 75 req / 10 sec | 400 req / min    |              |
| `POST`     | `/payments_intents/:id/payments/sync`  | 75 req / 10 sec | 400 req / min    |              |
| `GET`      | `/payments_intents/:id/payment-fees`   | 75 req / 10 sec | 450 req / min    |              |
| `GET`      | `/payments/:id/status`                 | 5 req / 5 sec   | 60 req / min     | *\*per :id*  |
| `GET`      | `/payments_intents/:id/status`         | 5 req / 5 sec   | 60 req / min     | *\*per :id*  |
| `POST`     | `/terminal/payments`                   | 5 req / 10 sec  | 30 req / min     |              |
| `GET`      | `/terminal/payments/:id`               | 5 req / 10 sec  | 30 req / min     |              |
| `GET`      | `/balance`                             | 75 req / 10 sec | 450 req / min    |              |
| `*`        | `*`                                    | 50 req / 5 sec  | 600 req / min    | Global limit |

<Note>
  La **limite réelle** correspond à la valeur de comment le code réagit en termes de requêtes / secondes.<br />La **limite convertie** facilite la compréhension et aide à comparer les valeurs sur une même échelle.
</Note>

<Warning>
  **Cette limite s'applique autant au trafic en mode `sandbox` qu'au trafic en mode `live`.<br />Pensez à arrêter le trafic sandbox si le flux devient important.**
</Warning>

## Comment gérer les limites

À chaque fois que l'API reçoit une requête au delà de la limite d'un point de terminaison, une erreur `Too Many Requests` avec le statut HTTP `429` sera retournée.

<Note>
  Veuillez consulter la [documentation MDN](https://developer.mozilla.org/en/docs/Web/HTTP/Status/429) à ce sujet.
</Note>

La requête échoue et ne sera pas traitée par l'API à cause de la limite de flux.

Des en-têtes sont fournis dans la réponse HTTP en cas de limitation:

| En-tête                 | Description                                                                                        |
| :---------------------- | :------------------------------------------------------------------------------------------------- |
| `Retry-After`           | En cas de limite atteinte,<br />cet en-tête fournit le temps à attendre avant la prochaine requête |
| `X-RateLimit-Limit`     | Limite en place sur le point de terminaison                                                        |
| `X-RateLimit-Remaining` | Nombre de requêtes encore possible avant d'atteindre la limite                                     |
| `X-RateLimit-Reset`     | Temps restant avant qu'une nouvelle requête puisse être faite                                      |

### Solution réactive (plus facile)

Une façon de gérer les limites de flux d'un point de vue client consiste à relancer les requêtes si elles échouent avec un code 429 :

<CodeGroup>
  ```javascript hub2-api.js theme={null}
  const MAXIMUM_TRY_COUNT = 3;
  const URL = 'https://api.hub2.io/balance;
  const CONFIGURATION = {
    method: "GET",
    headers: {
      ApiKey: MY_API_KEY,
      MerchantId: MY_MERCHANT_ID,
    },
  };

  (function requestRetry(numberOfTries) {
    fetch(URL, CONFIGURATION)
      .then(() => {
        // code here
      })
      .catch((error) => {
        if (error?.response?.status === 429) {
          if (numberOfTries > MAXIMUM_TRY_COUNT) {
            throw error;
          }

          // Adding 1 second of grace delay
          const retryAfter: number = parseInt(response.headers['retry-after'], 10) + 1;
          await new Promise((resolve) => setTimeout(resolve, retryAfter));
          return requestRetry(numberOfTries + 1);
        }
      })
  })(0);
  ```

  ```typescript hub2.service.ts theme={null}
  // Using framework NestJS
  import { HttpService } from "@nestjs/axios";
  import { Injectable } from "@nestjs/common";
  import { lastValueFrom } from "rxjs";

  @Injectable()
  export class HUB2Service {
    public static MAXIMUM_TRY_COUNT: number = 3;

    constructor(
      private readonly http: HttpService,
    ) {}

    async requestRetry(numberOfTries: number = 0): Promise<any> {
      const url = 'https://api.hub2.io/balance;
      const config = {
        headers: {
          ApiKey: MY_API_KEY,
          MerchantId: MY_MERCHANT_ID,
        },
      };
      try {
        const response = await lastValueFrom(this.http.post(url, {}, config));
      } catch (error) {
        if (error?.response?.status === 429) {
          if (numberOfTries > HUB2Service.MAXIMUM_TRY_COUNT) {
            throw error;
          }

          // Adding 1 second of grace delay
          const retryAfter: number = parseInt(response.headers['retry-after'], 10) + 1;
          await new Promise((resolve) => setTimeout(resolve, retryAfter));
          return this.requestRetry(numberOfTries + 1);
        }
      }
    }
  }
  ```
</CodeGroup>

### Solution pro-active (plus compliquée)

La solution proactive est plus délicate, elle consiste à préparer une quantité de requêtes prêtes dans un tableau, autant que la limite de flux de la destination. Lorsque le tableau est vide, alors la prochaine requête attend en ligne d'avoir une place qui se libère.

Veuillez consulter [cet article intéressant](https://www.useanvil.com/blog/engineering/throttling-and-consuming-apis-with-429-rate-limits/) sur comment implémenter la gestion de la limite de flux côté client, particulièrement les approches 4 et 4.1.

## Conclusion

Dans un monde parfait, il n'y aurait aucune limite de flux. Toutefois dans le monde réel, cela aide à empêcher les abus et à maintenir un service stable pour chacun.

L'équipe travaille de manière journalière pour améliorer la stabilité et les performances de l'API et cette page sera aussitôt mise à jour dès lors que des améliorations permettent de relâcher les limites.
