# Estima el género a partir de un correo electrónico

> Consulta indicios de nombres en correos con GenderAPI.io V2. Prueba la herramienta, compara las opciones de IA y aprende a tratar resultados unknown y listas de correos.

Canonical HTML: https://www.genderapi.io/es/determine-gender-from-email

Last reviewed: 2026-09-28

## ¿Qué información puede aportar un correo electrónico?

Envía una dirección con sintaxis válida mediante type: email. GenderAPI.io busca indicios de un nombre en la parte anterior a @ y devuelve una estimación estructurada. No verifica la existencia del buzón, su titular ni la identidad de género de esa persona.

La búsqueda en el conjunto de datos extrae candidatos y puede probar fragmentos de longitud limitada. El modo de alias mantiene la búsqueda por palabras, pero no añade esos fragmentos. Si coinciden varios registros, se selecciona el candidato con el mayor recuento almacenado; no necesariamente el nombre que tenías en mente. Revisa data.name y data.match antes de incorporarlo a un contacto.

| Ejemplo de entrada | Cómo interpretarlo |
| --- | --- |
| `alice.smith@example.com` | La parte anterior a @ aporta posibles candidatos. Puede haber una coincidencia, pero la entrada no garantiza cuál será seleccionado. |
| `alice+news@example.com` | La búsqueda elimina el sufijo que empieza por + al generar candidatos. La IA recibe el valor enviado, aunque se le indica que ignore ese sufijo. |
| `support@example.com` | Una dirección de equipo no aporta evidencias fiables de un nombre personal. No atribuyas a todo un buzón compartido el género de una persona. |
| `prenses@example.com` | forceToGenderize permite intentar una estimación a partir del significado del alias si el conjunto de datos no resuelve la consulta. En ese modo no se exige un nombre real. |
| `not-an-email` | Una sintaxis inválida produce un error de validación, no un resultado unknown completado correctamente. |

## Consulta un correo electrónico desde tu aplicación

El ejemplo utiliza tu clave API existente en el encabezado Bearer y selecciona fallback explícitamente. Sustituye la dirección por un dato que tengas autorización para procesar. Envía country solo si dispones de contexto relevante; el dominio del correo no demuestra dónde vive una persona. Si desconoces el país, omite el campo.

Configura GENDERAPI_API_KEY y ejecuta el ejemplo en tu servidor. POST mantiene el correo fuera de la URL de la solicitud. El resultado real puede diferir de la respuesta ilustrativa de la herramienta.

Ejecuta estos ejemplos en tu servidor. Configura GENDERAPI_API_KEY en el entorno de proceso con tu clave API existente. Confirma que meta.access.mode es api_key: una clave no reconocida puede recurrir a la prueba IP.

Cada solicitud de predicción es una nueva operación facturable, incluidos los reintentos. Estos ejemplos no se reintentan automáticamente. Comprueba el estado de facturación antes de enviar otra solicitud.

Las respuestas HTTP 4xx y 5xx JSON conservan el cuerpo del error y devuelven un estado de salida distinto de cero. Comprueba code, action y meta.usage.billing_status antes de volver a intentarlo.

**cURL**

cURL 7.76+ en un shell POSIX. Ejecuta en tu terminal.

```bash
curl --silent --show-error --fail-with-body --max-time 30 \
  --request POST 'https://api.genderapi.io/api/v2/gender' \
  --header "Authorization: Bearer ${GENDERAPI_API_KEY:?Set GENDERAPI_API_KEY}" \
  --header 'Content-Type: application/json' \
  --data '{
  "type": "email",
  "value": "alice.smith@example.com",
  "country": "US",
  "options": {
    "ai_mode": "fallback"
  }
}'
```

**JavaScript / Node.js**

Node.js 22+; fetch integrado. Guarda como example.mjs y ejecuta node example.mjs.

```javascript
// Server-side Node.js. Save as example.mjs.
const apiKey = process.env.GENDERAPI_API_KEY;
if (!apiKey) throw new Error("Set GENDERAPI_API_KEY");
const body = {
  "type": "email",
  "value": "alice.smith@example.com",
  "country": "US",
  "options": {
    "ai_mode": "fallback"
  }
};

const response = await fetch("https://api.genderapi.io/api/v2/gender", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(body),
  signal: AbortSignal.timeout(30_000),
  redirect: "error",
});
const raw = await response.text();
if (!(response.headers.get("content-type") ?? "").includes("json")) {
  throw new Error(`HTTP ${response.status}: expected JSON; request ID ${response.headers.get("x-request-id")}`);
}
const result = JSON.parse(raw); // Also accepts application/problem+json.
if (!response.ok) {
  console.error(`HTTP ${response.status}`, result);
  process.exitCode = 1; // A retry is a new operation; inspect billing first.
} else {
  console.log(JSON.stringify(result, null, 2));
  // For batches, inspect every item: HTTP 200 may contain item errors.
}
```

**Python**

Python 3.10+; biblioteca estándar. Guarda como example.py y ejecuta python3 example.py.

```python
import json
import os
import sys
import urllib.error
import urllib.request

api_key = os.environ.get("GENDERAPI_API_KEY")
if not api_key:
    raise RuntimeError("Set GENDERAPI_API_KEY")
body = json.loads("{\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"country\":\"US\",\"options\":{\"ai_mode\":\"fallback\"}}")

class NoRedirect(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None

request = urllib.request.Request(
    "https://api.genderapi.io/api/v2/gender",
    method="POST",
    data=json.dumps(body).encode("utf-8"),
    headers={
        "Authorization": "Bearer " + api_key,
        "Content-Type": "application/json",
    },
)
opener = urllib.request.build_opener(NoRedirect())
try:
    response = opener.open(request, timeout=30)
except urllib.error.HTTPError as error:
    response = error  # Keep the Problem Details body on non-2xx responses.
with response:
    status = response.status
    raw = response.read().decode("utf-8")
    if "json" not in response.headers.get("Content-Type", ""):
        raise RuntimeError(f"HTTP {status}: expected a JSON response")
    result = json.loads(raw)
print(json.dumps(result, indent=2), file=sys.stderr if status >= 300 else sys.stdout)
if not 200 <= status < 300:
    sys.exit(1)  # Inspect code, action and billing before retrying.
# For batches, inspect every item even when HTTP status is 200.
```

**PHP**

PHP 8+ con la extensión cURL. Guarda como example.php y ejecuta php example.php.

```php
<?php
$apiKey = getenv('GENDERAPI_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set GENDERAPI_API_KEY');
}
$body = json_decode('{"type":"email","value":"alice.smith@example.com","country":"US","options":{"ai_mode":"fallback"}}', true, 512, JSON_THROW_ON_ERROR);

$ch = curl_init('https://api.genderapi.io/api/v2/gender');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($body, JSON_THROW_ON_ERROR),
]);
$raw = curl_exec($ch);
if ($raw === false) {
    throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE) ?: '';
curl_close($ch);
if (strpos($contentType, 'json') === false) {
    throw new RuntimeException("HTTP $status: expected a JSON response");
}
$result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
$output = json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . PHP_EOL;
if ($status < 200 || $status >= 300) {
    fwrite(STDERR, $output); // Preserve the Problem Details body.
    exit(1);
}
echo $output;
// For batches, inspect every item; HTTP 200 can contain item errors.
```

**Java**

Java 17+; cliente estándar HTTP. Guarda como GenderApiExample.java y ejecuta java GenderApiExample.java.

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

public class GenderApiExample {
    private static String requiredEnv(String name) {
        String value = System.getenv(name);
        if (value == null || value.isBlank()) throw new IllegalStateException("Set " + name);
        return value;
    }

    public static void main(String[] args) throws Exception {
        String apiKey = requiredEnv("GENDERAPI_API_KEY");
        String body = "{\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"country\":\"US\",\"options\":{\"ai_mode\":\"fallback\"}}";
        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .followRedirects(HttpClient.Redirect.NEVER)
            .build();
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.genderapi.io/api/v2/gender"))
            .timeout(Duration.ofSeconds(30))
            .header("Authorization", "Bearer " + apiKey)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
            .build();
        HttpResponse<String> response = client.send(request,
            HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
        if (!response.headers().firstValue("content-type").orElse("").contains("json")) {
            throw new IllegalStateException("HTTP " + response.statusCode() + ": expected JSON");
        }
        // JSON text; parse with your application's JSON library when integrating.
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            System.err.println(response.body()); // Includes Problem Details.
            System.exit(1);
        }
        System.out.println(response.body());
        // For batches, inspect each item's data or error, including on HTTP 200.
    }
}
```

**C# / .NET**

Aplicación de consola .NET 8+. Úsalo como Program.cs en un proyecto de consola, luego ejecuta dotnet run.

```csharp
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

string RequiredEnv(string name) =>
    !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(name))
        ? Environment.GetEnvironmentVariable(name)!
        : throw new InvalidOperationException($"Set {name}");

var apiKey = RequiredEnv("GENDERAPI_API_KEY");
using var handler = new HttpClientHandler { AllowAutoRedirect = false };
using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.genderapi.io/api/v2/gender");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
request.Content = new StringContent("{\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"country\":\"US\",\"options\":{\"ai_mode\":\"fallback\"}}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var raw = await response.Content.ReadAsStringAsync();
if (!(response.Content.Headers.ContentType?.MediaType?.Contains("json") ?? false))
    throw new InvalidOperationException($"HTTP {(int)response.StatusCode}: expected JSON");
using var result = JsonDocument.Parse(raw);
if (!response.IsSuccessStatusCode)
{
    Console.Error.WriteLine(result.RootElement); // Preserve Problem Details.
    Environment.ExitCode = 1;
}
else
{
    Console.WriteLine(result.RootElement);
    // For batches, inspect every item even on HTTP 200.
}
```

**Go**

Go 1.22+; biblioteca estándar. Guarda como main.go y ejecuta go run main.go.

```go
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "strings"
    "time"
)

func requiredEnv(name string) string {
    value := os.Getenv(name)
    if value == "" { panic("Set " + name) }
    return value
}

func run() error {
    apiKey := requiredEnv("GENDERAPI_API_KEY")
    body := "{\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"country\":\"US\",\"options\":{\"ai_mode\":\"fallback\"}}"
    request, err := http.NewRequest("POST", "https://api.genderapi.io/api/v2/gender", strings.NewReader(body))
    if err != nil { return err }
    request.Header.Set("Authorization", "Bearer " + apiKey)
    request.Header.Set("Content-Type", "application/json")
    client := &http.Client{
        Timeout: 30 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
    }
    response, err := client.Do(request)
    if err != nil { return err }
    defer response.Body.Close()
    raw, err := io.ReadAll(response.Body)
    if err != nil { return err }
    if !strings.Contains(response.Header.Get("Content-Type"), "json") || !json.Valid(raw) {
        return fmt.Errorf("HTTP %d: expected a JSON response", response.StatusCode)
    }
    if response.StatusCode < 200 || response.StatusCode >= 300 {
        return fmt.Errorf("HTTP %d: %s", response.StatusCode, raw)
    }
    fmt.Println(string(raw))
    // For batches, inspect every item even on HTTP 200.
    return nil
}

func main() {
    if err := run(); err != nil {
        fmt.Fprintln(os.Stderr, err) // Keep Problem Details for error handling.
        os.Exit(1)
    }
}
```

- [Referencia de correo electrónico en V2](https://www.genderapi.io/es/docs/v2/gender-from-email)

## Interpreta el resultado junto con sus evidencias

Una asociación inferida no equivale al género declarado por la persona. Conserva por separado el dato original, las evidencias de la respuesta y la información facilitada por la persona. unknown es un resultado válido; no lo conviertas en una categoría inventada.

| Campo | Cómo utilizarlo |
| --- | --- |
| `data.gender / data.result_status` | Utiliza male o female solo cuando el resultado sea identified. Conserva el valor JSON null cuando sea unknown. |
| `data.name / data.match` | Revisa el nombre devuelto y el candidato seleccionado. Una coincidencia parcial no demuestra que el dato pertenezca a una persona con ese nombre. |
| `data.confidence / data.confidence_kind` | La confianza se expresa entre 0 y 1, o como null. observed_frequency procede de recuentos almacenados; model_reported es una puntuación de IA. Evalúa los umbrales por separado para cada tipo. |
| `data.source / data.sample_count` | Distingue dataset, ai y none. Los resultados de IA no tienen un recuento de muestras almacenadas. El tamaño de la muestra no es una medida de exactitud. |
| `meta.access.mode` | Comprueba api_key en una integración de cuenta. Si falta la clave o no se reconoce, puede utilizarse la prueba compartida por IP. |
| `meta.usage` | Revisa charged_credits y billing_status. Un resultado unknown completado correctamente consume créditos. No recibir la respuesta no demuestra que la consulta haya sido gratuita. |

- [Campos de respuesta y resultados desconocidos](https://www.genderapi.io/es/docs/v2/responses)
- [Exactitud y confianza](https://www.genderapi.io/es/accuracy-methodology)
- [Fuentes de datos y perfil del conjunto de datos](https://www.genderapi.io/es/data-provenance)

## Elige cuándo utilizar la IA

forceToGenderize es opcional para nombres, correos electrónicos y nombres de usuario. Si lo activas, omite ai_mode o utiliza fallback; combinarlo con off o always devuelve un error 422. Basta con un saldo inicial positivo para iniciar la consulta, aunque el cargo final deje el saldo por debajo de cero.

El análisis de alias puede devolver un género con name: null. También puede devolver unknown. Ni el respaldo estándar de IA ni el análisis de alias garantizan una respuesta correcta o distinta de null.

| Opción de la solicitud | Comportamiento | Créditos por consulta completada |
| --- | --- | --- |
| options.ai_mode: off | Consulta únicamente el conjunto de datos. | 1 crédito, incluido unknown |
| options.ai_mode: fallback | Consulta primero el conjunto de datos y recurre a la IA estándar si no obtiene un género. Es el modo predeterminado de las consultas individuales. | 1 crédito en total, incluido el respaldo de IA |
| options.ai_mode: always | Consulta directamente a la IA. | 2 créditos |
| forceToGenderize: true | Consulta primero el conjunto de datos; si no encuentra un género, permite interpretar el significado de un alias personal, aunque no contenga un nombre real. | 1 crédito si el conjunto de datos resuelve la consulta; 2 en total si se utiliza IA |

- [Opciones de IA y análisis de alias](https://www.genderapi.io/es/docs/v2/ai-options)
- [Créditos y uso](https://www.genderapi.io/es/docs/v2/credits-and-usage)

## Procesa listas de correos electrónicos por lotes

Utiliza POST /api/v2/gender/batch con un array items de entradas type: email. El límite es de 50 elementos con una clave de cuenta y de 10 en la prueba por IP. Asigna un id único a cada elemento para vincular el resultado con su fila original. La respuesta también conserva el orden de entrada e incluye index.

El modo predeterminado de los elementos de un lote utiliza solo el conjunto de datos. Añade options.ai_mode: fallback a cada elemento que necesite respaldo estándar de IA. Dos elementos fallback completados cuestan 2 créditos en total, incluidos los resultados unknown; una solicitud HTTP no equivale a un único crédito de predicción.

Revisa todos los elementos aunque el lote devuelva HTTP 200. Guarda los resultados identificados y desconocidos, y comprueba los errores y el cargo confirmado antes de reintentar los fallidos. Tras un tiempo de espera agotado, comprueba la facturación antes de reenviar el lote completo.

- [Ejemplos, límites y errores parciales en lotes](https://www.genderapi.io/es/docs/v2/batch)

## Comprende cómo se procesa el dato que envías

La herramienta envía el valor a GenderAPI.io solo cuando pulsas Analizar. Si interviene la IA, el servicio de inferencia configurado recibe type, value y el contexto de país enviado. Para consultar únicamente el conjunto de datos, utiliza options.ai_mode: off sin forceToGenderize en tu integración.

La Política de Privacidad, el acuerdo de tratamiento y la lista de subencargados describen las condiciones publicadas. El resultado es una asociación inferida; da prioridad a la información que facilite la persona. No lo utilices como fundamento de decisiones con consecuencias importantes para alguien.

- [Política de Privacidad](https://www.genderapi.io/es/privacy-policy)
- [Acuerdo de tratamiento de datos](https://www.genderapi.io/es/data-processing-agreement)
- [Subencargados del tratamiento](https://www.genderapi.io/es/subprocessors)

## ¿Puede la API extraer un nombre de pila de un correo?

Puede devolver un candidato si la parte anterior a @ contiene indicios útiles. Puede haber coincidencias por palabras o fragmentos, por lo que debes revisar data.match. El resultado no demuestra el nombre del titular del buzón.

## ¿Devuelve un género para info@ o support@?

Las direcciones compartidas de equipo normalmente no aportan evidencias de un nombre personal. unknown es válido. La IA o el modo de alias no verifican a las personas que utilizan un buzón compartido.

## ¿Un resultado unknown consume créditos?

Sí. Una consulta estándar de correo completada cuesta 1 crédito, incluidos fallback y unknown. Con forceToGenderize se cobra 1 crédito si el conjunto de datos resuelve la consulta, o 2 en total si se utiliza IA. La facturación de los errores se indica por separado en meta.usage.

## ¿Se elimina el dominio del correo antes de enviarlo a la IA?

No se garantiza esa eliminación. Los candidatos del conjunto de datos proceden de la parte anterior a @. La IA recibe el valor enviado y se le indica que ignore el dominio y el sufijo que empieza por +. Utiliza el modo de conjunto de datos si tu proceso lo requiere.
