> ## 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.

> Aprenda a realizar importaciones masivas de usuarios mediante la Management API.

# Importaciones masivas de usuarios

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) + "*****ENMASCARADO*****";
          }
          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>;
};

Puede importar datos de usuario en bloque en Auth0 mediante el endpoint [Create Import Users Job](https://auth0.com/docs/api/management/v2#!/Jobs/post_users_imports). Las importaciones en bloque son útiles para migrar usuarios desde una base de datos o un servicio existentes a Auth0.

<Warning>
  Si intenta usar más de un método de migración (por ejemplo, una migración automática y después una importación masiva de usuarios), puede encontrarse con el error `DUPLICATED_USER`. Este error indica que el usuario existe en el almacén de usuarios interno de Auth0, pero no en su inquilino. Para corregir este error, elimine el usuario con el endpoint [Delete a Connection User](https://auth0.com/docs/api/management/v2#!/Connections/delete_users_by_email) de Auth0 Management API y, a continuación, vuelva a intentar la importación.
</Warning>

<div id="prerequisites">
  ## Requisitos previos
</div>

Antes de iniciar el trabajo de importación de usuarios:

* Configure una conexión de base de datos en la que importar los usuarios y habilítela para al menos una aplicación.
* Si va a importar contraseñas, asegúrese de que tengan hash con uno de los algoritmos compatibles. Los usuarios cuyas contraseñas tengan hash con algoritmos no compatibles deberán restablecer su contraseña cuando inicien sesión por primera vez después de la importación masiva.
* Si va a importar inscripciones de <Tooltip tip="Autenticación multifactor (MFA): proceso de autenticación de usuarios que utiliza un factor además del nombre de usuario y la contraseña, como un código por SMS." cta="Ver glosario" href="/es/docs/glossary?term=MFA">MFA</Tooltip>, asegúrese de que sean de un tipo compatible: `email`, `phone` o `totp`.
* [Obtenga un token de la Management API](/es/docs/secure/tokens/access-tokens/management-api-access-tokens) para las solicitudes al endpoint de trabajos.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Si está usando un archivo de exportación de un inquilino de Auth0, debe convertir el archivo exportado de `ndjson` a [JSON](/es/docs/manage-users/user-migration/bulk-user-exports#json-compatible-format). Para conservar los mismos IDs de usuario, debe eliminar el prefijo `auth0|` de todos los IDs de usuario importados.

  El proceso de importación agrega automáticamente el prefijo `auth0|` a los IDs de usuario importados. Si no elimina el prefijo `auth0|` antes de importar, los IDs de usuario se devolverán como `auth0|auth0|...`
</Callout>

<div id="create-users-json-file">
  ## Crear un archivo JSON de usuarios
</div>

Cree un archivo JSON con los datos de usuario que desea importar en Auth0. La forma de exportar los datos de usuario a un archivo JSON variará según la base de datos de usuarios que ya tenga. El endpoint de <Tooltip tip="Management API: Un producto que permite a los clientes realizar tareas administrativas." cta="Ver glosario" href="/es/docs/glossary?term=Management+API">Management API</Tooltip> espera partes del archivo JSON. Por lo tanto, en lugar de usar `fs.readFileSync`, requiere `fs.createReadStream`. El endpoint espera un flujo de lectura canalizado en lugar del archivo JSON completo.

Para obtener más información sobre el esquema del archivo JSON y ver ejemplos, lea [Esquema de la base de datos y ejemplos de importación masiva](/es/docs/manage-users/user-migration/bulk-user-import-database-schema-and-examples).

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  El límite de tamaño de archivo para una importación masiva es de 500 KB. Deberá iniciar varias importaciones si sus datos superan este tamaño.
</Callout>

<div id="request-bulk-user-import">
  ## Solicitar una importación masiva de usuarios
</div>

Para iniciar un trabajo de importación masiva de usuarios, envía una solicitud `POST` al endpoint [Create Import Users Job](https://auth0.com/docs/api/management/v2#!/Jobs/post_users_imports). Asegúrate de reemplazar los valores de marcador de posición `MGMT_API_ACCESS_TOKEN`, `USERS_IMPORT_FILE.json`, `CONNECTION_ID` y `EXTERNAL_ID` por tu <Tooltip tip="Token de acceso: credencial de autorización, en forma de una cadena opaca o un JWT, utilizada para acceder a una API." cta="Ver glosario" href="/es/docs/glossary?term=Access+Token">Token de acceso</Tooltip> de la Management API, el archivo JSON de usuarios, el [ID de la conexión](/es/docs/authenticate/identity-providers/locate-the-connection-id) de la base de datos y el ID externo, respectivamente.

<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}")

  # Leer el archivo de importación de usuarios
  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>

| Parámetro               | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `users`                 | Archivo en formato JSON que contiene los usuarios que se importarán.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `connection_id`         | ID de la conexión en la que se insertarán los usuarios. Puede recuperar el ID mediante el endpoint [GET /api/v2/connections](https://auth0.com/docs/api/management/v2#!/Connections/get_connections).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `upsert`                | Valor booleano; `false` de forma predeterminada. Cuando se establece en `false`, se producirá un error con los usuarios existentes que coincidan por dirección de correo electrónico, ID de usuario, teléfono o username. Cuando se establece en `true`, los usuarios existentes que coincidan por dirección de correo electrónico se actualizarán, pero solo con atributos que admitan `upsert`. Para obtener una lista de los campos del perfil de usuario que se pueden actualizar mediante `upsert` durante la importación, consulte [User Profile Structure: User profile attributes](/es/docs/manage-users/user-accounts/user-profiles/user-profile-structure#user-profile-attributes). Nota: Incluir una entrada de usuario duplicada en el archivo de importación provocará un error. En este caso, Auth0 no realizará una inserción seguida de una actualización. |
| `external_id`           | Cadena opcional definida por el usuario que puede utilizarse para correlacionar varios trabajos. Se devuelve como parte de la respuesta de estado del trabajo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `send_completion_email` | Valor booleano; `true` de forma predeterminada. Cuando se establece en `true`, se envía un correo electrónico de finalización a todos los propietarios del inquilino cuando finaliza el trabajo de importación. Si *no* desea que se envíen correos electrónicos, debe establecer explícitamente este parámetro en `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

Si la solicitud se realiza correctamente, recibirá una respuesta similar a la siguiente:

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

La entidad devuelta representa el trabajo de importación.

Cuando finalice el trabajo de importación de usuarios, si `send_completion_email` se estableció en `true`, los administradores del inquilino recibirán un correo electrónico para notificarles si el trabajo falló o se completó correctamente. Un correo electrónico sobre un trabajo fallido podría notificar a los administradores que no se pudo procesar el archivo JSON de usuarios durante la importación.

<div id="concurrent-import-jobs">
  ### Trabajos de importación simultáneos
</div>

El endpoint [Create Import Users Job](https://auth0.com/docs/api/management/v2#!/Jobs/post_users_imports) tiene un límite de dos trabajos de importación simultáneos. Si se solicitan trabajos adicionales cuando ya hay dos pendientes, se devuelve una respuesta `429 Too Many Requests`:

```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">
  ## Consultar el estado del trabajo
</div>

Para consultar el estado de un trabajo, realiza una solicitud `GET` al [endpoint Get a Job](https://auth0.com/docs/api/management/v2#!/Jobs/get_jobs_by_id). Asegúrate de reemplazar los valores de marcador de posición `MGMT_API_ACCESS_TOKEN` y `JOB_ID` por tu token de acceso de la Management API y el id del trabajo de importación de usuarios.

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

Según el estado del trabajo de importación de usuarios, recibirás una respuesta similar a una de las siguientes:

**Pendiente**

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

**Completado**

Si un trabajo se ha completado, la respuesta de estado del trabajo incluirá los totales de registros procesados correctamente, fallidos, insertados y actualizados.

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

**Fallido**

Si hay un error en el trabajo, se devolverá como fallido. Sin embargo, tenga en cuenta que la información de usuario no válida, como un correo electrónico no válido, no hará que falle todo el trabajo.

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

Para conocer los detalles de los registros fallidos, consulte **Retrieve failed entries** más abajo.

<div id="job-timeouts">
  ## Tiempos de espera de los trabajos
</div>

Todos los trabajos de importación de usuarios vencen después de **dos (2) horas**. Si su trabajo no se completa dentro de este plazo, se marca como fallido.

Además, todos los datos relacionados con su trabajo se eliminan automáticamente después de 24 horas y ya no se podrá acceder a ellos. Por lo tanto, **recomendamos encarecidamente que almacene los resultados del trabajo mediante el mecanismo de almacenamiento que prefiera**.

<div id="retrieve-failed-entries">
  ## Recuperar entradas fallidas
</div>

<Warning>
  Todos los datos relacionados con el trabajo se eliminan automáticamente después de 24 horas y ya no se puede acceder a ellos. Por este motivo, le recomendamos encarecidamente que almacene los resultados del trabajo con el mecanismo de almacenamiento que prefiera.
</Warning>

Si hubo errores en el trabajo de importación de usuarios, puede obtener los detalles del error haciendo una solicitud `GET` al endpoint [Get Job Error Details](https://auth0.com/docs/api/management/v2#!/Jobs/get_errors). Asegúrese de reemplazar los valores de marcador de posición `MGMT_API_ACCESS_TOKEN` y `JOB_ID` por su token de acceso de la Management API y el ID del trabajo de importación de usuarios.

<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 solicitud se realiza correctamente, recibirá una respuesta similar a la siguiente. Los campos sensibles, como `hash.value`, se ocultarán en la respuesta.

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

Cada objeto de error incluirá un código de error y un mensaje que lo explica con más detalle. Los posibles códigos de error son:

* 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">
  ## Prácticas recomendadas para migraciones a gran escala
</div>

Al importar un gran volumen de usuarios (lo que requiere 10 o más trabajos), siga estas recomendaciones para garantizar una migración exitosa:

<div id="file-size-and-chunking">
  ### Tamaño de archivo y fragmentación
</div>

Divida los registros de usuario en fragmentos pequeños de menos de 400 KB por archivo. Esto permite procesar aproximadamente 1.000 usuarios por trabajo con menos de 10 campos de metadatos por usuario, sin superar con holgura el límite de tamaño de archivo de 500 KB.

<div id="job-scheduling-and-concurrency">
  ### Programación y concurrencia de trabajos
</div>

Dado que Auth0 limita las importaciones de usuarios a dos trabajos simultáneos por inquilino, use un framework de programación de trabajos (como [Bull](https://github.com/OptimalBits/bull) o [Agenda](https://github.com/agenda/agenda)) para:

* Programar los trabajos de importación de forma sistemática
* Aplicar el límite de simultaneidad requerido
* Hacer un seguimiento del progreso de la importación para reanudarla donde se interrumpió
* Mantener el historial de trabajos y sus estados actuales

<div id="error-handling-strategy">
  ### Estrategia de gestión de errores
</div>

* No interrumpa el proceso de importación por errores de un solo usuario. Importe todos los usuarios y resuelva los problemas después.
* Implemente un trabajo de "finalización" que revise todos los trabajos generados y recopile los registros fallidos en un archivo nuevo.
* Corrija cualquier error en los registros fallidos recopilados e impórtelos como un trabajo nuevo.
* Incluya una estrategia de reintento para gestionar caídas de la conexión de red y errores temporales.

<div id="upsert-mode-considerations">
  ### Consideraciones sobre el modo `upsert`
</div>

Ten cuidado al habilitar el modo `upsert`:

* Las importaciones con `upsert` son más lentas que las importaciones estándar.
* El modo `upsert` no admite la combinación de `user_metadata` ni `app_metadata`. Los metadatos existentes se sobrescribirán por completo con los nuevos valores.
* Usa el modo `upsert` solo cuando necesites actualizar usuarios existentes y entiendas estas limitaciones.

<div id="data-retention">
  ### Retención de datos
</div>

Recuerde que todos los datos relacionados con los trabajos se eliminan automáticamente transcurridas 24 horas. Guarde los resultados de los trabajos y los detalles de los errores en su propio mecanismo de almacenamiento para su seguimiento y análisis a largo plazo.

<div id="learn-more">
  ## Más información
</div>

* [Configurar la migración automática desde tu base de datos](/es/docs/manage-users/user-migration/configure-automatic-migration-from-your-database)
* [Extensión de importación/exportación de usuarios](/es/docs/manage-users/user-migration/user-import-export-extension)
* [Esquema de base de datos y ejemplos de importación masiva de usuarios](/es/docs/manage-users/user-migration/bulk-user-import-database-schema-and-examples)
* [Escenarios de migración de usuario](/es/docs/manage-users/user-migration/user-migration-scenarios)
