> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-actions-triggers-prototype.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Appeler une API de fournisseur d’identité

> Décrit comment appeler l’API d’un fournisseur d’identité externe.

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

Lorsque vous authentifiez avec succès un utilisateur auprès d’un fournisseur d’identité externe (<Tooltip href="/docs/fr-ca/glossary?term=idp" tip="Fournisseur d’identité (IdP)
Service de stockage et de gestion des identités numériques." cta="Voir le glossaire">IdP</Tooltip>), tel que Facebook ou GitHub, l’IdP inclut souvent un jeton d’accès dans le profil utilisateur qu’il renvoie à Auth0.

Vous pouvez récupérer et utiliser ce jeton pour appeler l’API de l’IdP.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Cet article suppose que vous avez déjà configuré la connexion avec l’IdP de votre choix. Si ce n’est pas le cas, accédez à [Fournisseurs d’identités pris en charge par Auth0](/docs/fr-ca/authenticate/identity-providers/social-identity-providers), sélectionnez le fournisseur d’identités de votre choix et suivez les étapes de configuration.
</Callout>

La procédure à suivre diffère selon que votre code s’exécute dans le système dorsal ou dans le système du côté client.

* Si votre code s’exécute dans le système dorsal, nous pouvons supposer que votre serveur est fiable pour stocker des secrets en toute sécurité (comme vous le verrez, nous utilisons un secret dans le scénario du système dorsal). Si c’est le cas, passez à la section [système dorsal](#from-the-backend) de cet article.
* Si votre code s’exécute dans le système du côté client (par exemple, il s’agit d’une application à page unique, d’une application native de bureau ou d’une application mobile), votre application ne peut pas conserver les informations d’identification de manière sécurisée et doit suivre une autre approche. Dans ce cas, passez à la section [système du côté client](#from-the-frontend) de cet article.

## Depuis le système dorsal

Lorsque vous authentifiez un utilisateur, l’IdP inclut souvent un jeton d’accès dans le profil utilisateur qu’il renvoie à Auth0.

Pour des raisons de sécurité et de conformité, Auth0 n’envoie pas ce jeton à votre application dans le cadre du profil utilisateur. Pour l’obtenir, vous devez accéder à <Tooltip href="/docs/fr-ca/glossary?term=management-api" tip="Management API
Un produit permettant aux clients d’effectuer des tâches administratives." cta="Voir le glossaire">Management API</Tooltip> d’Auth0 et récupérer le profil complet de l’utilisateur.

1. Obtenez un jeton d’accès qui vous permet d’appeler la [Management API d’Auth0](/docs/fr-ca/api/management/v2).
2. Appelez le point de terminaison [Obtenir les utilisateurs selon leurs ID](/docs/fr-ca/api/management/v2#!/Users/get_users_by_id) du Management API d’Auth0 à l’aide du jeton d’accès obtenu à la première étape. Ce point final renvoie le profil complet de l’utilisateur, qui contient le jeton d’accès à l’IdP.
3. Extraire le jeton d’accès de l’IdP de la réponse et l’utiliser pour appeler l’API de l’IdP.

### Étape 1 : Obtenir un jeton

Vous aurez besoin d’un jeton d’accès pour appeler la [Management API](/docs/fr-ca/api/management/v2).

#### Créer une application d’essai pour Management API

Si c’est la première fois que vous demandez un [Jeton Management APIv2](/docs/fr-ca/api/management/v2/tokens), vous devrez créer et configurer une application qui peut être utilisée pour appeler Management API :

1. Naviguez vers [Auth0 Dashboard > Applications > API](https://manage.auth0.com/#/apis), et sélectionnez [Auth0 Management API](https://manage.auth0.com/#/apis/management/authorized-clients).
2. Sélectionnez la vue **Explorateur d’API** et cliquez sur **Créer et autoriser une application d’essai**.

Cela créera une nouvelle application et accordera toutes les permissions de Management API, ce qui signifie que les jetons générés pour cette application pourront accéder à tous les points de terminaison du Management API.

<Card title="Vous ne voyez pas le bouton?">
  Si vous ne voyez pas ce bouton, cela signifie que vous avez au moins une autre application autorisée pour Management API. Dans ce cas, vous pouvez soit mettre à jour les permissions de l’application existante et l’utiliser, ou en créer une en suivant ces étapes :

  1. Naviguez vers [Auth0 Dashboard > Applications > Applications](https://manage.auth0.com/#/applications), et sélectionnez **Créer une application**.
  2. Sélectionnez **Applications machine-machine**, puis **Créer**.
  3. Dans le menu déroulant **Sélectionner une API**, sélectionnez `Auth0 Management API`.
  4. Autorisez les permissions requises, puis sélectionnez **Authorize (Autoriser)**.
  5. Sélectionnez l’affichage **API**, puis activez le bouton bascule **Management API Auth0**.
</Card>

<Warning>
  Pour des raisons de sécurité, nous vous conseillons de n’attribuer que les permissions nécessaires à votre application. Pour ce cas particulier, les permissions nécessaires sont : `read:users`, `read:user_idp_tokens`. Les permissions nécessaires sont répertoriées pour chaque point de terminaison dans [Explorateur de Management API](/docs/fr-ca/api/management/v2).
</Warning>

Pour accorder ou supprimer des permissions de Management API d’Auth0 [enregistrée](https://manage.auth0.com/#/apis/management/authorized-clients), sélectionnez la [**vue**Machine to Machine Applications (Applications de communication entre machines)](https://manage.auth0.com/#/apis/management/authorized-clients) :

<Frame>
  <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/mxRp7IkiVukPESZw/docs/images/fr-ca/cdy7uua7fh8z/6nuMjQMrTWhoVqtRwJBQz7/edd19556e26c988d313878a04c4a1618/2025-02-25_11-14-55.png?fit=max&auto=format&n=mxRp7IkiVukPESZw&q=85&s=6cac8c17a56069c82fe2064b45d1b07c" alt="Modifier les permissions accordées à l'application" width="898" height="836" data-path="docs/images/fr-ca/cdy7uua7fh8z/6nuMjQMrTWhoVqtRwJBQz7/edd19556e26c988d313878a04c4a1618/2025-02-25_11-14-55.png" />
</Frame>

#### Obtenir le jeton de Management API

Vous avez maintenant terminé la configuration et êtes prêt à obtenir votre jeton de Management API :

1. À partir de la [Management API d’Auth0 enregistrée](https://manage.auth0.com/#/apis/management/authorized-clients) , sélectionnez la [**vue**Essai](https://manage.auth0.com/#/apis/management/test).
2. Choisissez votre application dans le menu déroulant **Application** pour pré-remplir les extraits prêts à l’emploi avec des variables personnalisées.
3. Choisissez le langage de votre choix pour l’extrait, puis copiez-le et exécutez-le.
4. Extrayez la propriété `access_token` de la réponse. C’est ce que vous utiliserez pour accéder à Management API.

<Card title="À quoi servent les snippets?">
  Les snippets font une opération `POST` au point de terminaison [/oauth/token de l’Auth0 Authentication API (API d’authentification Auth0)](/docs/fr-ca/api/authentication#client-credentials) à l’aide de l’autorisation **OAuth 2.0 Client Credentials (Authentifiants client OAuth 2.0)**. Il s’agit de l’autorisation que les processus machine-machine utilisent pour accéder à une API. Pour en savoir plus sur le flux, lisez [Flux des identifiants client](/docs/fr-ca/get-started/authentication-and-authorization-flow/client-credentials-flow).
</Card>

#### Expiration du jeton

Par défaut, le jeton que vous avez reçu expire dans 24 heures (86 400 secondes). Pour changer cela :

1. Naviguez vers [Auth0 Dashboard > Applications > API](https://manage.auth0.com/#/apis), et sélectionnez [Auth0 Management API](https://manage.auth0.com/#/apis/management/authorized-clients).
2. Sélectionnez la vue **Paramètres**, localisez le champ **Expiration du jeton (secondes)**, saisissez une nouvelle valeur et cliquez sur **Enregistrer**. La valeur maximale que vous pouvez définir est de 2 592 000 secondes (30 jours), mais nous vous recommandons de conserver la valeur par défaut.

Le prochain jeton que vous générerez utilisera le délai d’expiration mis à jour.

<Warning>
  Ces jetons**ne peuvent pas être révoqués**. Pour minimiser les risques, nous vous conseillons d’émettre des jetons de courte durée et d’octroyer uniquement les permissions nécessaires pour chaque application. Dans un environnement de production, vous pouvez configurer un simple interface de ligne de commande qui récupérera un nouveau jeton lorsque l’ancien expirera.
</Warning>

### Étape 2 : Obtenir le profil utilisateur complet

Pour obtenir le profil d’un utilisateur, appelez le point de terminaison [Obtenir un utilisateur](/docs/fr-ca/api/management/v2#!/Users/get_users_by_id) du Management API en utilisant le jeton d’accès que vous avez extrait dans la section précédente.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://{yourDomain}/api/v2/users/%7BuserId%7D' \
    --header 'authorization: Bearer {yourAccessToken}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/api/v2/users/%7BuserId%7D");
  var request = new RestRequest(Method.GET);
  request.AddHeader("authorization", "Bearer {yourAccessToken}");
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/api/v2/users/%7BuserId%7D"

  	req, _ := http.NewRequest("GET", url, nil)

  	req.Header.Add("authorization", "Bearer {yourAccessToken}")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.get("https://{yourDomain}/api/v2/users/%7BuserId%7D")
    .header("authorization", "Bearer {yourAccessToken}")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://{yourDomain}/api/v2/users/%7BuserId%7D',
    headers: {authorization: 'Bearer {yourAccessToken}'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```objc Obj-C theme={null}
  #import <Foundation/Foundation.h>

  NSDictionary *headers = @{ @"authorization": @"Bearer {yourAccessToken}" };

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/api/v2/users/%7BuserId%7D"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"GET"];
  [request setAllHTTPHeaderFields:headers];

  NSURLSession *session = [NSURLSession sharedSession];
  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                  if (error) {
                                                      NSLog(@"%@", error);
                                                  } else {
                                                      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                      NSLog(@"%@", httpResponse);
                                                  }
                                              }];
  [dataTask resume];
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/api/v2/users/%7BuserId%7D",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer {yourAccessToken}"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  headers = { 'authorization': "Bearer {yourAccessToken}" }

  conn.request("GET", "/{yourDomain}/api/v2/users/%7BuserId%7D", headers=headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/api/v2/users/%7BuserId%7D")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)
  request["authorization"] = 'Bearer {yourAccessToken}'

  response = http.request(request)
  puts response.read_body
  ```

  ```swift Swift theme={null}
  import Foundation

  let headers = ["authorization": "Bearer {yourAccessToken}"]

  let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/api/v2/users/%7BuserId%7D")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "GET"
  request.allHTTPHeaderFields = headers

  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  })

  dataTask.resume()
  ```
</AuthCodeGroup>

Remplacer ces valeurs :

* `{userId}` : ID de l’utilisateur pour lequel vous souhaitez appeler l’API de l’IdP.
* `{yourAccessToken}` : Jeton d’accès que vous avez extrait dans la section précédente.

<Card title="Où puis-je trouver l’identifiant utilisateur?">
  - À des fins de test, vous pouvez trouver un ID utilisateur dans [Auth0 Dashboard > Gestion des utilisateurs > Utilisateurs](https://manage.auth0.com/#/users). Localisez un utilisateur, et copiez la valeur du champ **user\_id**.

  - Pour votre implémentation, vous pouvez soit extraire l’ID utilisateur de la demande `sub` dans le [jeton d’ID](/docs/fr-ca/secure/tokens/id-tokens), soit appeler le [point de terminaison /userinfo](/docs/fr-ca/api/authentication#get-user-info) de l’Authentication API et l’extraire de la propriété de réponse `user_id`.
</Card>

### Étape 3 : Extraire le jeton d’accès de l’IdP

Vous pouvez trouver le jeton d’accès utilisé pour appeler l’API de l’IdP dans le tableau `identities` de l’utilisateur : `user.identities[0].access_token`.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Pour certains fournisseurs d’identités, Auth0 stocke également un jeton d’actualisation, que vous pouvez utiliser pour obtenir un nouveau jeton d’accès pour l’IdP. Compatible avec : BitBucket, Google (OAuth 2.0), OAuth 2.0, SharePoint et Azure AD. Pour en savoir plus, consultez [Jetons d’accès de fournisseur d’identités](/docs/fr-ca/secure/tokens/access-tokens/identity-provider-access-tokens).
</Callout>

Dans la plupart des cas, l’utilisateur n’aura qu’une seule identité, mais si l’utilisateur s’est connecté plusieurs fois via différentes connexions et que vous avez utilisé l’[association de comptes](/docs/fr-ca/manage-users/user-accounts/user-account-linking/link-user-accounts), il peut y en avoir plusieurs.

Dans cet exemple de réponse, nous voyons que notre utilisateur n’a qu’une seule identité : `google-oauth2`.

```json lines theme={null}
{
  "email": "john.doe@test.com",
  "email_verified": true,
  "name": "John Doe",
  "given_name": "John",
  "family_name": "Doe",
  "picture": "https://myavatar/photo.jpg",
  "gender": "male",
  "locale": "en",
  "updated_at": "2017-03-15T07:14:32.451Z",
  "user_id": "google-oauth2|111199914890750704174",
  "nickname": "john.doe",
  "identities": [
    {
      "provider": "google-oauth2",
      "access_token": "ya29.GlsPBCS6ahokDlgCYnVLnDKNE71HBXPEzNhAPoKJLAGKDSe1De3_xclahNcdZXoU-26hCpa8h6240TV86dtaEQ4ZWoeeZduHDq_yeu9QyQqUr--S9B2CR9YJrLTD",
      "expires_in": 3599,
      "user_id": "111199914890750704174",
      "connection": "google-oauth2",
      "isSocial": true
    }
  ],
  "created_at": "2017-03-15T07:13:41.134Z",
  "last_ip": "127.0.0.1",
  "last_login": "2017-03-15T07:14:32.451Z",
  "logins_count": 99
}
```

Vous êtes maintenant prêt à appeler l’API de l’IdP. Veuillez vous référer à la documentation de l’IdP pour plus de détails sur la façon de procéder.

<Warning>
  N’exposez pas les jetons IdP à votre application du côté client! Si votre application est publique, consultez la [section frontend](#from-the-frontend) de cet article.
</Warning>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Pour en savoir plus sur la manière de demander des permissions spécifiques pour un jeton d’accès de fournisseur d’identités, consultez [Ajouter des permissions/autorisations pour appeler les API du fournisseur d’identité](/docs/fr-ca/authenticate/identity-providers/adding-scopes-for-an-external-idp).
</Callout>

## Depuis le côté client

Si vous travaillez avec une application publique (application à page unique, bureau natif ou application mobile), vous êtes au bon endroit.

Lorsque vous travaillez avec une application du côté client, le processus d’appel des IdP API diffère du processus du système dorsal, car les applications du côté client sont des applications publiques qui **ne peuvent pas conserver les informations d’identification en toute sécurité**. Étant donné que le code d’une application à page unique peut être consulté et modifié, et que les applications natives/mobiles peuvent être décompilées et inspectées, on ne peut pas leur faire confiance pour conserver des informations sensibles telles que des clés secrètes ou des mots de passe.

En particulier, elles ne peuvent pas contenir en toute sécurité le **Secret du client** pour l’application de communication entre machines, laquelle vous utilisez pour appeler `/oauth/token` au cours de la première étape du processus dorsal.

Au lieu de cela, vous devez construire un proxy pour votre système dorsal et l’exposer à votre application en tant qu’API.

### Construire un proxy

Tout d’abord, vous allez construire un processus dans votre programme dorsal qui mettra en œuvre les étapes incluses dans [la section du système dorsal](#from-the-backend) de cet article, et l’exposer à votre application en tant qu’API.

Vous appellerez l’API de l’IdP à partir du même processus dorsal, de sorte que le jeton d’accès ne soit jamais exposé à votre application publique.

Ensuite, vous appelerez l’API de votre proxy à partir de votre application publique en utilisant le [Flux de code d’autorisation avec Proof Key for Code Exchange (PKCE)](/docs/fr-ca/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce).

<Card title="Montrez-moi comment">
  Si vous ne l’avez pas encore implémenté, vous pourriez trouver notre scénario d’architecture de [Applications à page unique avec API](/docs/fr-ca/get-started/architecture-scenarios/spa-api) utile. Il couvre un scénario différent, mais explique comment configurer Auth0, comment faire une requête à une API depuis une SPA et comment implémenter des validations API. Il inclut un exemple qui utilise [Angular 2](https://github.com/auth0-samples/auth0-pnp-exampleco-timesheets/tree/master/timesheets-spa/angular) et [Node.js](https://github.com/auth0-samples/auth0-pnp-exampleco-timesheets/tree/master/timesheets-api/node).

  Nous offrons également une variation avec [Applications mobiles avec API](/docs/fr-ca/get-started/architecture-scenarios/mobile-api) (l’exemple utilise [Android](https://github.com/auth0-samples/auth0-pnp-exampleco-timesheets/tree/master/timesheets-mobile/android) et [Node.js](https://github.com/auth0-samples/auth0-pnp-exampleco-timesheets/tree/master/timesheets-api/node)).
</Card>
