# 사용자 이름이나 별명으로 성별 추정하기

> GenderAPI.io V2로 사용자 이름을 분석하세요. 일반 이름 일치나 선택적 별명 추정을 사용해 보고, 1크레딧 또는 2크레딧 비용을 이해하고, 알 수 없는 결과를 그대로 유지하세요.

Canonical HTML: https://www.genderapi.io/ko/determine-gender-from-username

Last reviewed: 2026-09-29

## 이름 신호와 별명의 의미는 다릅니다

핸들이나 별명에는 type: username을 사용하세요. 맨 앞의 @ 기호는 선택 사항이며 데이터셋 일치에서는 제거됩니다. 후보 추출에서는 구분 기호와 숫자를 처리하고, 제한된 범위에서 부분 문자열도 시도할 수 있습니다. 별명 모드는 토큰 일치는 유지하지만 이러한 부분 문자열 후보는 추가하지 않습니다. 선택된 저장 레코드는 사용할 수 있는 후보 중 합계가 가장 큰 레코드이며, 계정 소유자의 실제 이름을 증명하지 않습니다.

일반 AI 폴백은 알아볼 수 있는 이름을 찾습니다. forceToGenderize를 사용하면 실제 이름을 추출할 수 없을 때에도 개인 별명을 바탕으로 한 연관성을 추정할 수 있습니다. 두 방식 모두 unknown을 반환할 수 있으며, 브랜드, 캐릭터, 공유 계정은 한 사람을 나타내지 않을 수 있습니다.

| 입력 예시 | 접근 방식 | 확인할 사항 |
| --- | --- | --- |
| `@alice.smith` | 데이터셋을 먼저 조회하는 일반 fallback으로 시작합니다. | 선택된 이름과 일치 방법을 확인하세요. 첫 토큰이 선택되었다고 가정하지 마세요. |
| `robert89` | 후보를 추출할 때 숫자가 제거될 수 있습니다. | 일치한 이름은 연관성일 뿐 확인된 신원이 아닙니다. |
| `prenses` | 결과가 없을 때 별명을 바탕으로 AI 추정을 시도하려면 forceToGenderize를 활성화합니다. | name이 null이어도 gender는 null이 아닐 수 있습니다. AI 점수는 model_reported입니다. |
| `team_support` | 역할 계정이나 공유 계정은 개인의 계정이 아닐 수 있다고 보고 처리합니다. | unknown을 유지하고 공유 계정에 개인의 신원을 부여하지 마세요. |

## 연동에서 별명 추정 사용해 보기

이 요청은 별명 추정을 사용하도록 설정합니다. 데이터셋을 먼저 확인하고, 성별이 반환되지 않으면 AI가 별칭의 의미를 사용할 수 있습니다. 일반 조회에는 forceToGenderize를 생략하세요. 이 경우에도 단일 요청은 기본적으로 일반 폴백을 사용합니다.

이 예시에서는 국가 컨텍스트로 TR을 지정합니다. 애플리케이션의 관련 컨텍스트를 사용하고 data.match.scope를 확인하세요. 입력한 국가가 국가별 레코드를 보장하지는 않으며, 국적이나 거주지를 나타내지도 않습니다.

이 예시는 서버에서 실행하세요. 프로세스 환경 변수 GENDERAPI_API_KEY에 기존 API 키를 설정하세요. 인식되지 않는 키는 IP 체험으로 전환될 수 있으므로 meta.access.mode가 api_key인지 확인하세요.

재시도를 포함해 모든 추정 요청은 새로 과금되는 작업입니다. 이 예시는 자동으로 재시도하지 않습니다. 다른 요청을 보내기 전에 과금 상태를 확인하세요.

HTTP 4xx 및 5xx JSON 응답에서는 오류 본문을 그대로 출력하고 0이 아닌 종료 코드를 반환합니다. 재시도하기 전에 code, action과 meta.usage.billing_status를 확인하세요.

**cURL**

POSIX 셸의 cURL 7.76+. 터미널에서 실행하세요.

```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": "username",
  "value": "prenses",
  "country": "TR",
  "forceToGenderize": true
}'
```

**JavaScript / Node.js**

Node.js 22+, 내장 fetch. example.mjs로 저장하고 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": "username",
  "value": "prenses",
  "country": "TR",
  "forceToGenderize": true
};

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+, 표준 라이브러리. example.py로 저장하고 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\":\"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",
    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+, cURL 확장. example.php로 저장하고 php example.php를 실행하세요.

```php
<?php
$apiKey = getenv('GENDERAPI_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set GENDERAPI_API_KEY');
}
$body = json_decode('{"type":"username","value":"prenses","country":"TR","forceToGenderize":true}', 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+, 표준 HTTP 클라이언트. GenderApiExample.java로 저장하고 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\":\"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"))
            .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**

.NET 8+ 콘솔 애플리케이션. 콘솔 프로젝트의 Program.cs로 사용한 다음 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\":\"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.
}
```

**Go**

Go 1.22+, 표준 라이브러리. main.go로 저장하고 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\":\"username\",\"value\":\"prenses\",\"country\":\"TR\",\"forceToGenderize\":true}"
    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)
    }
}
```

- [사용자 이름용 V2 전체 참조](https://www.genderapi.io/ko/docs/v2/gender-from-username)

## 결과와 근거를 함께 보관하기

추정된 연관성은 본인이 밝힌 성별이 아닙니다. 원래 입력값, 반환된 근거, 본인이 제공한 정보는 서로 구분해 보관하세요. 알 수 없는 결과도 유효한 결과이므로 애플리케이션에서 추측한 범주로 바꾸지 마세요.

| 필드 | 사용 방법 |
| --- | --- |
| `data.gender / data.result_status` | male 또는 female은 identified일 때만 사용하세요. 결과가 알 수 없음이면 원래의 JSON null을 그대로 유지하세요. |
| `data.name / data.match` | 반환된 이름과 선택된 후보를 확인하세요. 부분 문자열이 일치했다고 해서 입력값이 그 이름을 가진 사람의 것이라는 증거가 되지는 않습니다. |
| `data.confidence / data.confidence_kind` | 신뢰도는 0~1 척도의 값 또는 null입니다. observed_frequency는 저장된 건수에서 나오고, model_reported는 AI 점수입니다. 임계값은 종류별로 따로 평가하세요. |
| `data.source / data.sample_count` | dataset, ai, none을 구분하세요. AI 결과에는 저장된 표본 수가 없습니다. 표본 수는 측정된 정확도가 아닙니다. |
| `meta.access.mode` | 계정 연동에서는 api_key인지 확인하세요. 키가 없거나 인식되지 않으면 대신 공유 IP 체험이 사용될 수 있습니다. |
| `meta.usage` | charged_credits와 billing_status를 확인하세요. 성공한 알 수 없는 결과도 과금됩니다. 응답을 받지 못했다고 해서 요청이 무료였다는 뜻은 아닙니다. |

- [응답 필드와 알 수 없는 결과](https://www.genderapi.io/ko/docs/v2/responses)
- [정확도와 신뢰도 설명](https://www.genderapi.io/ko/accuracy-methodology)
- [데이터 출처와 날짜가 명시된 데이터셋 개요](https://www.genderapi.io/ko/data-provenance)

## AI를 사용할 시점 선택하기

forceToGenderize는 이름, 이메일 주소, 사용자 이름에 선택적으로 사용할 수 있습니다. 이 옵션을 켜면 ai_mode를 생략하거나 fallback을 사용하세요. off와 always는 함께 쓸 수 없으며 422를 반환합니다. 최종 차감으로 잔액이 0 아래로 내려가더라도 시작 잔액이 0보다 크면 요청을 시작할 수 있습니다.

별명 모드는 name: null과 함께 성별을 반환할 수 있으며, 알 수 없는 결과를 반환할 수도 있습니다. 일반 AI 폴백도 별명 추정도 정확하거나 null이 아닌 답을 보장하지 않습니다.

| 요청 옵션 | 동작 | 성공한 조회의 크레딧 |
| --- | --- | --- |
| options.ai_mode: off | 데이터셋만 사용합니다. | 1(알 수 없는 결과 포함) |
| options.ai_mode: fallback | 먼저 데이터셋을 조회하고, 성별이 반환되지 않으면 일반 AI를 사용합니다. 단일 요청의 기본값입니다. | 총 1(AI 폴백 포함) |
| options.ai_mode: always | AI에 직접 요청합니다. | 2 |
| forceToGenderize: true | 먼저 데이터셋을 조회한 다음, 실제 이름이 없어도 AI가 개인의 별명이나 별칭을 해석할 수 있게 합니다. | 데이터셋에서 결과를 얻으면 1, AI를 사용하면 총 2 |

- [AI 옵션과 별명 추정](https://www.genderapi.io/ko/docs/v2/ai-options)
- [크레딧과 사용량](https://www.genderapi.io/ko/docs/v2/credits-and-usage)

## 목록을 처리할 때 사용자 이름마다 결과 유지하기

사용자 이름 목록이나 이름, 이메일 주소, 사용자 이름이 섞인 목록에는 POST /api/v2/gender/batch를 사용하세요. 최대 항목 수는 API 키 사용 시 50개, IP 체험에서는 10개입니다. 각 항목에는 국가와 AI 옵션을 따로 지정하며, 선택적으로 지정하는 ID는 일괄 요청 안에서 고유해야 합니다.

일괄 요청의 기본값은 데이터셋 전용입니다. 일반 AI를 사용하려면 항목별로 fallback을 활성화하고, 별명 추정에는 항목별로 forceToGenderize를 설정하세요. 모든 결과에서 data 또는 error를 확인하고, id나 index로 원래 행과의 연결을 유지하세요. 성공한 알 수 없는 항목도 과금됩니다.

- [일괄 요청 만들기와 부분 실패 처리](https://www.genderapi.io/ko/docs/v2/batch)
- [오류, 받지 못한 응답과 재시도](https://www.genderapi.io/ko/docs/v2/errors-and-retries)

## 보내는 데이터 이해하기

실시간 데모는 사용자가 직접 제출할 때만 입력한 값을 GenderAPI.io로 보냅니다. AI가 사용되면 제출한 type, value와 국가 컨텍스트가 추정용으로 설정된 서비스에 전송됩니다. 데이터셋만으로 추정하려면 연동에서 forceToGenderize 없이 options.ai_mode: off를 사용하세요.

개인정보 처리방침, 데이터 처리 계약, 하위 처리자 목록에 공개된 처리 조건이 설명되어 있습니다. 결과는 추정된 연관성이므로 본인이 제공한 정보를 우선하세요. 개인에게 중대한 영향을 미치는 결정의 근거로 사용하지 마세요.

- [개인정보 처리방침](https://www.genderapi.io/ko/privacy-policy)
- [데이터 처리 계약](https://www.genderapi.io/ko/data-processing-agreement)
- [하위 처리자](https://www.genderapi.io/ko/subprocessors)

## 사용자 이름에 실제 이름이 들어 있어야 하나요?

일반 AI 추정에는 사용할 수 있는 이름이 필요합니다. forceToGenderize를 사용하면 데이터셋 조회에서 결과가 없을 때 API가 별명을 바탕으로 한 연관성도 시도할 수 있습니다. 이 모드는 실제 이름이 필요하지 않으며 name: null을 반환할 수 있습니다.

## forceToGenderize를 사용하면 성별이 반드시 반환되나요?

아니요. 별명 추정을 허용할 뿐이며 최종 결과는 여전히 알 수 없음일 수 있습니다. 원래의 JSON null을 유지하고 result_status와 reason을 확인하세요.

## API가 소셜 미디어 프로필을 확인하나요?

이 엔드포인트는 제출한 값을 분석합니다. 계정 소유자를 확인하기 위해 계정의 프로필, 게시물, 사진을 가져오지 않습니다.

## 이름이나 이메일 주소에도 forceToGenderize를 사용할 수 있나요?

예. name, email, username 입력에 모두 선택적으로 사용할 수 있습니다. 먼저 데이터셋을 사용하고, 결과가 없으면 별명을 해석하는 AI를 사용합니다. 데이터셋에서 결과를 얻으면 1크레딧, AI를 사용하면 총 2크레딧입니다.
