Continuar → Descripción general

Referencia de REST API

Unos pocos endpoints, una estructura de respuesta. Todo lo siguiente está activo en tu cuenta.

https://namegender.com/api/v1/gender Registrarse gratis
llms-full.txt

Markdown para asistentes de código como Claude Code, Cursor y Copilot. Pégalo en el chat o dale el enlace al asistente.

Inicio rápido

Crea una clave en tu panel de control y envía tu primera solicitud. No necesitas SDK.

curl "https://namegender.com/api/v1/gender?name=Ay%C5%9Fe&country=TR" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php

$query = http_build_query(['name' => 'Ayşe', 'country' => 'TR']);

$ch = curl_init('https://namegender.com/api/v1/gender?' . $query);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer YOUR_API_KEY'],
]);

$result = json_decode(curl_exec($ch), true);

echo $result['gender'];       // female
echo $result['probability'];  // 100
const params = new URLSearchParams({ name: 'Ayşe', country: 'TR' });

const response = await fetch(`https://namegender.com/api/v1/gender?${params}`, {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
});

const result = await response.json();

console.log(result.gender);       // "female"
console.log(result.probability);  // 100
import requests

response = requests.get(
    "https://namegender.com/api/v1/gender",
    params={"name": "Ayşe", "country": "TR"},
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)

result = response.json()
print(result["gender"])       # female
print(result["probability"])  # 100
require "net/http"
require "json"

uri = URI("https://namegender.com/api/v1/gender")
uri.query = URI.encode_www_form(name: "Ayşe", country: "TR")

request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end

puts JSON.parse(response.body)["gender"]   # female
req, _ := http.NewRequest("GET", "https://namegender.com/api/v1/gender?name=Ay%C5%9Fe&country=TR", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")

resp, err := http.DefaultClient.Do(req)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

var result struct {
    Gender      string `json:"gender"`
    Probability int    `json:"probability"`
}
json.NewDecoder(resp.Body).Decode(&result)

fmt.Println(result.Gender)   // female

Cada endpoint devuelve la misma estructura, así que puedes cambiar entradas sin modificar tu código de análisis.

Autenticación

Cada solicitud lleva tu clave de API en un encabezado. Usa Authorization: Bearer por defecto, o X-Api-Key si tu cliente HTTP reserva el encabezado Authorization para otra cosa. Una clave colocada en la URL se rechaza: las URL acaban copiadas en registros de proxy, herramientas de analítica y el historial del navegador.

Encabezado Authorization (recomendado)
Authorization: Bearer ng_live_xxxxxxxxxxxx

No se pudo copiar. Selecciona y copia el texto.

Encabezado X-Api-Key
X-Api-Key: ng_live_xxxxxxxxxxxx

No se pudo copiar. Selecciona y copia el texto.

Nunca expongas tu clave en código del lado del cliente. Las llamadas desde un navegador o aplicación móvil deben pasar a través de tu propio backend.

Puedes restringir una clave a direcciones IP específicas desde el panel de control.

Bibliotecas cliente

Envolturas delgadas sobre la API REST. Envían tu clave, construyen cada petición y convierten las respuestas de error en excepciones.

JavaScript Código fuente
npm install namegender

No se pudo copiar. Selecciona y copia el texto.

Command line Código fuente
npm install -g namegender

No se pudo copiar. Selecciona y copia el texto.

composer require namegender/namegender

No se pudo copiar. Selecciona y copia el texto.

pip install namegender-client

No se pudo copiar. Selecciona y copia el texto.

gem install namegender

No se pudo copiar. Selecciona y copia el texto.

<repository>
  <id>jitpack.io</id>
  <url>https://jitpack.io</url>
</repository>

<dependency>
  <groupId>com.github.anpekesen</groupId>
  <artifactId>namegender-java</artifactId>
  <version>v0.9.0</version>
</dependency>

No se pudo copiar. Selecciona y copia el texto.

dotnet add package NameGender --version 0.6.0

No se pudo copiar. Selecciona y copia el texto.

go get github.com/anpekesen/namegender-go@v0.7.0

No se pudo copiar. Selecciona y copia el texto.

remotes::install_github('anpekesen/namegender-r', ref = 'v0.7.0')

No se pudo copiar. Selecciona y copia el texto.

PowerShell Código fuente
Install-Module NameGender

No se pudo copiar. Selecciona y copia el texto.

cargo add namegender

No se pudo copiar. Selecciona y copia el texto.

No las necesitas. La API son unos pocos endpoints de JSON simple; una biblioteca te ahorra una tarde, no un proyecto. Si tu lenguaje no está listado, la referencia REST tiene ejemplos para copiar y pegar.

Ver todo

Asistentes de IA (MCP)

Usa NameGender desde Claude, Cursor y cualquier otro cliente compatible con el Model Context Protocol. Pregúntale al asistente por una lista de nombres y llamará a la API por ti, con la evidencia junto a cada respuesta.

Claude Code
claude mcp add namegender -e NAMEGENDER_API_KEY=ng_live_... -- npx -y namegender-mcp

No se pudo copiar. Selecciona y copia el texto.

Claude Desktop, Cursor y otros clientes
{
    "mcpServers": {
        "namegender": {
            "command": "npx",
            "args": [
                "-y",
                "namegender-mcp"
            ],
            "env": {
                "NAMEGENDER_API_KEY": "ng_live_..."
            }
        }
    }
}

No se pudo copiar. Selecciona y copia el texto.

Añade esto al archivo de configuración MCP del cliente y reinícialo.

Herramientas

gender_from_name
Género a partir de un nombre de pila o un nombre completo.
gender_from_email
Lee el nombre de una dirección de email; las direcciones genéricas como info@ devuelven desconocido.
gender_from_username
Lee el nombre de un nombre de usuario o handle.
gender_bulk
Hasta 100 valores en una sola solicitud, con un resumen de la tasa de coincidencia.
name_countries
Países donde un nombre está registrado. No es una afirmación sobre su origen.
salutation
Saludo inicial de una carta en el idioma de la carta; la forma neutra cuando el género no es seguro.
name_check
Si un nombre escrito en un formulario parece real, con los motivos. Nunca califica un nombre de falso.
age_from_name
Edad mediana y rangos de edad de las personas con un nombre de pila en Estados Unidos, Francia y Noruega.
account_status
Créditos restantes y la asignación gratuita de hoy.

Cada consulta usa créditos de la cuenta propietaria de la clave, exactamente igual que una llamada directa a la API. Publicado en el registro oficial de MCP como io.github.anpekesen/namegender. Paquete npm · Código fuente

GET · POST https://namegender.com/api/v1/gender
Markdown

Género a partir del nombre

Acepta un nombre de pila o un nombre completo. Los títulos, nombres intermedios y apellidos se eliminan antes de la búsqueda, así que "Dr. Ayşe Yılmaz" y "Ayşe" dan la misma respuesta.

Parámetro Tipo Descripción
name
requerido
string El nombre a clasificar. Nombre de pila o nombre completo.
country
opcional
string Código de país ISO 3166-1 alfa-2. Mejora la precisión para nombres cuyo género varía según la región, como Andrea (masculino en Italia, femenino en Alemania).
locale
opcional
string Una etiqueta de idioma como de-DE o en_US, por ejemplo el idioma del navegador. Su región pasa a ser el país cuando no se envía country. Una etiqueta sin región (en, de) no fija ningún país.
ip
opcional
string La dirección IP del usuario final. Se usa su país cuando no se envía country ni un locale con región. No se guarda. IP geolocation by DB-IP (db-ip.com).
ai_fallback
opcional
boolean Si el nombre no tiene entrada en nuestros datos, pide una estimación a un modelo de lenguaje en lugar de devolver null. Solo funciona cuando las búsquedas con IA están activadas en tu configuración, y cuesta un crédito adicional.
best_guess
opcional
boolean Devuelve el género predominante incluso cuando la evidencia no alcanza el umbral de confianza. Desactivado por defecto: una respuesta cercana al 50/50 que parece definitiva hace más daño que un null.
curl "https://namegender.com/api/v1/gender?name=Jordan" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "credits_charged": 1,
  "credits_remaining": 49999,
  "request_id": "req_4b7e0c2d9a1f6358",
  "query": "Jordan",
  "name": "Jordan",
  "first_name": "Jordan",
  "middle_name": null,
  "last_name": null,
  "name_type": "personal",
  "gender": "male",
  "country": null,
  "sample_size": 62240,
  "probability": 84,
  "took_ms": 1,
  "confidence": "high",
  "source": "db",
  "matched_as": null
}
GET · POST https://namegender.com/api/v1/gender/email
Markdown

Género a partir del correo electrónico

Extrae la persona de la parte local de la dirección y luego la clasifica. "ayse.yilmaz84@example.com" se resuelve a Ayşe.

Parámetro Tipo Descripción
email
requerido
string La dirección de correo electrónico. Solo se usa la parte anterior a @.
country
opcional
string Código de país ISO 3166-1 alfa-2. Mejora la precisión para nombres cuyo género varía según la región, como Andrea (masculino en Italia, femenino en Alemania).
locale
opcional
string Una etiqueta de idioma como de-DE o en_US, por ejemplo el idioma del navegador. Su región pasa a ser el país cuando no se envía country. Una etiqueta sin región (en, de) no fija ningún país.
ip
opcional
string La dirección IP del usuario final. Se usa su país cuando no se envía country ni un locale con región. No se guarda. IP geolocation by DB-IP (db-ip.com).
ai_fallback
opcional
boolean Si el nombre no tiene entrada en nuestros datos, pide una estimación a un modelo de lenguaje en lugar de devolver null. Solo funciona cuando las búsquedas con IA están activadas en tu configuración, y cuesta un crédito adicional.
best_guess
opcional
boolean Devuelve el género predominante incluso cuando la evidencia no alcanza el umbral de confianza. Desactivado por defecto: una respuesta cercana al 50/50 que parece definitiva hace más daño que un null.

best_guess actúa sobre el nombre leído de la dirección, no sobre la dirección en sí. Si no se puede leer ningún nombre, no hay nada que forzar y gender sigue siendo null. Ten en cuenta que aquí una respuesta forzada se apoya en una extracción que también puede ser errónea.

curl "https://namegender.com/api/v1/gender/email?email=ayse.yilmaz84%40example.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "credits_charged": 1,
  "credits_remaining": 49998,
  "query": "ayse.yilmaz84@example.com",
  "name": "Ayse",
  "gender": "female",
  "sample_size": 655,
  "probability": 100,
  "took_ms": 1,
  "confidence": "high",
  "source": "db"
}
GET · POST https://namegender.com/api/v1/gender/username
Markdown

Género a partir del nombre de usuario

Maneja camelCase, snake_case, dígitos finales y signos @ iniciales. "AyseYilmaz84" se resuelve a Ayşe.

Parámetro Tipo Descripción
username
requerido
string El nombre de usuario o identificador. Un @ inicial se ignora.
country
opcional
string Código de país ISO 3166-1 alfa-2. Mejora la precisión para nombres cuyo género varía según la región, como Andrea (masculino en Italia, femenino en Alemania).
locale
opcional
string Una etiqueta de idioma como de-DE o en_US, por ejemplo el idioma del navegador. Su región pasa a ser el país cuando no se envía country. Una etiqueta sin región (en, de) no fija ningún país.
ip
opcional
string La dirección IP del usuario final. Se usa su país cuando no se envía country ni un locale con región. No se guarda. IP geolocation by DB-IP (db-ip.com).
ai_fallback
opcional
boolean Si el nombre no tiene entrada en nuestros datos, pide una estimación a un modelo de lenguaje en lugar de devolver null. Solo funciona cuando las búsquedas con IA están activadas en tu configuración, y cuesta un crédito adicional.
best_guess
opcional
boolean Devuelve el género predominante incluso cuando la evidencia no alcanza el umbral de confianza. Desactivado por defecto: una respuesta cercana al 50/50 que parece definitiva hace más daño que un null.
curl "https://namegender.com/api/v1/gender/username?username=AyseYilmaz84" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "credits_charged": 1,
  "credits_remaining": 49997,
  "query": "AyseYilmaz84",
  "name": "Ayse",
  "gender": "female",
  "sample_size": 655,
  "probability": 100,
  "took_ms": 1,
  "confidence": "high",
  "source": "db"
}
POST https://namegender.com/api/v1/gender/bulk
Markdown

Solicitud en lote

Envía hasta 100 nombres en una solicitud. Usa esto en lugar de hacer un bucle: una llamada en lote para 100 nombres es un único viaje de ida y vuelta y una búsqueda deduplicada única.

Parámetro Tipo Descripción
names
requerido
string[] Array de nombres. Máximo 100 elementos.
type
opcional
string Qué son los elementos: nombre, correo electrónico o nombre de usuario. Por defecto, nombre.
country
opcional
string Se aplica a cada elemento de la solicitud.
locale
opcional
string Etiqueta de idioma cuya región pasa a ser el país de cada elemento cuando no se envía country.
ip
opcional
string Dirección IP del usuario final cuyo país se usa para cada elemento cuando no se envía country ni un locale con región. No se guarda. IP geolocation by DB-IP (db-ip.com).
curl -X POST "https://namegender.com/api/v1/gender/bulk" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"names": ["Ayşe", "Mehmet", "Priya", "Wei"]}'
<?php

$ch = curl_init('https://namegender.com/api/v1/gender/bulk');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'names' => ['Ayşe', 'Mehmet', 'Priya', 'Wei'],
    ]),
]);

$data = json_decode(curl_exec($ch), true);

foreach ($data['results'] as $row) {
    printf("%-8s %-7s %d%%\n", $row['query'], $row['gender'] ?? '?', $row['probability']);
}
const response = await fetch('https://namegender.com/api/v1/gender/bulk', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ names: ['Ayşe', 'Mehmet', 'Priya', 'Wei'] }),
});

const { results, summary } = await response.json();

console.log(summary.match_rate);   // 100
results.forEach(r => console.log(r.query, r.gender, r.probability));
import requests

response = requests.post(
    "https://namegender.com/api/v1/gender/bulk",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"names": ["Ayşe", "Mehmet", "Priya", "Wei"]},
)

data = response.json()
print(data["summary"]["match_rate"])   # 100

for row in data["results"]:
    print(row["query"], row["gender"], row["probability"])
{
  "credits_charged": 4,
  "credits_remaining": 49995,
  "request_id": "req_71d0a9e3c5b24f86",
  "took_ms": 2,
  "summary": {
    "total": 4,
    "identified": 4,
    "unknown": 0,
    "match_rate": 100
  },
  "results": [
    { "query": "Ayşe",   "gender": "female", "probability": 100, "sample_size":  655, "confidence": "high", "source": "db" },
    { "query": "Mehmet", "gender": "male",   "probability": 100, "sample_size": 1130, "confidence": "high", "source": "db" },
    { "query": "Priya",  "gender": "female", "probability": 100, "sample_size": 2993, "confidence": "high", "source": "db" },
    { "query": "Wei",    "gender": "male",   "probability":  86, "sample_size":  136, "confidence": "high", "source": "db" }
  ]
}

Los resultados vuelven en el mismo orden en que los enviaste. Los créditos se cobran por nombre, y toda la solicitud se rechaza antes de cualquier trabajo si tu saldo es insuficiente, así que nunca obtendrás un lote procesado parcialmente.

El bloque de resumen te muestra la tasa de coincidencia de un vistazo, para que puedas decidir si la entrada necesita limpieza antes de procesar el resto.

POST GET DELETE https://namegender.com/api/v1/batches
Markdown

Trabajos de archivo

Sube un archivo CSV o XLSX de hasta 100 MB y 1.000.000 filas y recíbelo con columnas de género añadidas a cada fila. Un crédito por fila, cobrado solo si el trabajo se completa.

  1. 1. POST /batches Envía el archivo y name_column. El trabajo se pone en cola de inmediato.
  2. 2. GET /batches/{id} Consulta el trabajo hasta que status sea completed o failed. poll_after_seconds indica cuánto esperar entre consultas.
  3. 3. GET /batches/{id}/result Descarga el resultado. Vuelve en el formato que subiste.
Parámetro Tipo Descripción
file
requerido
file CSV, TSV o XLSX con una fila de encabezado.
name_column
requerido
string Encabezado de la columna con los nombres, tal como aparece en el archivo. Obligatorio salvo con start=false.
country_column
opcional
string Encabezado de una columna con un código de país por fila.
country
opcional
string País predeterminado para las filas que no tienen uno.
ai_fallback
opcional
boolean Consultar un modelo de IA para nombres que no están en el conjunto de datos. Requiere el consentimiento de IA en Ajustes.
best_guess
opcional
boolean Devolver el género más probable aunque la evidencia sea débil.
delete_after_download
opcional
boolean El resultado se puede descargar una vez y después se elimina.
start
opcional
boolean false: solo subir e inspeccionar. Por defecto, true.
# 1. Upload and start
curl -X POST "https://namegender.com/api/v1/batches" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: 6f1c2e0a-customers-2026-09" \
  -F "file=@customers.csv" \
  -F "name_column=first_name" \
  -F "country_column=country"

# 2. Poll until status is completed or failed
curl "https://namegender.com/api/v1/batches/B-7K2M9QX4TA" \
  -H "Authorization: Bearer YOUR_API_KEY"

# 3. Download the result
curl "https://namegender.com/api/v1/batches/B-7K2M9QX4TA/result" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o customers-gender.csv
import { NameGender } from 'namegender';
import { openAsBlob } from 'node:fs';
import { writeFile } from 'node:fs/promises';

const client = new NameGender(process.env.NAMEGENDER_API_KEY);

const job = await client.batches.create(await openAsBlob('customers.csv'), {
  filename: 'customers.csv',
  name_column: 'first_name',
  country_column: 'country',
});

const done = await client.batches.wait(job.id);
if (done.status === 'failed') throw new Error(done.error.code);

const file = await client.batches.download(done.id);
await writeFile('customers-gender.csv', Buffer.from(await file.arrayBuffer()));
from namegender import NameGender

client = NameGender("YOUR_API_KEY")

job = client.batches.create("customers.csv", name_column="first_name", country_column="country")

done = client.batches.wait(job["id"])
if done["status"] == "failed":
    raise RuntimeError(done["error"]["code"])

client.batches.download(done["id"], "customers-gender.csv")
{
  "id": "B-7K2M9QX4TA",
  "status": "completed",
  "source": "api",
  "file": { "name": "customers.csv", "format": "csv" },
  "columns": { "name": "first_name", "country": "country" },
  "rows": { "total": 200000, "processed": 200000, "identified": 187412 },
  "progress": 100,
  "credits": { "reserved": 200000, "charged": 200000 },
  "summary": { "male": 96120, "female": 91292, "unknown": 12588, "from_llm": 0 },
  "error": null,
  "result": {
    "url": "https://namegender.com/api/v1/batches/B-7K2M9QX4TA/result",
    "format": "csv",
    "expires_at": "2026-10-01T10:04:12Z"
  },
  "poll_after_seconds": null
}

name_column es obligatorio para iniciar: una columna adivinada que resulte incorrecta gastaría créditos en los datos equivocados. Envía start=false para ver primero las columnas, una vista previa y el coste, y luego inicia el trabajo.

Envía una cabecera Idempotency-Key. Un reintento con la misma clave devuelve el primer trabajo en lugar de abrir otro.

Puede haber hasta 3 trabajos en cola o en ejecución a la vez. Un trabajo que no ha empezado se puede cancelar y se devuelve su crédito; uno en proceso no se puede detener.

POST https://your-server.example/…
Markdown

Webhooks

Añade un endpoint en Webhooks de tu panel y le enviaremos un POST firmado cuando un trabajo de archivo termine o falle, sin que tengas que consultar.

Evento Tipo Descripción
batch.completed BatchJob El trabajo terminó. El cuerpo lleva el trabajo tal como lo devuelve GET /batches/{id}.
batch.failed BatchJob El trabajo falló y no se cobró. Ramifica según error.code.
credits.low CreditsAlert Al ritmo actual, los créditos duran 7 días o menos. Se comprueba cada hora; se tienen en cuenta las renovaciones de suscripción.
credits.depleted CreditsAlert El saldo está vacío y las peticiones se rechazan con 402. Se comprueba cada hora.
webhook.test object Solo se envía con "Enviar evento de prueba" del panel y solo a ese endpoint.
Cabecera Tipo Descripción
NameGender-Signature
requerido
string t=<segundos unix>,v1=<hex>. Tras renovar el secreto aparece un segundo v1 durante 24 horas.
NameGender-Event-Id
requerido
string El id del evento. Es el mismo en cada reintento del mismo evento.
NameGender-Delivery-Attempt
requerido
integer 1 en el primer intento, hasta 8.

Verifica cada petición

v1 es el HMAC-SHA256 de la marca de tiempo, un punto y el cuerpo sin procesar, con el secreto de tu endpoint. Compara en tiempo constante, acepta la petición si coincide algún v1 y rechaza una marca de tiempo que difiera más de cinco minutos de tu reloj. Las bibliotecas cliente hacen todo esto en una llamada.

Verifica el cuerpo tal como llega. Un framework que analiza el JSON y lo vuelve a serializar cambia los bytes y la firma no coincide.
import express from 'express';
import { webhooks, NameGenderWebhookError } from 'namegender';

const app = express();

// express.raw, not express.json: the signature covers the exact bytes.
app.post('/namegender', express.raw({ type: 'application/json' }), async (req, res) => {
  let event;
  try {
    event = await webhooks.verify(
      req.body,
      req.get('NameGender-Signature'),
      process.env.NAMEGENDER_WEBHOOK_SECRET,
    );
  } catch (error) {
    if (error instanceof NameGenderWebhookError) return res.sendStatus(400);
    throw error;
  }

  res.sendStatus(204);   // answer first, then do the work

  if (event.type === 'batch.completed') {
    const job = event.data.object;   // same object as GET /batches/{id}
  }
});
import os
from flask import Flask, request
from namegender import webhooks, WebhookVerificationError

app = Flask(__name__)

@app.post("/namegender")
def namegender_webhook():
    try:
        event = webhooks.verify(
            request.get_data(),   # raw bytes, not request.json
            request.headers.get("NameGender-Signature"),
            os.environ["NAMEGENDER_WEBHOOK_SECRET"],
        )
    except WebhookVerificationError:
        return "", 400

    if event["type"] == "batch.completed":
        job = event["data"]["object"]   # same object as GET /batches/{id}
    return "", 204
<?php

$body   = file_get_contents('php://input');   // raw body, before json_decode
$header = $_SERVER['HTTP_NAMEGENDER_SIGNATURE'] ?? '';
$secret = getenv('NAMEGENDER_WEBHOOK_SECRET');

parse_str(str_replace(',', '&', $header), $parts);   // t=…&v1=…
preg_match_all('/v1=([0-9a-f]{64})/', $header, $m);

$t = (int) ($parts['t'] ?? 0);
$expected = hash_hmac('sha256', $t . '.' . $body, $secret);
$valid = abs(time() - $t) <= 300
    && array_filter($m[1], fn ($sig) => hash_equals($expected, $sig));

if (! $valid) {
    http_response_code(400);
    exit;
}

http_response_code(204);
$event = json_decode($body, true);
{
  "id": "evt_16f7c01502fda5436e8b7c4e",
  "type": "batch.completed",
  "created_at": "2026-09-24T10:04:12Z",
  "api_version": "v1",
  "data": {
    "object": {
      "id": "B-7K2M9QX4TA",
      "status": "completed",
      "rows": { "total": 200000, "processed": 200000, "identified": 187412 },
      "credits": { "reserved": 200000, "charged": 200000 },
      "result": { "url": "…/api/v1/batches/B-7K2M9QX4TA/result", "format": "csv" }
    }
  }
}
  • Responde con cualquier 2xx en menos de 10 segundos y haz el trabajo después.
  • Cualquier otra respuesta, redirecciones incluidas, se reintenta hasta 7 veces durante unas 45 horas. Si un endpoint sigue fallando tres días, se desactiva y te enviamos un correo.
  • Un reintento lleva el mismo id y el orden no está garantizado. Deduplica por NameGender-Event-Id y lee el trabajo con GET cuando necesites su estado actual.
  • Al renovar el secreto en el panel, el anterior sigue firmando 24 horas, así actualizas tu servidor sin perder eventos.
  • Pueden añadirse nuevos tipos de evento. Responde 2xx a un tipo que no gestiones e ignóralo.
GET POST https://namegender.com/api/v1/gender/countries
Markdown

Distribución por país

Devuelve los países donde se registra un nombre. Se devuelven dos listas que deliberadamente no se fusionan: `registrations` es el volumen medido, comparable solo entre los once países que publican estadísticas de nombres contabilizadas, y `attested_in` es presencia, sin ponderación asignada.

Esto no es una inferencia de país de origen o etnia, y no debe usarse como tal. Las estadísticas contabilizadas existen solo para once países: EE.UU., Reino Unido, Francia, Canadá, España, Irlanda, Noruega, Austria, Israel, Polonia y Suiza. Por lo tanto, una búsqueda de "Mehmet" clasifica primero a Suiza y Francia, con alrededor del 29% cada una, y Turquía no aparece en la clasificación en absoluto — Turquía no publica conteos. Turquía sí aparece en `attested_in`.
Parámetro Tipo Descripción
name
requerido
string El nombre a buscar.
limit
opcional
integer Cuántos países contabilizados incluir en `registrations`. 1–100, predeterminado 25. Los porcentajes no se recalculan para la lista más corta.
curl "https://namegender.com/api/v1/gender/countries?name=Mehmet" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "credits_charged": 1,
  "credits_remaining": 49994,
  "took_ms": 3,
  "name": "Mehmet",
  "basis": {
    "counted_sources": ["ssa", "ons", "nrs", "nisra", "insee", "statcan", "ine", "cso", "ssb", "statat", "pesel", "bfs"],
    "counted_countries": 8,
    "attested_countries": 16,
    "note": "Shares are calculated only across countries that publish counted name statistics…"
  },
  "registrations": [
    { "country": "CH", "count": 3890, "share": 29.45, "gender": "male", "source": "bfs"    },
    { "country": "FR", "count": 3775, "share": 28.58, "gender": "male", "source": "insee"  },
    { "country": "PL", "count": 1808, "share": 13.69, "gender": "male", "source": "pesel"  }
  ],
  "attested_in": ["AL","AT","AU","BE","CA","CH","ES","FR","GB","KS","MK","NO","PL","SE","TR","US"]
}

Un crédito por solicitud. `share` se calcula sobre todos los países con conteo, así que suma 100 solo cuando `limit` no recorta la lista; `counted_countries` también cuenta antes del recorte. `attested_in` no incluye porcentajes porque no hay conteo detrás de esos registros para calcularlo.

GET POST https://namegender.com/api/v1/salutation
Markdown

Saludo

Convierte un nombre en un saludo listo para una carta o un correo, en diez idiomas: “Sehr geehrte Frau Dr. Müller,”, “Sayın Ahmet Bey,”, “Madame,”, “山田様”. La consulta de género está incluida y cuesta el mismo crédito. Cada respuesta trae una línea formal, una informal y una neutra, además de las partes de la línea formal.

Parámetro Tipo Descripción
name
requerido
string Nombre completo, con títulos incluidos (“Dr. Anna Müller”). Envía este o `first_name` y `last_name`.
first_name, last_name
opcional
string Úsalos en lugar de `name` cuando tu CRM guarda los nombres en campos separados. No se analiza nada.
email
opcional
string Dirección de correo, usada cuando no se envía un nombre. El nombre se lee de la parte antes de la @, sin tildes (Mueller, no Müller); info@ y otras direcciones de cargo reciben el saludo para organizaciones.
language
opcional
string Idioma del saludo: en, en-US, en-GB, de, de-AT, de-CH, fr, es, it, pt, pt-PT, pt-BR, nl, tr, pl, ja. Sin él: el idioma de `locale`, luego el idioma principal del país y luego inglés. Un idioma no admitido es un error, nunca un cambio silencioso a inglés.
country, locale, ip
opcional
string Pista de país para la consulta de género, como en los endpoints de género. Solo elige el idioma cuando no se envía `language`.
gender
opcional
string `male`, `female` o `neutral`, si ya lo conoces. Reemplaza la consulta; `neutral` siempre da la forma neutra.
min_probability
opcional
integer Probabilidad mínima para un saludo con género, 50–100. Predeterminado 90.
title
opcional
string Título académico guardado en un campo aparte, como `Dr.` Se usa en los saludos en alemán e inglés.
curl -X POST "https://namegender.com/api/v1/salutation" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Dr. Anna Müller", "language": "de"}'
{
  "credits_charged": 1,
  "credits_remaining": 49993,
  "language": "de",
  "form": "gendered",
  "reason": null,
  "salutation": {
    "formal": "Sehr geehrte Frau Dr. Müller,",
    "informal": "Liebe Anna,",
    "neutral": "Guten Tag Dr. Anna Müller,"
  },
  "parts": { "opening": "Sehr geehrte", "courtesy": "Frau", "academic": "Dr.", "name": "Müller" },
  "gender": "female",
  "gender_source": "lookup",
  "probability": 99,
  "first_name": "Anna",
  "last_name": "Müller",
  "name_type": "personal"
}

Un género equivocado es peor que ninguno, así que la forma con género solo se usa cuando el género se conoce con al menos `min_probability` y el idioma tiene la parte del nombre que necesita. Si no, `form` es `neutral` y `reason` explica por qué. Las empresas y las direcciones de cargo reciben `form: organization`. `best_guess` y `ai_fallback` no se aplican aquí.

POST /api/v1/salutation/bulk acepta hasta 100 nombres en `names`, un crédito cada uno, con las mismas opciones aplicadas a cada nombre.

GET POST https://namegender.com/api/v1/name-check
Markdown

Comprobación de nombre

Indica si un nombre escrito en un formulario de registro o de captación parece el nombre de una persona real, y por qué. Detecta tecleo al azar (“asdf qwerty”), valores de relleno (“Test Test”, “John Doe”, “n/a”), personajes de ficción (“Mickey Mouse”), groserías y dígitos, símbolos o direcciones de correo en el campo del nombre. Un crédito por nombre.

No es una verificación de identidad y nunca califica un nombre de falso. Usa `implausible` y `suspicious` para marcar un registro o pedir más información, no para rechazar personas automáticamente.
Parámetro Tipo Descripción
name
requerido
string El nombre tal como se escribió en el formulario. Envía este o `first_name` y `last_name`.
first_name, last_name
opcional
string Úsalos en lugar de `name` cuando tu formulario tiene campos separados.
country, locale, ip
opcional
string Pista de país, como en los endpoints de género. Ayuda a separar el nombre y a buscarlo en los registros.
curl -X POST "https://namegender.com/api/v1/name-check" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "asdf qwerty"}'
{
  "credits_charged": 1,
  "credits_remaining": 49992,
  "query": "asdf qwerty",
  "assessment": "implausible",
  "score": 0,
  "signals": [
    { "code": "placeholder", "severity": "high", "part": "first_name", "value": "asdf" },
    { "code": "keyboard_pattern", "severity": "high", "part": "first_name", "value": "asdf" },
    { "code": "keyboard_pattern", "severity": "high", "part": "last_name", "value": "qwerty" }
  ],
  "first_name": "Asdf",
  "last_name": "Qwerty",
  "name_type": "personal",
  "evidence": { "first_name_status": "not_found", "first_name_counted_records": 0 }
}

`assessment` es `implausible` cuando hay una señal de gravedad alta (patrón de teclado, letras repetidas, valor de relleno, grosería, correo o URL), `suspicious` con una media (personaje de ficción, dígitos, símbolos, nombre de empresa, sin vocales, muy largo) o dos bajas, y `plausible` en los demás casos. `score` va de 0 a 100 para que fijes tu propio umbral. Un nombre de pila que aparece en registros oficiales de nacimientos lo sube; un nombre que nunca hemos visto no lo baja por sí solo. Los apellidos se juzgan solo por su forma: detrás de este endpoint no hay un conjunto de datos de apellidos.

Probado con 4.610 nombres de pila reales en nueve escrituras, solos y junto a un apellido: ninguno se marcó como sospechoso o inverosímil. Los apellidos como Null, Test o Cockburn, los nombres de dos letras como Ng y los nombres únicos se dejan en paz a propósito.

POST /api/v1/name-check/bulk acepta hasta 100 nombres en `names`, un crédito cada uno, con un resumen de las tres valoraciones.

GET POST https://namegender.com/api/v1/age
Markdown

Edad por nombre

Qué edad tienen las personas vivas con un nombre de pila: la edad mediana, la mitad central (`age_range`) y el 80% central (`age_range_80`). Brittany en Estados Unidos: mediana 36, la mitad entre 32 y 38. Un crédito por nombre.

Describe un grupo, no a una persona. En la mayoría de los nombres la mitad central abarca de 10 a 25 años. Úsalo para análisis de audiencia, segmentos e investigación, nunca para decidir nada sobre una persona concreta: crédito, contratación, vivienda, seguros, elegibilidad o verificación de edad.
Parámetro Tipo Descripción
name
requerido
string Un nombre de pila o un nombre completo; se usa el nombre de pila.
gender
opcional
string `male` o `female` para usar solo los registros de ese sexo. Los hombres llamados Leslie tienen 16 años más que las mujeres llamadas Leslie.
country, locale, ip
opcional
string Pista de país, como en los endpoints de género. Cubiertos: US, FR y NO. Sin pista se usa la serie de Estados Unidos y `country_source` es `default`. Otro país devuelve `reason: country_not_covered` y no cuesta nada.
curl "https://namegender.com/api/v1/age?name=Brittany" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "credits_charged": 1,
  "credits_remaining": 49991,
  "request_id": "req_8f2c1a",
  "name": "Brittany",
  "first_name": "Brittany",
  "gender": null,
  "age": 36,
  "age_range": { "low": 32, "high": 38 },
  "age_range_80": { "low": 28, "high": 41 },
  "birth_year": 1990,
  "sample_size": 353775,
  "births": 361434,
  "country": "US",
  "country_source": "default",
  "source": "ssa",
  "series": "1880-2024",
  "reference_year": 2026,
  "reason": null
}

Método: nacimientos registrados por nombre, sexo y año, con cada año ponderado por la proporción de esa cohorte de nacimiento que sigue viva (tablas de mortalidad por cohorte de la SSA). Fuentes: nacimientos SSA 1880–2024 (US), INSEE 1900–2025 (Francia), SSB 1945–2025 (Noruega). `reason` es `not_found` para un nombre que no está en la serie e `insufficient_data` por debajo de 100 personas vivas.

Los nacimientos en el extranjero no están en ninguna serie, así que los nombres comunes entre inmigrantes parecen más jóvenes de lo que son. La serie de Noruega empieza en 1945, por lo que faltan las personas nacidas antes. La tabla de mortalidad de Estados Unidos se usa también para Francia y Noruega.

POST /api/v1/age/bulk acepta hasta 100 nombres en `names`, un crédito cada uno, en el orden de envío.

GET https://namegender.com/api/v1/me
Markdown

Saldo

Consulta tu saldo de créditos y lo que queda de la asignación gratuita de hoy. Esta llamada no se cobra.

curl "https://namegender.com/api/v1/me" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "email": "you@example.com",
  "credits_remaining": 50099,
  "purchased_credits": 50000,
  "free_today": 99,
  "free_daily_limit": 100,
  "lifetime_requests": 12480
}

Escrituras no latinas

Envía un nombre en su escritura original y lo vinculamos con los datos de referencia. Sin parámetros adicionales: detectamos la escritura y elegimos la estrategia correcta.

Compatible
Escritura árabe

La escritura árabe omite las vocales cortas, así que محمد se translittera a "mhmd" mientras nuestros datos contienen "muhammed". Hacemos coincidencia por el patrón de consonantes, y preservamos el marcador femenino ة para que خالد (Khalid) y خالدة (Khalida) se mantengan separados. También cubre nombres persas y urdu escritos en árabe.

Caracteres chinos

Se convierten a pinyin. El apellido viene primero en chino, así que 李明 tiene apellido 李 (Li) y nombre 明 (Ming) — removemos el apellido antes de buscar. Un carácter único es un nombre completo y se trata como tal.

Coreano

Mismo tratamiento de apellido primero que en chino, usando los apellidos coreanos comunes.

Kana japonés

Hiragana y katakana se leen correctamente (ひろし → Hiroshi).

Cirílico

Nombres rusos, ucranianos, búlgaros y serbios se transliteran directamente.

Devanagari

Nombres en hindi, marathi y nepalí. Se maneja la vocal final inherente (राहुल → Rahul, no "Rahula").

No compatible
Kanji japonés

Los caracteres kanji japoneses y los caracteres chinos ocupan el mismo rango Unicode, por lo que no podemos distinguirlos solo por los caracteres. La entrada Han se lee como chino: un nombre kanji que no tenemos almacenado literalmente obtiene su lectura mandarina, que para un nombre japonés generalmente es incorrecta (健太 se lee como "jian tai" cuando el nombre es Kenta). Los nombres que sí tenemos coinciden exactamente y son correctos. Envía nombres japoneses en kana o caracteres latinos para estar seguro.

Tailandés

El tailandés omite vocales como el árabe y necesita su propia capa de coincidencia. Aún no está implementado, así que estos devuelven null.

# Arap yazısı — ünsüz iskeleti üzerinden eşleşir
curl "https://namegender.com/api/v1/gender?name=%D9%85%D8%AD%D9%85%D8%AF" -H "Authorization: Bearer KEY"
# -> { "gender": "male", "probability": 100, "source": "script", "matched_as": "mahamad" }

# Çince — soyadı ayıklanır, verilen ad sorgulanır
curl "https://namegender.com/api/v1/gender?name=%E6%9D%8E%E6%98%8E" -H "Authorization: Bearer KEY"
# -> { "gender": "male", "probability": 92, "source": "db" }

No se pudo copiar. Selecciona y copia el texto.

Cuando no podemos convertir un sistema de escritura, la respuesta es gender: null con source: none. Verifica el campo source: script significa que transliteramos, db significa que coincidimos directamente con los caracteres que enviaste. Los dos tienen diferentes niveles de confianza, y te mostramos cuál obtuviste.

Campos de respuesta

Idénticos en todos los endpoints.

Campo Tipo Descripción
credits_charged integer Cuántos créditos se descontaron por esta llamada.
credits_remaining integer Tu saldo disponible una vez pagada esta llamada: créditos comprados más lo que queda de la asignación gratuita de hoy.
query string La entrada exactamente como la enviaste, antes de cualquier limpieza.
name string El nombre que realmente buscamos después de eliminar títulos y apellidos.
first_name string Nombre de pila extraído de la entrada. Se devuelve aunque gender sea null, sin coste adicional.
middle_name string Otros nombres entre el nombre de pila y el apellido. Las iniciales se omiten.
last_name string Apellido, con partículas como van o de la. Con un country hispanohablante incluye los dos apellidos. Siempre null en nombres de usuario.
name_type string personal, organization (Acme S.L.) o role (info@, atención al cliente). Las organizaciones y los roles no reciben género.
gender string masculino, femenino, o null cuando no tenemos suficiente confianza.
country string El país del que provienen las estadísticas, o null para el agregado global.
country_source string De dónde salió el país: country, locale, ip o null cuando la respuesta es mundial.
sample_size integer Número de personas registradas detrás de esta respuesta. 0 significa que la fuente publica proporciones o constancias, no un recuento que podamos auditar.
probability integer Confianza en el género indicado, 50 a 100. 0 cuando el género es null.
took_ms integer Tiempo que dedicamos a resolver la búsqueda, en milisegundos enteros. No incluye el tiempo de red de tu lado.

Dos campos que otros servicios no ofrecen

source te dice de dónde vino la respuesta: la base de datos de referencia, una coincidencia aproximada o el fallback de IA. matched_as nombra la entrada en la que aterrizó la coincidencia aproximada. Juntos te permiten decidir cuánto confiar en un resultado individual en lugar de aceptarlo sin cuestionarlo.

Campo Tipo Descripción
source string db, script, fuzzy, llm, o none.
confidence string alta, media, baja, sin verificar o desconocida, según la evidencia de la muestra.
matched_as string Para una coincidencia aproximada, la entrada de la base de datos que coincidió. En caso contrario null.

Códigos de error

El código de estado HTTP te indica que una llamada falló. Después, el cuerpo JSON nombra el motivo en error, lo explica en message y te da un request_id para citar al soporte, además de un enlace a la fila correspondiente más abajo. Decide siempre según error, nunca según message: los mensajes se traducen y pueden redactarse de otra forma.

Código HTTP Significado
missing_key 401 No se envió ninguna clave API. Añade un header Authorization: Bearer o un header X-Api-Key a la solicitud.
invalid_key 401 Esta clave API no es válida.
revoked_key 401 Esta clave API ha sido revocada.
blocked 403 Esta cuenta ha sido suspendida. Contacta con soporte.
email_not_verified 403 La dirección de correo de esta cuenta aún no se ha confirmado. Abre el enlace de confirmación que te enviamos o solicita uno nuevo desde tu panel.
ip_not_allowed 403 Las solicitudes desde esta dirección IP no están permitidas para esta clave.
proxy_secret_required 403 Esta clave solo funciona a través de su marketplace de API, que firma cada solicitud. Usa la clave que te emitieron allí.
forbidden 403 No tienes permiso para realizar esta acción.
no_credits 402 No tienes créditos disponibles. Compra más o espera a que se reinicie tu cuota gratuita diaria.
missing_input 400 El parámetro "name" es obligatorio.
invalid_input 422 El parámetro "name" no es válido.
too_many_items 422 Se puede enviar un máximo de 100 elementos en una solicitud.
unknown_endpoint 404 No hay endpoint en esta ruta. Verifica la URL en la documentación de la API.
method_not_allowed 405 Este endpoint no acepta solicitudes DELETE.
payload_too_large 413 El cuerpo de la solicitud es demasiado grande.
rate_limited 429 Demasiadas solicitudes. Ralentiza el ritmo e intenta de nuevo en poco tiempo.
batch_not_found 404 No hay ningún trabajo de archivo con este ID en esta cuenta.
batch_not_startable 409 Este trabajo ya se ha iniciado o cerrado.
batch_not_finished 409 Este trabajo aún no ha terminado. Consulta su estado y descarga el resultado cuando se haya completado.
batch_in_progress 409 Este trabajo se está procesando y no se puede cancelar ahora. Elimínalo cuando haya terminado.
result_gone 410 Este trabajo no tiene resultado para descargar. Falló, se canceló, caducó o su resultado de descarga única ya se descargó.
too_many_batches 429 Ya tienes 100 trabajos de archivo en curso. Espera a que termine uno antes de iniciar otro.
not_ready 503 La base de datos de nombres se está reconstruyendo. Intenta de nuevo en un momento.
server_error 500 Algo salió mal en nuestro lado. Ya hemos sido notificados.
{
  "error": "no_credits",
  "message": "You are out of credits. Buy more or wait for your daily free quota to reset.",
  "request_id": "req_9c1f5b2a7e0d4a13",
  "docs": "https://namegender.com/docs#error-no_credits"
}

No se pudo copiar. Selecciona y copia el texto.

Límites de velocidad

El uso normal no alcanza un límite. El tope existe para evitar que una clave filtrada sea abusada, y se cuenta por clave API en lugar de por IP para que varios clientes en un servidor no consuman la asignación de otros.

Límite actual: 1.200 solicitudes por minuto por clave. ¿Necesitas más? Pregunta y lo aumentaremos en tu cuenta.

Cada respuesta lleva los headers estándar X-RateLimit-Limit y X-RateLimit-Remaining.

Espacios y letras no latinas en solicitudes GET

Un nombre como Ayşe Yılmaz o 中村 no puede viajar en una URL tal como se escribe. Aplica codificación porcentual al valor cuando llames con GET, o envíalo en un cuerpo JSON con POST y olvídate de codificar.

Ayşe Yılmaz  ->  Ay%C5%9Fe%20Y%C4%B1lmaz
محمد          ->  %D9%85%D8%AD%D9%85%D8%AF
中村           ->  %E4%B8%AD%E6%9D%91

No se pudo copiar. Selecciona y copia el texto.