DOCUMENTACIÓN API V2

GenderAPI.io V2: lotes de nombres, correos y usuarios

Combina nombres, correos y usuarios en un lote de GenderAPI.io V2. Envía hasta 50 registros con clave de API o 10 en la prueba por IP, con resultados por registro.

Nombres, correos y usuarios por lotes

ParámetroTipoObligatorioValor predeterminadoDescripción
itemsarray<object>Sí—Entre 1 y 50 elementos; como máximo 10 en la prueba por IP. Se conserva el orden de entrada.
items[].typestringSí—Categoría de entrada: name, email o username.
items[].valuestringSí—Requerido. 1–254 caracteres; no en blanco, sin caracteres de control. Los valores de correo electrónico deben tener una sintaxis de correo electrónico válida.
items[].countrystringNo—Código ISO 3166-1 alpha-2 en mayúsculas opcional, por ejemplo TR o US. La búsqueda específica de un país puede recurrir al conjunto de datos global.
items[].forceToGenderizebooleanNofalseConsulta primero el conjunto de datos y después la IA para apodos si no hay resultado. Compatible con name, email y username.
items[].optionsobjectNo—Objeto con las opciones de IA de cada entrada.
items[].options.ai_modestringNooffValores permitidos: off, fallback, always. Con forceToGenderize: true, omite este campo o utiliza fallback.
items[].idstringNo—Identificador opcional con entre 1 y 64 caracteres en el cuerpo POST JSON. Debe ser único dentro de un lote y se devuelve con el resultado del lote. Las solicitudes individuales aceptan este identificador pero no lo incluyen en la respuesta. Las consultas GET no lo admiten.

GenderAPI.io V2 acepta nombres, correos y usuarios juntos en POST https://api.genderapi.io/api/v2/gender/batch. Envía un array items con entre 1 y 50 registros con clave de API, o hasta 10 en la prueba por IP. Cada registro utiliza type y value, y admite tus propios country, forceToGenderize y options. Los id son opcionales y deben ser únicos en el lote.

Los resultados conservan el orden de entrada. Cada uno contiene index, charged_credits y exactamente uno de data o error. Si enviaste un id, también se devuelve. HTTP 200 puede incluir errores por registro: revísalos todos. meta.summary contiene total, succeeded, identified, unknown y failed. Un resultado completado sin predicción se considera correcto y tiene coste.

Si la validación o la planificación de la solicitud falla, se rechaza todo el lote antes de deducir los créditos. Si todas las entradas fallan durante la ejecución, la API devuelve una respuesta de problema que no es 2xx con una matriz data y el alias heredado results. Las entradas fallidas cuestan cero créditos después de un reembolso confirmado. Si la facturación no está confirmada, no presupongas que el costo informado para cada entrada es definitivo.

Elige un lenguaje de programación. Configura tu clave API, luego ejecuta el ejemplo en tu servidor.

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.

Antes de ejecutar: acceso y manejo de errores

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.

Para las respuestas JSON HTTP 4xx y 5xx, los ejemplos conservan el cuerpo del error y salen con un estado distinto de cero. Comprueba code, action y meta.usage.billing_status antes de volver a intentarlo. Para una respuesta por lotes HTTP 200, revisa también data o error en cada resultado.

Guía de errores y reintentos →
cURL
curl --silent --show-error --fail-with-body --max-time 30 \
  --request POST 'https://api.genderapi.io/api/v2/gender/batch' \
  --header "Authorization: Bearer ${GENDERAPI_API_KEY:?Set GENDERAPI_API_KEY}" \
  --header 'Content-Type: application/json' \
  --data '{
  "items": [
    {
      "id": "contact-1",
      "type": "name",
      "value": "Carmen",
      "country": "ES"
    },
    {
      "id": "contact-2",
      "type": "email",
      "value": "alice.smith@example.com",
      "options": {
        "ai_mode": "fallback"
      }
    },
    {
      "id": "contact-3",
      "type": "username",
      "value": "prenses",
      "country": "TR",
      "forceToGenderize": true
    }
  ]
}'

cURL 7.76+ en un shell POSIX. Ejecuta en tu terminal. Documentación del entorno de ejecución

JavaScript / Node.js
// 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 = {
  "items": [
    {
      "id": "contact-1",
      "type": "name",
      "value": "Carmen",
      "country": "ES"
    },
    {
      "id": "contact-2",
      "type": "email",
      "value": "alice.smith@example.com",
      "options": {
        "ai_mode": "fallback"
      }
    },
    {
      "id": "contact-3",
      "type": "username",
      "value": "prenses",
      "country": "TR",
      "forceToGenderize": true
    }
  ]
};

const response = await fetch("https://api.genderapi.io/api/v2/gender/batch", {
  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.
}

Node.js 22+; fetch integrado. Guarda como example.mjs y ejecuta node example.mjs. Documentación del entorno de ejecución

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("{\"items\":[{\"id\":\"contact-1\",\"type\":\"name\",\"value\":\"Carmen\",\"country\":\"ES\"},{\"id\":\"contact-2\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-3\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}")

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/batch",
    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.

Python 3.10+; biblioteca estándar. Guarda como example.py y ejecuta python3 example.py. Documentación del entorno de ejecución

PHP
<?php
$apiKey = getenv('GENDERAPI_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set GENDERAPI_API_KEY');
}
$body = json_decode('{"items":[{"id":"contact-1","type":"name","value":"Carmen","country":"ES"},{"id":"contact-2","type":"email","value":"alice.smith@example.com","options":{"ai_mode":"fallback"}},{"id":"contact-3","type":"username","value":"prenses","country":"TR","forceToGenderize":true}]}', true, 512, JSON_THROW_ON_ERROR);

$ch = curl_init('https://api.genderapi.io/api/v2/gender/batch');
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.

PHP 8+ con la extensión cURL. Guarda como example.php y ejecuta php example.php. Documentación del entorno de ejecución

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 = "{\"items\":[{\"id\":\"contact-1\",\"type\":\"name\",\"value\":\"Carmen\",\"country\":\"ES\"},{\"id\":\"contact-2\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-3\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}";
        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/batch"))
            .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.
    }
}

Java 17+; cliente estándar HTTP. Guarda como GenderApiExample.java y ejecuta java GenderApiExample.java. Documentación del entorno de ejecución

C# / .NET
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/batch");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
request.Content = new StringContent("{\"items\":[{\"id\":\"contact-1\",\"type\":\"name\",\"value\":\"Carmen\",\"country\":\"ES\"},{\"id\":\"contact-2\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-3\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}", 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.
}

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

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 := "{\"items\":[{\"id\":\"contact-1\",\"type\":\"name\",\"value\":\"Carmen\",\"country\":\"ES\"},{\"id\":\"contact-2\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-3\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}"
    request, err := http.NewRequest("POST", "https://api.genderapi.io/api/v2/gender/batch", 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)
    }
}

Go 1.22+; biblioteca estándar. Guarda como main.go y ejecuta go run main.go. Documentación del entorno de ejecución

Leer una respuesta por lotes

Este ejemplo combina dos resultados reales capturados el 1 de octubre de 2026, una coincidencia de conjunto de datos y un resultado desconocido, con una falla del proveedor ilustrativa. Muestra una respuesta HTTP 200 de éxito parcial, no el resultado esperado de la solicitud por lotes anterior. Los dos elementos exitosos cuestan 1 crédito cada uno; el elemento fallido tiene un cargo cero confirmado.

Respuesta JSON ilustrativa
{
  "data": [
    {
      "index": 0,
      "id": "known",
      "charged_credits": 1,
      "data": {
        "input": {
          "type": "name",
          "value": "Carmen",
          "country": "ES"
        },
        "name": "carmen",
        "gender": "female",
        "country": "ES",
        "confidence": 0.9978779840848806,
        "confidence_kind": "observed_frequency",
        "sample_count": 1885,
        "source": "dataset",
        "result_status": "identified",
        "reason": null,
        "country_source": "dataset",
        "match": {
          "name": "carmen",
          "method": "normalized",
          "scope": "country",
          "country": "ES"
        }
      }
    },
    {
      "index": 1,
      "id": "missing",
      "charged_credits": 1,
      "data": {
        "input": {
          "type": "name",
          "value": "zzzxxyy",
          "country": null
        },
        "name": null,
        "gender": null,
        "country": null,
        "confidence": null,
        "confidence_kind": null,
        "sample_count": null,
        "source": "none",
        "result_status": "unknown",
        "reason": "not_found",
        "country_source": null,
        "match": {
          "name": null,
          "method": null,
          "scope": null,
          "country": null
        }
      }
    },
    {
      "index": 2,
      "id": "failed",
      "charged_credits": 0,
      "error": {
        "type": "urn:genderapi:problem:ai_upstream_error",
        "title": "ai upstream error",
        "status": 502,
        "detail": "The AI provider could not complete the request.",
        "instance": "urn:uuid:11111111-1111-4111-8111-111111111111",
        "code": "ai_upstream_error",
        "request_id": "11111111-1111-4111-8111-111111111111",
        "documentation": "https://api.genderapi.io/api/v2/errors",
        "action": "inspect_billing_before_retry"
      }
    }
  ],
  "meta": {
    "request_id": "11111111-1111-4111-8111-111111111111",
    "duration_ms": 12,
    "access": {
      "mode": "ip_trial",
      "reason": "api_key_missing"
    },
    "usage": {
      "charged_credits": 2,
      "remaining_credits": 6,
      "billing_status": "confirmed",
      "resets_at": "2026-09-26T12:00:00.000Z",
      "limit": 10,
      "period_seconds": 86400
    },
    "summary": {
      "total": 3,
      "succeeded": 2,
      "identified": 1,
      "unknown": 1,
      "failed": 1
    }
  }
}

Campos de los resultados por lotes

CampoTipo¿Admite null?EjemploDescripción
dataarray<object>No[…]Resultados ordenados. Cada elemento contiene una predicción o un error; revíselos todos.
data[].indexintegerNo0Posición en el array items enviado, empezando por cero.
data[].idstringNo"contact-1"Su identificador de entrada; solo aparece si lo proporcionó.
data[].charged_creditsintegerNo1Cobro neto del elemento tras reembolsos confirmados. No lo considere definitivo si el cobro global no está confirmado.
data[].dataobjectNo{…}Presente en elementos correctos, incluidos resultados desconocidos. Usa los campos de predicción de la guía de respuestas.
data[].errorobjectNo{…}Presente en elementos fallidos en lugar de data. Usa los campos Problem Details de la guía de errores.

Campos del resumen del lote

CampoTipo¿Admite null?EjemploDescripción
meta.summary.totalintegerNo3Número total de elementos del lote.
meta.summary.succeededintegerNo2Elementos correctos, incluidas predicciones desconocidas.
meta.summary.identifiedintegerNo1Elementos correctos con género distinto de null.
meta.summary.unknownintegerNo1Elementos correctos con género null; estos resultados se cobran.
meta.summary.failedintegerNo1Elementos fallidos. total = succeeded + failed; succeeded = identified + unknown.

Acceso, facturación y metadatos de la solicitud

CampoTipo¿Admite null?EjemploDescripción
meta.request_idstringNo"550e8400-e29b-41d4-a716-446655440000"Identificador único de este intento HTTP; también se envía en X-Request-ID.
meta.duration_msintegerNo42Tiempo de procesamiento de la solicitud en milisegundos.
meta.access.modestringNo"api_key"api_key, ip_trial o unauthenticated. Comprueba api_key para cualquier integración de cuenta, gratuita o de pago.
meta.access.reasonstringSínullMotivo del acceso de prueba: api_key_missing, api_key_invalid o api_key_not_found; null en otros casos.
meta.usage.charged_creditsintegerSí1Créditos netos cobrados. Cero antes del cobro o tras un reembolso completo confirmado; null si el cobro no está confirmado.
meta.usage.remaining_creditsintegerSí99Saldo al finalizar la operación. Puede ser negativo; null si no está disponible o el cobro no está confirmado.
meta.usage.billing_statusstringNo"confirmed"not_charged, confirmed o unconfirmed. Compruébelo antes de reintentar una predicción fallida.
meta.usage.resets_atstringSí"2026-09-27T12:00:00.000Z"Reinicio de la prueba por IP en UTC (ISO 8601); null para cuentas con clave API o si se desconoce.
meta.usage.limitintegerSí10Créditos de la prueba por IP; null para cuentas con clave API.
meta.usage.period_secondsintegerSí86400Duración de la prueba por IP en segundos; null para cuentas con clave API.

Planificar créditos y reintentos por lotes

Autentícate con tu clave actual mediante Bearer y envía Content-Type: application/json. Cada lote es una operación nueva. Si repites un lote parcialmente fallido, envía solo los registros fallidos después de comprobar el cobro; los registros completados se cobrarían de nuevo.

De forma predeterminada, las entradas por lotes utilizan off y cuestan 1 crédito por predicción completa. Seleccionar fallback también cuesta 1 crédito en total, incluida la IA. Seleccionar always cuesta 2 créditos. Con forceToGenderize, un género encontrado en el conjunto de datos cuesta 1 crédito; Usar IA cuesta 2 créditos en total. Las predicciones completadas con un género desconocido también cuestan créditos. Un saldo inicial de 1 crédito es suficiente para comenzar un lote. La deducción final podrá dejar el saldo negativo.

Procesa una lista y conserva la correspondencia de cada registro

El endpoint de lotes acepta listas de nombres, listas de correos o entradas mixtas. Divide el trabajo en grupos de hasta 50 registros con clave de API, o 10 en la prueba por IP. Conserva la posición de cada fila en tu lista original y asigna un id único dentro de cada lote. El index devuelto empieza en cero y corresponde al lote enviado, no a la lista completa.

PasoQué guardar o comprobarPor qué importa
1. Prepara cada loteConserva la fila de origen y el id; configura country y las opciones de IA por registro.Distintas personas pueden tener el mismo nombre.
2. Lee toda la respuestaGuarda meta.request_id y relaciona cada entrada de data[] mediante id o index.HTTP 200 puede incluir tanto predicciones completadas como errores por registro.
3. Guarda los resultados completadosConserva las predicciones identified y unknown, los valores JSON null y los campos que explican su origen.unknown es un resultado completado con coste, no un registro fallido que debas repetir automáticamente.
4. Revisa los errores y los créditosComprueba cada error y meta.usage.billing_status antes de enviar otra solicitud.Con el cobro confirmado, repite solo los registros fallidos cuyo error permita reintentar. Los registros completados se cobrarían de nuevo.
5. Detén los reintentos inciertosConserva el identificador de solicitud si el cobro está unconfirmed o un fallo de red impide conocer el resultado.No reenvíes todo el lote sin comprobarlo: sigue primero las guías de errores y cobro.

Elige el modo de inferencia para cada registro

Este ejemplo ejecutable utiliza tres configuraciones: solo conjunto de datos para un nombre completo, fallback estándar para un correo y análisis de alias para un usuario. Son entradas de ejemplo; no garantizan obtener una predicción para los tres registros. Elige un lenguaje en las pestañas del código y configura GENDERAPI_API_KEY antes de ejecutarlo.

A diferencia de las consultas individuales, los registros de un lote sin forceToGenderize usan IA off de forma predeterminada. Envía fallback explícitamente para recurrir a la IA cuando sea necesario. off y fallback estándar cuestan 1 crédito por registro completado; always omite el conjunto de datos y cuesta 2. forceToGenderize cuesta 1 si el conjunto de datos ofrece una predicción, o 2 en total si se usa IA. Los resultados unknown completados también se cobran. No combines forceToGenderize con off ni always.

Elige un lenguaje de programación. Configura tu clave API, luego ejecuta el ejemplo en tu servidor.

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.

Antes de ejecutar: acceso y manejo de errores

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.

Para las respuestas JSON HTTP 4xx y 5xx, los ejemplos conservan el cuerpo del error y salen con un estado distinto de cero. Comprueba code, action y meta.usage.billing_status antes de volver a intentarlo. Para una respuesta por lotes HTTP 200, revisa también data o error en cada resultado.

Guía de errores y reintentos →
cURL
curl --silent --show-error --fail-with-body --max-time 30 \
  --request POST 'https://api.genderapi.io/api/v2/gender/batch' \
  --header "Authorization: Bearer ${GENDERAPI_API_KEY:?Set GENDERAPI_API_KEY}" \
  --header 'Content-Type: application/json' \
  --data '{
  "items": [
    {
      "id": "contact-001",
      "type": "name",
      "value": "Ayşe Yılmaz",
      "country": "TR",
      "options": {
        "ai_mode": "off"
      }
    },
    {
      "id": "contact-002",
      "type": "email",
      "value": "alice.smith@example.com",
      "options": {
        "ai_mode": "fallback"
      }
    },
    {
      "id": "contact-003",
      "type": "username",
      "value": "prenses",
      "country": "TR",
      "forceToGenderize": true
    }
  ]
}'

cURL 7.76+ en un shell POSIX. Ejecuta en tu terminal. Documentación del entorno de ejecución

JavaScript / Node.js
// 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 = {
  "items": [
    {
      "id": "contact-001",
      "type": "name",
      "value": "Ayşe Yılmaz",
      "country": "TR",
      "options": {
        "ai_mode": "off"
      }
    },
    {
      "id": "contact-002",
      "type": "email",
      "value": "alice.smith@example.com",
      "options": {
        "ai_mode": "fallback"
      }
    },
    {
      "id": "contact-003",
      "type": "username",
      "value": "prenses",
      "country": "TR",
      "forceToGenderize": true
    }
  ]
};

const response = await fetch("https://api.genderapi.io/api/v2/gender/batch", {
  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.
}

Node.js 22+; fetch integrado. Guarda como example.mjs y ejecuta node example.mjs. Documentación del entorno de ejecución

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("{\"items\":[{\"id\":\"contact-001\",\"type\":\"name\",\"value\":\"Ayşe Yılmaz\",\"country\":\"TR\",\"options\":{\"ai_mode\":\"off\"}},{\"id\":\"contact-002\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-003\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}")

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/batch",
    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.

Python 3.10+; biblioteca estándar. Guarda como example.py y ejecuta python3 example.py. Documentación del entorno de ejecución

PHP
<?php
$apiKey = getenv('GENDERAPI_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set GENDERAPI_API_KEY');
}
$body = json_decode('{"items":[{"id":"contact-001","type":"name","value":"Ayşe Yılmaz","country":"TR","options":{"ai_mode":"off"}},{"id":"contact-002","type":"email","value":"alice.smith@example.com","options":{"ai_mode":"fallback"}},{"id":"contact-003","type":"username","value":"prenses","country":"TR","forceToGenderize":true}]}', true, 512, JSON_THROW_ON_ERROR);

$ch = curl_init('https://api.genderapi.io/api/v2/gender/batch');
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.

PHP 8+ con la extensión cURL. Guarda como example.php y ejecuta php example.php. Documentación del entorno de ejecución

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 = "{\"items\":[{\"id\":\"contact-001\",\"type\":\"name\",\"value\":\"Ayşe Yılmaz\",\"country\":\"TR\",\"options\":{\"ai_mode\":\"off\"}},{\"id\":\"contact-002\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-003\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}";
        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/batch"))
            .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.
    }
}

Java 17+; cliente estándar HTTP. Guarda como GenderApiExample.java y ejecuta java GenderApiExample.java. Documentación del entorno de ejecución

C# / .NET
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/batch");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
request.Content = new StringContent("{\"items\":[{\"id\":\"contact-001\",\"type\":\"name\",\"value\":\"Ayşe Yılmaz\",\"country\":\"TR\",\"options\":{\"ai_mode\":\"off\"}},{\"id\":\"contact-002\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-003\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}", 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.
}

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

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 := "{\"items\":[{\"id\":\"contact-001\",\"type\":\"name\",\"value\":\"Ayşe Yılmaz\",\"country\":\"TR\",\"options\":{\"ai_mode\":\"off\"}},{\"id\":\"contact-002\",\"type\":\"email\",\"value\":\"alice.smith@example.com\",\"options\":{\"ai_mode\":\"fallback\"}},{\"id\":\"contact-003\",\"type\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}]}"
    request, err := http.NewRequest("POST", "https://api.genderapi.io/api/v2/gender/batch", 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)
    }
}

Go 1.22+; biblioteca estándar. Guarda como main.go y ejecuta go run main.go. Documentación del entorno de ejecución