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

> Découvrez comment effectuer une importation groupée d’utilisateurs avec Management API.

# Importation groupée d’utilisateurs

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>;
};

Vous pouvez effectuer une importation groupée d’utilisateurs dans Auth0 à l’aide du point de terminaison [Create Import Users Job](https://auth0.com/docs/api/management/v2#!/Jobs/post_users_imports). Les importations groupées d’utilisateurs sont utiles pour migrer des utilisateurs depuis une base de données ou un service existant vers Auth0.

<Warning>
  Si vous essayez d’utiliser plus d’une méthode de migration (par exemple, une migration automatique suivie d’une importation groupée d’utilisateurs), vous risquez d’obtenir une erreur `DUPLICATED_USER`. Cette erreur indique que l’utilisateur existe dans le répertoire interne des utilisateurs d’Auth0, mais pas dans votre locataire. Pour corriger cette erreur, supprimez l’utilisateur à l’aide du point de terminaison [Delete a Connection User](https://auth0.com/docs/api/management/v2#!/Connections/delete_users_by_email) de l’Auth0 Management API, puis réessayez l’importation.
</Warning>

<div id="prerequisites">
  ## Prérequis
</div>

Avant de lancer la tâche d’importation des utilisateurs :

* Configurez une connexion de base de données pour y importer les utilisateurs et activez-la pour au moins une application.
* Si vous importez des mots de passe, assurez-vous qu’ils sont hachés à l’aide de l’un des algorithmes pris en charge. Les utilisateurs dont les mots de passe sont hachés avec des algorithmes non pris en charge devront réinitialiser leur mot de passe à leur première connexion après l’importation en bloc.
* Si vous importez des inscriptions à la <Tooltip tip="Authentification multifacteur (MFA) : processus d’authentification de l’utilisateur qui utilise un facteur en plus du nom d’utilisateur et du mot de passe, comme un code envoyé par SMS." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=MFA">MFA</Tooltip>, assurez-vous qu’il s’agit d’un type pris en charge : `email`, `phone` ou `totp`.
* [Obtenez un jeton Management API](/fr-CA/docs/secure/tokens/access-tokens/management-api-access-tokens) pour les requêtes au point de terminaison de la tâche.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Si vous utilisez un fichier d’exportation provenant d’un locataire Auth0, vous devez convertir le fichier exporté de `ndjson` en [JSON](/fr-CA/docs/manage-users/user-migration/bulk-user-exports#json-compatible-format). Pour conserver les mêmes identifiants utilisateur, vous devez supprimer le `préfixe auth0|` de tous les identifiants utilisateur importés.

  Le processus d’importation ajoute automatiquement le préfixe `auth0|` aux identifiants utilisateur importés. Si vous ne supprimez pas le préfixe `auth0|` avant l’importation, les identifiants utilisateur seront renvoyés sous la forme `auth0|auth0|...`
</Callout>

<div id="create-users-json-file">
  ## Créer le fichier JSON des utilisateurs
</div>

Créez un fichier JSON contenant les données utilisateur que vous souhaitez importer dans Auth0. La manière d’exporter ces données vers un fichier JSON varie selon votre base de données d’utilisateurs actuelle. Le point de terminaison <Tooltip tip="Management API : un produit qui permet aux clients d’effectuer des tâches administratives." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Management+API">Management API</Tooltip> s’attend à recevoir le fichier JSON par sections. Ainsi, au lieu d’utiliser `fs.readFileSync`, vous devez utiliser `fs.createReadStream`. Le point de terminaison attend un flux de lecture transmis par pipeline plutôt que le fichier JSON complet.

Pour en savoir plus sur le schéma du fichier JSON et voir des exemples, consultez [Schéma de base de données pour l’importation en masse et exemples](/fr-CA/docs/manage-users/user-migration/bulk-user-import-database-schema-and-examples).

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  La taille maximale d’un fichier pour une importation en masse est de 500 KB. Vous devrez lancer plusieurs importations si vos données dépassent cette limite.
</Callout>

<div id="request-bulk-user-import">
  ## Demander l’importation groupée d’utilisateurs
</div>

Pour démarrer une tâche d’importation groupée d’utilisateurs, effectuez une requête `POST` vers le point de terminaison [Create Import Users Job](https://auth0.com/docs/api/management/v2#!/Jobs/post_users_imports). Assurez-vous de remplacer les valeurs d’espace réservé `MGMT_API_ACCESS_TOKEN`, `USERS_IMPORT_FILE.json`, `CONNECTION_ID` et `EXTERNAL_ID` par votre <Tooltip tip="Jeton d’accès : information d’autorisation, sous la forme d’une chaîne opaque ou d’un JWT, utilisée pour accéder à une API." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Access+Token">jeton d’accès</Tooltip> de la Management API, votre fichier JSON d’utilisateurs, l’[ID de connexion](/fr-CA/docs/authenticate/identity-providers/locate-the-connection-id) de la base de données et l’ID externe, respectivement.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/api/v2/jobs/users-imports' \
    --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
    --form users=@USERS_IMPORT_FILE.json \
    --form connection_id=CONNECTION_ID \
    --form external_id=EXTERNAL_ID
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/api/v2/jobs/users-imports");
  var request = new RestRequest(Method.POST);
  request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
  request.AddHeader("content-type", "multipart/form-data; boundary=---011000010111000001101001");
  request.AddParameter("multipart/form-data; boundary=---011000010111000001101001", "-----011000010111000001101001\r
  Content-Disposition: form-data; name="users"; filename="USERS_IMPORT_FILE.json"\r
  Content-Type: text/json\r
  \r
  \r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="connection_id"\r
  \r
  CONNECTION_ID\r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="external_id"\r
  \r
  EXTERNAL_ID\r
  -----011000010111000001101001--\r
  ", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

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

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

  func main() {

  	url := "https://{yourDomain}/api/v2/jobs/users-imports"

  	payload := strings.NewReader("-----011000010111000001101001\r
  Content-Disposition: form-data; name="users"; filename="USERS_IMPORT_FILE.json"\r
  Content-Type: text/json\r
  \r
  \r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="connection_id"\r
  \r
  CONNECTION_ID\r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="external_id"\r
  \r
  EXTERNAL_ID\r
  -----011000010111000001101001--\r
  ")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
  	req.Header.Add("content-type", "multipart/form-data; boundary=---011000010111000001101001")

  	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.post("https://{yourDomain}/api/v2/jobs/users-imports")
    .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
    .header("content-type", "multipart/form-data; boundary=---011000010111000001101001")
    .body("-----011000010111000001101001\r
  Content-Disposition: form-data; name="users"; filename="USERS_IMPORT_FILE.json"\r
  Content-Type: text/json\r
  \r
  \r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="connection_id"\r
  \r
  CONNECTION_ID\r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="external_id"\r
  \r
  EXTERNAL_ID\r
  -----011000010111000001101001--\r
  ")
    .asString();
  ```

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

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/api/v2/jobs/users-imports',
    headers: {
      authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
      'content-type': 'multipart/form-data; boundary=---011000010111000001101001'
    },
    data: '-----011000010111000001101001\r
  Content-Disposition: form-data; name="users"; filename="USERS_IMPORT_FILE.json"\r
  Content-Type: text/json\r
  \r
  \r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="connection_id"\r
  \r
  CONNECTION_ID\r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="external_id"\r
  \r
  EXTERNAL_ID\r
  -----011000010111000001101001--\r
  '
  };

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

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

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/api/v2/jobs/users-imports",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "-----011000010111000001101001\r
  Content-Disposition: form-data; name="users"; filename="USERS_IMPORT_FILE.json"\r
  Content-Type: text/json\r
  \r
  \r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="connection_id"\r
  \r
  CONNECTION_ID\r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="external_id"\r
  \r
  EXTERNAL_ID\r
  -----011000010111000001101001--\r
  ",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer MGMT_API_ACCESS_TOKEN",
      "content-type: multipart/form-data; boundary=---011000010111000001101001"
    ],
  ]);

  $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("{yourDomain}")

  # Lire le fichier d'importation des utilisateurs
  with open("USERS_IMPORT_FILE.json", "rb") as f:
      file_contents = f.read()

  payload = (
      "-----011000010111000001101001\r\n"
      "Content-Disposition: form-data; name=\"users\"; filename=\"USERS_IMPORT_FILE.json\"\r\n"
      "Content-Type: application/json\r\n"
      "\r\n"
      + file_contents.decode("utf-8") + "\r\n"
      "-----011000010111000001101001\r\n"
      "Content-Disposition: form-data; name=\"connection_id\"\r\n"
      "\r\n"
      "CONNECTION_ID\r\n"
      "-----011000010111000001101001\r\n"
      "Content-Disposition: form-data; name=\"external_id\"\r\n"
      "\r\n"
      "EXTERNAL_ID\r\n"
      "-----011000010111000001101001--\r\n"
  )

  headers = {
      'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
      'content-type': "multipart/form-data; boundary=---011000010111000001101001"
      }

  conn.request("POST", "/api/v2/jobs/users-imports", payload, 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/jobs/users-imports")

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

  request = Net::HTTP::Post.new(url)
  request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
  request["content-type"] = 'multipart/form-data; boundary=---011000010111000001101001'
  request.body = "-----011000010111000001101001\r
  Content-Disposition: form-data; name="users"; filename="USERS_IMPORT_FILE.json"\r
  Content-Type: text/json\r
  \r
  \r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="connection_id"\r
  \r
  CONNECTION_ID\r
  -----011000010111000001101001\r
  Content-Disposition: form-data; name="external_id"\r
  \r
  EXTERNAL_ID\r
  -----011000010111000001101001--\r
  "

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

| Paramètre               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `users`                 | Fichier au format JSON contenant les utilisateurs à importer.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `connection_id`         | ID de la connexion dans laquelle les utilisateurs seront insérés. Vous pouvez récupérer cet ID à l’aide du point de terminaison [GET /api/v2/connections](https://auth0.com/docs/api/management/v2#!/Connections/get_connections).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `upsert`                | Valeur booléenne : `false` par défaut. Lorsqu’elle est définie à `false`, les utilisateurs existants qui correspondent à une adresse courriel, à un ID d’utilisateur, à un téléphone ou à un nom d’utilisateur échoueront. Lorsqu’elle est définie à `true`, les utilisateurs existants qui correspondent à une adresse courriel seront mis à jour, mais uniquement avec des attributs pouvant être mis à jour par upsert. Pour obtenir la liste des champs du profil utilisateur pouvant faire l’objet d’un upsert lors de l’importation, consultez [User Profile Structure: User profile attributes](/fr-CA/docs/manage-users/user-accounts/user-profiles/user-profile-structure#user-profile-attributes). Remarque : fournir une entrée utilisateur en double dans le fichier d’importation entraînera une erreur. Dans ce cas, Auth0 n’effectuera pas d’insertion suivie d’une mise à jour. |
| `external_id`           | Chaîne facultative définie par l’utilisateur qui peut servir à faire le lien entre plusieurs tâches. Elle est renvoyée dans la réponse d’état de la tâche.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `send_completion_email` | Valeur booléenne : `true` par défaut. Lorsqu’elle est définie à `true`, un courriel de fin de traitement est envoyé à tous les propriétaires du locataire une fois la tâche d’importation terminée. Si vous ne voulez *pas* que des courriels soient envoyés, vous devez définir explicitement ce paramètre à `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |

Si la demande réussit, vous recevrez une réponse semblable à la suivante :

```json lines theme={null}
{
  "status": "pending",
  "type": "users_import",
  "created_at": "",
  "id": "job_abc123",
  "connection_id": "CONNECTION_ID",
  "upsert": false,
  "external_id": "EXTERNAL_ID",
  "send_completion_email": true
}
```

L’entité renvoyée représente la tâche d’importation.

Lorsque la tâche d’importation d’utilisateurs se termine et que `send_completion_email` a été défini à `true`, le ou les administrateurs du locataire recevront un courriel les informant si la tâche a échoué ou réussi. Dans le cas d’une tâche ayant échoué, le courriel peut aviser le ou les administrateurs qu’une erreur est survenue lors de l’analyse du fichier JSON des utilisateurs pendant l’importation.

<div id="concurrent-import-jobs">
  ### Tâches d’importation concurrentes
</div>

Le point de terminaison [Create Import Users Job](https://auth0.com/docs/api/management/v2#!/Jobs/post_users_imports) est limité à deux tâches d’importation concurrentes. Si vous demandez des tâches supplémentaires alors que deux sont déjà en attente, une réponse `429 Too Many Requests` est renvoyée :

```json lines theme={null}
{
  "statusCode": 429,
  "error": "Too Many Requests",
  "message": "There are 2 active import users jobs, please wait until some of them are finished and try again
}
```

<div id="check-job-status">
  ## Vérifier l’état de la tâche
</div>

Pour vérifier l’état d’une tâche, envoyez une requête `GET` au point de terminaison [Get a Job](https://auth0.com/docs/api/management/v2#!/Jobs/get_jobs_by_id). Assurez-vous de remplacer les valeurs d’espace réservé `MGMT_API_ACCESS_TOKEN` et `JOB_ID` par votre jeton d’accès de la Management API et l’id de la tâche d’importation des utilisateurs.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://{yourDomain}/api/v2/jobs/JOB_ID' \
    --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
    --header 'content-type: application/json'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/api/v2/jobs/JOB_ID");
  var request = new RestRequest(Method.GET);
  request.AddHeader("content-type", "application/json");
  request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
  IRestResponse response = client.Execute(request);
  ```

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

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

  func main() {

  	url := "https://{yourDomain}/api/v2/jobs/JOB_ID"

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

  	req.Header.Add("content-type", "application/json")
  	req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")

  	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/jobs/JOB_ID")
    .header("content-type", "application/json")
    .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
    .asString();
  ```

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

  var options = {
    method: 'GET',
    url: 'https://{yourDomain}/api/v2/jobs/JOB_ID',
    headers: {
      'content-type': 'application/json',
      authorization: 'Bearer MGMT_API_ACCESS_TOKEN'
    }
  };

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

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

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/api/v2/jobs/JOB_ID",
    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 MGMT_API_ACCESS_TOKEN",
      "content-type: application/json"
    ],
  ]);

  $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("{yourDomain}")

  headers = {
      'content-type': "application/json",
      'authorization': "Bearer MGMT_API_ACCESS_TOKEN"
      }

  conn.request("GET", "/api/v2/jobs/JOB_ID", 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/jobs/JOB_ID")

  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["content-type"] = 'application/json'
  request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

Selon l’état de la tâche d’importation des utilisateurs, vous recevrez une réponse semblable à l’une des suivantes :

**En attente**

```json lines theme={null}
{
  "status": "pending",
  "type": "users_import",
  "created_at": "",
  "id": "job_abc123",
  "connection_id": "CONNECTION_ID",
  "external_id": "EXTERNAL_ID"
}
```

**Terminé**

Si une tâche est terminée, la réponse sur l’état de la tâche inclura le nombre total d’enregistrements traités avec succès, ayant échoué, insérés et mis à jour.

```json lines theme={null}
{
  "status": "completed",
  "type": "users_import",
  "created_at": "",
  "id": "job_abc123",
  "connection_id": "CONNECTION_ID",
  "external_id": "EXTERNAL_ID",
  "summary": {
    "failed": 0,
    "updated": 0,
    "inserted": 1,
    "total": 1
  }
}
```

**Échec**

S’il y a une erreur dans la tâche, son état sera renvoyé comme ayant échoué. Notez toutefois que des renseignements utilisateur non valides, comme un courriel invalide, n’entraîneront pas l’échec de l’ensemble de la tâche.

```json lines theme={null}
{
  "status": "failed",
  "type": "users_import",
  "created_at": "",
  "id": "job_abc123",
  "connection_id": "CONNECTION_ID",
  "external_id": "EXTERNAL_ID",
}
```

Pour obtenir plus de détails sur les entrées en échec, consultez **Récupérer les entrées en échec** ci-dessous.

<div id="job-timeouts">
  ## Délais d’expiration des tâches
</div>

Toutes les tâches d’importation d’utilisateurs expirent après **deux (2) heures**. Si votre tâche ne se termine pas dans ce délai, elle est marquée en échec.

De plus, toutes les données liées à votre tâche sont automatiquement supprimées après 24 heures et ne sont plus accessibles ensuite. Par conséquent, **nous vous recommandons fortement d’enregistrer les résultats de la tâche au moyen du mécanisme de stockage de votre choix**.

<div id="retrieve-failed-entries">
  ## Récupérer les entrées en échec
</div>

<Warning>
  Toutes les données liées à la tâche sont automatiquement supprimées après 24 heures et ne sont plus accessibles ensuite. C’est pourquoi nous vous recommandons fortement d’enregistrer les résultats de la tâche à l’aide du mécanisme de stockage de votre choix.
</Warning>

S’il y a eu des erreurs lors de la tâche d’importation d’utilisateurs, vous pouvez en obtenir les détails en envoyant une requête `GET` au point de terminaison [Obtenir les détails des erreurs de tâche](https://auth0.com/docs/api/management/v2#!/Jobs/get_errors). Assurez-vous de remplacer les valeurs d’espace réservé `MGMT_API_ACCESS_TOKEN` et `JOB_ID` par votre jeton d’accès de la Management API et l’ID de votre tâche d’importation d’utilisateurs.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://{yourDomain}/api/v2/jobs/JOB_ID/errors' \
    --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
    --header 'content-type: application/json'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/api/v2/jobs/JOB_ID/errors");
  var request = new RestRequest(Method.GET);
  request.AddHeader("content-type", "application/json");
  request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
  IRestResponse response = client.Execute(request);
  ```

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

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

  func main() {

  	url := "https://{yourDomain}/api/v2/jobs/JOB_ID/errors"

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

  	req.Header.Add("content-type", "application/json")
  	req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")

  	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/jobs/JOB_ID/errors")
    .header("content-type", "application/json")
    .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
    .asString();
  ```

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

  var options = {
    method: 'GET',
    url: 'https://{yourDomain}/api/v2/jobs/JOB_ID/errors',
    headers: {
      'content-type': 'application/json',
      authorization: 'Bearer MGMT_API_ACCESS_TOKEN'
    }
  };

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

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

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/api/v2/jobs/JOB_ID/errors",
    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 MGMT_API_ACCESS_TOKEN",
      "content-type: application/json"
    ],
  ]);

  $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("{yourDomain}")

  headers = {
      'content-type': "application/json",
      'authorization': "Bearer MGMT_API_ACCESS_TOKEN"
      }

  conn.request("GET", "/api/v2/jobs/JOB_ID/errors", 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/jobs/JOB_ID/errors")

  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["content-type"] = 'application/json'
  request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

Si la requête aboutit, vous recevrez une réponse semblable à la suivante. Les champs sensibles, comme `hash.value`, seront masqués dans la réponse.

```json lines theme={null}
[
    {
        "user": {
            "email": "test@test.io",
            "user_id": "7af4c65cb0ac6e162f081822422a9dde",
            "custom_password_hash": {
                "algorithm": "ldap",
                "hash": {
                    "value": "*****"
                }
            }
        },
        "errors": [
            {
                "code": "...",
                "message": "...",
                "path": "..."
            }
        ]
    }
]
```

Chaque objet d’erreur inclut un code d’erreur et un message qui fournit plus de détails sur l’erreur. Les codes d’erreur possibles sont :

* ANY\_OF\_MISSING
* ARRAY\_LENGTH\_LONG
* ARRAY\_LENGTH\_SHORT
* CONFLICT
* CONFLICT\_EMAIL
* CONFLICT\_USERNAME
* CONNECTION\_NOT\_FOUND
* DUPLICATED\_USER
* ENUM\_MISMATCH
* FORMAT
* INVALID\_TYPE
* MAX\_LENGTH
* MAXIMUM
* MFA\_FACTORS\_FAILED
* MIN\_LENGTH
* MINIMUM
* NOT\_PASSED
* OBJECT\_REQUIRED
* PATTERN
* PROFILE\_SIZE\_EXCEEDED

<div id="best-practices-for-large-scale-migrations">
  ## Bonnes pratiques pour les migrations à grande échelle
</div>

Lorsque vous importez un grand nombre d’utilisateurs (ce qui nécessite 10 tâches ou plus), suivez ces recommandations pour assurer le succès de la migration :

<div id="file-size-and-chunking">
  ### Taille des fichiers et fractionnement
</div>

Répartissez les enregistrements d’utilisateurs en petits blocs de moins de 400 KB par fichier. Cela permet de traiter environ 1 000 utilisateurs par tâche avec moins de 10 champs de métadonnées par utilisateur, tout en restant largement sous la limite de taille de fichier de 500 KB.

<div id="job-scheduling-and-concurrency">
  ### Planification des tâches et concurrence
</div>

Comme Auth0 limite les importations d’utilisateurs à deux tâches simultanées par locataire, utilisez un framework de planification des tâches (comme [Bull](https://github.com/OptimalBits/bull) ou [Agenda](https://github.com/agenda/agenda)) pour :

* Planifier systématiquement les tâches d’importation
* Appliquer la limite de concurrence requise
* Suivre la progression de l’importation afin de reprendre là où vous vous êtes arrêté en cas d’interruption
* Conserver l’historique des tâches et leur état actuel

<div id="error-handling-strategy">
  ### Stratégie de gestion des erreurs
</div>

* N’interrompez pas le processus d’importation lorsqu’un seul utilisateur échoue. Importez tous les utilisateurs, puis traitez les problèmes par la suite.
* Implémentez une tâche de « finalisation » qui passe en revue toutes les tâches générées et regroupe les enregistrements ayant échoué dans un nouveau fichier.
* Corrigez les erreurs dans les enregistrements regroupés ayant échoué, puis importez-les dans une nouvelle tâche.
* Prévoyez une stratégie de reprise pour gérer les pertes de connexion réseau et les défaillances temporaires.

<div id="upsert-mode-considerations">
  ### Considérations relatives au mode upsert
</div>

Faites preuve de prudence lorsque vous activez le mode `upsert` :

* Les importations en mode upsert sont plus lentes que les importations standard.
* Le mode upsert ne prend pas en charge la fusion de `user_metadata` ou `app_metadata`. Les métadonnées existantes seront entièrement remplacées par les nouvelles valeurs.
* Utilisez le mode upsert uniquement si vous devez mettre à jour des utilisateurs existants et si vous comprenez bien ces limites.

<div id="data-retention">
  ### Conservation des données
</div>

N’oubliez pas que toutes les données liées aux tâches sont automatiquement supprimées après 24 heures. Conservez les résultats des tâches et les détails des erreurs au moyen de votre propre mécanisme de stockage afin d’en assurer le suivi et l’analyse à long terme.

<div id="learn-more">
  ## En savoir plus
</div>

* [Configurer la migration automatique depuis votre base de données](/fr-CA/docs/manage-users/user-migration/configure-automatic-migration-from-your-database)
* [Extension d’importation/exportation d’utilisateurs](/fr-CA/docs/manage-users/user-migration/user-import-export-extension)
* [Schéma de base de données et exemples d’importation groupée d’utilisateurs](/fr-CA/docs/manage-users/user-migration/bulk-user-import-database-schema-and-examples)
* [Scénarios de migration d’utilisateurs](/fr-CA/docs/manage-users/user-migration/user-migration-scenarios)
