REST API 참고서
몇 개의 엔드포인트, 하나의 응답 형식. 아래의 모든 내용은 귀하의 계정에 대해 실시간으로 작동합니다.
https://namegender.com/api/v1/gender
무료 가입
Claude Code, Cursor, Copilot 같은 코딩 어시스턴트용 Markdown입니다. 채팅에 붙여 넣거나 어시스턴트에게 링크를 전달하세요.
빠른 시작
대시보드에서 키를 생성한 후 첫 번째 요청을 보냅니다. 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
모든 엔드포인트는 동일한 형식으로 반환되므로, 입력을 전환할 때 파싱 코드를 변경할 필요가 없습니다.
인증
모든 요청은 헤더에 API 키를 담아 보냅니다. 기본적으로 Authorization: Bearer를 사용하고, HTTP 클라이언트가 Authorization 헤더를 다른 용도로 쓰는 경우에는 X-Api-Key를 사용하세요. URL에 넣은 키는 거부됩니다: URL은 프록시 로그, 분석 도구, 브라우저 기록에 복사되기 때문입니다.
Authorization: Bearer ng_live_xxxxxxxxxxxx
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
X-Api-Key: ng_live_xxxxxxxxxxxx
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
대시보드에서 특정 IP 주소로 키를 제한할 수 있습니다.
클라이언트 라이브러리
REST API를 감싸는 얇은 래퍼입니다. API 키를 전송하고, 각 요청을 구성하며, 오류 응답을 예외로 변환합니다.
npm install namegender
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
npm install -g namegender
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
composer require namegender/namegender
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
pip install namegender-client
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
gem install namegender
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
<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>
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
dotnet add package NameGender --version 0.6.0
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
go get github.com/anpekesen/namegender-go@v0.7.0
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
remotes::install_github('anpekesen/namegender-r', ref = 'v0.7.0')
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
Install-Module NameGender
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
cargo add namegender
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
필요하지 않습니다. API는 몇 개의 단순한 JSON 엔드포인트뿐입니다. 라이브러리로 아낄 수 있는 것은 프로젝트가 아니라 오후 한나절입니다. 언어가 나열되어 있지 않다면 REST 참조에 복사-붙여넣기 예제가 있습니다.
모두 보기AI 어시스턴트 (MCP)
Claude, Cursor 및 Model Context Protocol을 지원하는 모든 클라이언트에서 NameGender를 사용하세요. 어시스턴트에게 이름 목록에 대해 물어보면 대신 API를 호출하고, 모든 답변 옆에 근거를 함께 보여 줍니다.
claude mcp add namegender -e NAMEGENDER_API_KEY=ng_live_... -- npx -y namegender-mcp
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
{
"mcpServers": {
"namegender": {
"command": "npx",
"args": [
"-y",
"namegender-mcp"
],
"env": {
"NAMEGENDER_API_KEY": "ng_live_..."
}
}
}
}
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
클라이언트의 MCP 설정 파일에 이 내용을 추가한 후 클라이언트를 다시 시작하세요.
도구
gender_from_name- 이름(성 제외) 또는 전체 이름으로 성별을 판별합니다.
gender_from_email- 이메일 주소에 포함된 이름을 읽습니다. info@ 같은 역할 주소는 알 수 없음을 반환합니다.
gender_from_username- 사용자명 또는 핸들에 포함된 이름을 읽습니다.
gender_bulk- 요청 한 번에 최대 100개 값을 처리하며, 일치율 요약을 제공합니다.
name_countries- 이름이 기록된 국가입니다. 출신에 대한 주장이 아닙니다.
salutation- 편지의 언어로 쓴 편지의 첫 줄입니다. 성별이 확실하지 않으면 중립 호칭을 씁니다.
name_check- 양식에 입력된 이름이 실제 이름처럼 보이는지와 그 이유입니다. 어떤 이름도 가짜라고 부르지 않습니다.
age_from_name- 미국, 프랑스, 노르웨이에서 어떤 이름을 가진 사람들의 나이 중앙값과 나이 범위입니다.
account_status- 남은 크레딧과 오늘의 무료 제공량입니다.
모든 조회는 API를 직접 호출할 때와 똑같이 키를 소유한 계정의 크레딧을 사용합니다. 공식 MCP 레지스트리에 io.github.anpekesen/namegender(으)로 등록되어 있습니다. npm 패키지 · 소스
이름에서 성별
이름 또는 성명을 입력받습니다. 직함, 중간 이름, 성은 조회 전에 제거되므로, "Dr. Ayşe Yılmaz"와 "Ayşe"는 동일한 결과를 반환합니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
name
필수
|
string
|
분류할 이름. 이름 또는 성명. |
country
선택
|
string
|
ISO 3166-1 alpha-2 국가 코드. 지역에 따라 성별이 다른 이름(예: Andrea는 이탈리아에서는 남성, 독일에서는 여성)의 정확도를 향상합니다. |
locale
선택
|
string
|
de-DE나 en_US 같은 언어 태그(예: 브라우저 언어). country를 보내지 않으면 태그의 지역이 국가로 쓰입니다. 지역이 없는 태그(en, de)는 국가를 정하지 않습니다. |
ip
선택
|
string
|
최종 사용자의 IP 주소. country도 지역이 있는 locale도 보내지 않으면 이 주소의 국가가 쓰입니다. 저장되지 않습니다. IP geolocation by DB-IP (db-ip.com). |
ai_fallback
선택
|
boolean
|
이름이 저희 데이터에 없으면 null을 반환하는 대신 언어 모델에 추정을 요청합니다. 설정에서 AI 조회를 켠 후에만 작동하며, 크레딧 1개가 추가로 소비됩니다. |
best_guess
선택
|
boolean
|
근거가 신뢰도 임계값에 미치지 못하더라도 우세한 성별을 반환합니다. 기본적으로 꺼져 있습니다: 확정적으로 보이는 50/50에 가까운 답변은 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
}
이메일에서 성별
주소의 로컬 부분에서 사람을 추출한 후 분류합니다. "ayse.yilmaz84@example.com"은 Ayşe로 확인됩니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
email
필수
|
string
|
이메일 주소. @ 앞의 부분만 사용됩니다. |
country
선택
|
string
|
ISO 3166-1 alpha-2 국가 코드. 지역에 따라 성별이 다른 이름(예: Andrea는 이탈리아에서는 남성, 독일에서는 여성)의 정확도를 향상합니다. |
locale
선택
|
string
|
de-DE나 en_US 같은 언어 태그(예: 브라우저 언어). country를 보내지 않으면 태그의 지역이 국가로 쓰입니다. 지역이 없는 태그(en, de)는 국가를 정하지 않습니다. |
ip
선택
|
string
|
최종 사용자의 IP 주소. country도 지역이 있는 locale도 보내지 않으면 이 주소의 국가가 쓰입니다. 저장되지 않습니다. IP geolocation by DB-IP (db-ip.com). |
ai_fallback
선택
|
boolean
|
이름이 저희 데이터에 없으면 null을 반환하는 대신 언어 모델에 추정을 요청합니다. 설정에서 AI 조회를 켠 후에만 작동하며, 크레딧 1개가 추가로 소비됩니다. |
best_guess
선택
|
boolean
|
근거가 신뢰도 임계값에 미치지 못하더라도 우세한 성별을 반환합니다. 기본적으로 꺼져 있습니다: 확정적으로 보이는 50/50에 가까운 답변은 null보다 더 큰 해를 끼칩니다. |
best_guess는 주소 자체가 아니라 주소에서 읽어낸 이름에 적용됩니다. 이름을 읽어낼 수 없으면 강제할 대상이 없으므로 gender는 null로 유지됩니다. 여기서 강제된 답변은 그 자체로 틀릴 수 있는 추출 결과 위에 놓여 있다는 점을 기억하세요.
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"
}
사용자명에서 성별
camelCase, snake_case, 후행 숫자 및 선행 @ 기호를 처리합니다. "AyseYilmaz84"는 Ayşe로 확인됩니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
username
필수
|
string
|
사용자명 또는 핸들. 선행 @는 무시됩니다. |
country
선택
|
string
|
ISO 3166-1 alpha-2 국가 코드. 지역에 따라 성별이 다른 이름(예: Andrea는 이탈리아에서는 남성, 독일에서는 여성)의 정확도를 향상합니다. |
locale
선택
|
string
|
de-DE나 en_US 같은 언어 태그(예: 브라우저 언어). country를 보내지 않으면 태그의 지역이 국가로 쓰입니다. 지역이 없는 태그(en, de)는 국가를 정하지 않습니다. |
ip
선택
|
string
|
최종 사용자의 IP 주소. country도 지역이 있는 locale도 보내지 않으면 이 주소의 국가가 쓰입니다. 저장되지 않습니다. IP geolocation by DB-IP (db-ip.com). |
ai_fallback
선택
|
boolean
|
이름이 저희 데이터에 없으면 null을 반환하는 대신 언어 모델에 추정을 요청합니다. 설정에서 AI 조회를 켠 후에만 작동하며, 크레딧 1개가 추가로 소비됩니다. |
best_guess
선택
|
boolean
|
근거가 신뢰도 임계값에 미치지 못하더라도 우세한 성별을 반환합니다. 기본적으로 꺼져 있습니다: 확정적으로 보이는 50/50에 가까운 답변은 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"
}
일괄 요청
한 번의 요청으로 최대 100개의 이름을 보냅니다. 루프 대신 이를 사용하세요: 100개 이름의 단일 일괄 호출은 하나의 왕복 및 단일 중복 제거 조회입니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
names
필수
|
string[]
|
이름 배열. 최대 100개 항목. |
type
선택
|
string
|
항목이 무엇인지: 이름, 이메일 또는 사용자명. 기본값은 이름입니다. |
country
선택
|
string
|
요청의 모든 항목에 적용됩니다. |
locale
선택
|
string
|
country를 보내지 않으면 지역이 모든 항목의 국가로 쓰이는 언어 태그. |
ip
선택
|
string
|
country도 지역이 있는 locale도 보내지 않으면 국가가 모든 항목에 쓰이는 최종 사용자 IP 주소. 저장되지 않습니다. 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" }
]
}
결과는 전송한 순서대로 반환됩니다. 크레딧은 이름당 부과되며, 잔액이 부족한 경우 어떤 작업도 실행되기 전에 전체 요청이 거부되므로 절반만 처리된 배치를 받을 수 없습니다.
요약 블록은 일치율을 한눈에 보여주므로, 나머지를 처리하기 전에 입력을 정리해야 하는지 결정할 수 있습니다.
파일 작업
최대 100 MB, 1,000,000행의 CSV 또는 XLSX 파일을 업로드하면 모든 행에 성별 열이 추가된 파일을 돌려받습니다. 행당 1크레딧이며, 작업이 완료된 경우에만 청구됩니다.
-
1.
POST /batches파일과 name_column을 보냅니다. 작업은 즉시 대기열에 들어갑니다. -
2.
GET /batches/{id}status가 completed 또는 failed가 될 때까지 작업을 조회합니다. poll_after_seconds는 조회 사이에 기다릴 시간을 알려 줍니다. -
3.
GET /batches/{id}/result결과를 다운로드합니다. 업로드한 형식 그대로 돌아옵니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
file
필수
|
file
|
머리글 행이 있는 CSV, TSV 또는 XLSX. |
name_column
필수
|
string
|
이름이 들어 있는 열의 머리글(파일에 적힌 그대로). start=false가 아니면 필수입니다. |
country_column
선택
|
string
|
행마다 국가 코드가 들어 있는 열의 머리글. |
country
선택
|
string
|
국가가 없는 행에 사용할 기본 국가. |
ai_fallback
선택
|
boolean
|
데이터 세트에 없는 이름은 AI 모델에 묻습니다. 설정에서 AI 동의가 필요합니다. |
best_guess
선택
|
boolean
|
근거가 약해도 더 가능성 높은 성별을 반환합니다. |
delete_after_download
선택
|
boolean
|
결과는 한 번만 다운로드할 수 있으며 그 후 삭제됩니다. |
start
선택
|
boolean
|
false: 업로드하고 확인만 합니다. 기본값은 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이 필요합니다. 추측한 열이 틀리면 잘못된 데이터에 크레딧을 쓰게 됩니다. 먼저 start=false로 열, 미리 보기, 비용을 확인한 뒤 작업을 시작하세요.
Idempotency-Key 헤더를 보내세요. 같은 키로 다시 시도하면 두 번째 작업을 만들지 않고 첫 번째 작업을 반환합니다.
동시에 대기 중이거나 실행 중인 작업은 최대 3개입니다. 시작되지 않은 작업은 취소할 수 있으며 크레딧이 반환됩니다. 처리 중인 작업은 중지할 수 없습니다.
웹훅
대시보드의 웹훅에서 엔드포인트를 추가하면, 파일 작업이 완료되거나 실패할 때 서명된 POST를 보내 드립니다. 상태를 조회할 필요가 없습니다.
| 이벤트 | 타입 | 설명 |
|---|---|---|
batch.completed
|
BatchJob
|
작업이 끝났습니다. 본문에는 GET /batches/{id}가 반환하는 것과 똑같은 작업이 담깁니다. |
batch.failed
|
BatchJob
|
작업이 실패했으며 요금이 청구되지 않았습니다. error.code로 분기하세요. |
credits.low
|
CreditsAlert
|
현재 속도라면 크레딧이 7일 이내에 소진됩니다. 매시간 확인하며 구독 갱신도 반영합니다. |
credits.depleted
|
CreditsAlert
|
잔액이 비어 요청이 402로 거부되고 있습니다. 매시간 확인합니다. |
webhook.test
|
object
|
대시보드의 "테스트 이벤트 보내기"로만, 해당 엔드포인트에만 전송됩니다. |
| 헤더 | 타입 | 설명 |
|---|---|---|
NameGender-Signature
필수
|
string
|
t=<유닉스 초>,v1=<16진수>. 비밀 키를 교체한 뒤 24시간 동안 두 번째 v1이 함께 옵니다. |
NameGender-Event-Id
필수
|
string
|
이벤트 ID. 같은 이벤트의 재시도마다 동일합니다. |
NameGender-Delivery-Attempt
필수
|
integer
|
첫 시도는 1, 최대 8. |
모든 요청을 검증하세요
v1은 타임스탬프, 점, 원본 본문을 엔드포인트 비밀 키로 HMAC-SHA256한 값입니다. 상수 시간으로 비교하고, 어떤 v1이든 일치하면 요청을 받아들이며, 시계와 5분 넘게 차이 나는 타임스탬프는 거부하세요. 클라이언트 라이브러리는 이 모든 것을 한 번의 호출로 처리합니다.
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" }
}
}
}
- 10초 안에 아무 2xx로 응답하고, 작업은 그다음에 하세요.
- 리디렉션을 포함한 다른 응답은 약 45시간에 걸쳐 최대 7회 재시도됩니다. 엔드포인트가 3일 동안 계속 실패하면 중지되고 이메일로 알려 드립니다.
- 재시도는 같은 이벤트 ID를 가지며 순서는 보장되지 않습니다. NameGender-Event-Id로 중복을 제거하고, 현재 상태가 필요하면 GET으로 작업을 읽으세요.
- 대시보드에서 비밀 키를 교체해도 이전 키가 24시간 동안 함께 서명하므로, 이벤트를 놓치지 않고 서버를 업데이트할 수 있습니다.
- 새 이벤트 유형이 추가될 수 있습니다. 처리하지 않는 유형에는 2xx로 응답하고 무시하세요.
국가 분포
이름이 기록된 국가들을 반환합니다. 두 개의 목록이 반환되며 의도적으로 병합되지 않습니다: `registrations`은 측정된 규모로 집계된 이름 통계를 공개하는 11개 국가 간에만 비교 가능하며, `attested_in`은 가중치 없이 존재 여부를 나타냅니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
name
필수
|
string
|
조회할 이름입니다. |
limit
선택
|
integer
|
`registrations`에 나열할 계산된 국가 수입니다. 1–100, 기본값 25. 목록이 짧아져도 비율은 다시 계산되지 않습니다. |
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"]
}
요청당 1 크레딧. `share`는 통계가 있는 모든 국가를 기준으로 계산되므로 `limit`이 목록을 자르지 않을 때만 합계가 100이 되며, `counted_countries`도 잘리기 전을 기준으로 셉니다. `attested_in`은 계산 근거가 되는 통계가 없어 백분율을 포함하지 않습니다.
호칭
이름을 편지나 이메일에 바로 쓸 수 있는 호칭으로 바꿉니다. 10개 언어 지원: “Sehr geehrte Frau Dr. Müller,”, “Sayın Ahmet Bey,”, “Madame,”, “山田様”. 성별 조회가 포함되며 비용은 동일하게 1 크레딧입니다. 각 응답에는 격식체, 비격식체, 중립 줄과 격식체 줄의 구성 요소가 포함됩니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
name
필수
|
string
|
직함을 포함한 전체 이름(“Dr. Anna Müller”). 이 값 또는 `first_name`과 `last_name`을 보내세요. |
first_name, last_name
선택
|
string
|
CRM이 이름을 별도 필드에 저장하는 경우 `name` 대신 사용하세요. 아무것도 파싱하지 않습니다. |
email
선택
|
string
|
이름을 보내지 않을 때 사용하는 이메일 주소입니다. 이름은 @ 앞부분에서 악센트 없이 읽습니다(Müller가 아니라 Mueller). info@ 같은 역할 주소에는 조직용 호칭이 붙습니다. |
language
선택
|
string
|
호칭의 언어: en, en-US, en-GB, de, de-AT, de-CH, fr, es, it, pt, pt-PT, pt-BR, nl, tr, pl, ja. 없으면 `locale`의 언어, 그다음 국가의 주 언어, 그다음 영어 순입니다. 지원하지 않는 언어는 오류이며, 영어로 조용히 바뀌지 않습니다. |
country, locale, ip
선택
|
string
|
성별 조회를 위한 국가 힌트로, 성별 엔드포인트와 같습니다. `language`를 보내지 않을 때만 언어를 정합니다. |
gender
선택
|
string
|
이미 알고 있다면 `male`, `female` 또는 `neutral`. 조회 결과보다 우선하며, `neutral`은 항상 중립 형태를 줍니다. |
min_probability
선택
|
integer
|
성별 호칭을 쓰기 위한 최소 확률, 50–100. 기본값 90. |
title
선택
|
string
|
별도 필드에 보관하는 학위 직함(예: `Dr.`). 독일어와 영어 호칭에 사용됩니다. |
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"
}
잘못된 성별은 성별이 없는 것보다 나쁘므로, 성별 형태는 성별이 최소 `min_probability`로 확인되고 해당 언어에 필요한 이름 부분이 있을 때만 사용됩니다. 그렇지 않으면 `form`이 `neutral`이 되고 `reason`이 이유를 알려 줍니다. 회사와 역할 주소에는 `form: organization`이 붙습니다. `best_guess`와 `ai_fallback`은 여기에 적용되지 않습니다.
POST /api/v1/salutation/bulk는 `names`에 최대 100개의 이름을 받으며, 이름당 1 크레딧이고 모든 이름에 같은 옵션이 적용됩니다.
이름 확인
가입 양식이나 리드 양식에 입력된 이름이 실제 사람의 이름처럼 보이는지와 그 이유를 알려 줍니다. 키보드를 아무렇게나 두드린 입력(“asdf qwerty”), 자리표시자(“Test Test”, “John Doe”, “n/a”), 가상의 캐릭터(“Mickey Mouse”), 욕설, 이름 필드에 들어간 숫자·기호·이메일 주소를 잡아냅니다. 이름당 1 크레딧입니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
name
필수
|
string
|
양식에 입력된 그대로의 이름. 이 값 또는 `first_name`과 `last_name`을 보내세요. |
first_name, last_name
선택
|
string
|
양식에 필드가 나뉘어 있으면 `name` 대신 사용하세요. |
country, locale, ip
선택
|
string
|
국가 힌트로, 성별 엔드포인트와 같습니다. 이름 분석과 기록 조회에 도움이 됩니다. |
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 }
}
심각도가 높은 신호(키보드 패턴, 반복된 글자, 자리표시자, 욕설, 이메일 또는 URL)가 있으면 `assessment`는 `implausible`, 중간 신호(가상의 캐릭터, 숫자, 기호, 회사명, 모음 없음, 매우 김)가 하나 있거나 낮은 신호가 둘이면 `suspicious`, 그 밖에는 `plausible`입니다. `score`는 0에서 100까지이며 자체 기준값에 사용할 수 있습니다. 공식 출생 기록에서 발견된 이름은 점수를 올리고, 처음 보는 이름이라는 이유만으로는 점수를 내리지 않습니다. 성은 형태로만 판단합니다. 이 엔드포인트 뒤에는 성 데이터셋이 없습니다.
9개 문자 체계의 실제 이름 4,610개로, 단독으로 그리고 성과 함께 테스트했습니다. 의심스럽거나 개연성 없음으로 표시된 이름은 하나도 없었습니다. Null, Test, Cockburn 같은 성, Ng 같은 두 글자 이름, 단일 이름은 의도적으로 문제 삼지 않습니다.
POST /api/v1/name-check/bulk는 `names`에 최대 100개의 이름을 받으며, 이름당 1 크레딧이고 세 가지 판정의 요약이 함께 제공됩니다.
이름으로 나이 추정
어떤 이름을 가진 생존 인구의 나이를 알려 줍니다. 나이 중앙값, 가운데 절반(`age_range`), 가운데 80%(`age_range_80`)입니다. 미국의 Brittany는 중앙값 36세, 절반이 32세에서 38세 사이입니다. 이름당 1 크레딧입니다.
| 매개변수 | 타입 | 설명 |
|---|---|---|
name
필수
|
string
|
이름 또는 전체 이름. 성을 제외한 이름이 사용됩니다. |
gender
선택
|
string
|
해당 성별의 기록만 사용하려면 `male` 또는 `female`. 남성 Leslie는 여성 Leslie보다 16살 많습니다. |
country, locale, ip
선택
|
string
|
국가 힌트로, 성별 엔드포인트와 같습니다. 지원 국가: US, FR, NO. 힌트가 없으면 미국 계열을 사용하며 `country_source`는 `default`입니다. 그 밖의 국가는 `reason: country_not_covered`를 반환하며 비용이 들지 않습니다. |
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
}
방법: 이름, 성별, 연도별 등록 출생 수를 쓰고, 각 연도에 그 출생 코호트 중 아직 생존한 비율로 가중치를 줍니다(SSA 코호트 생명표). 출처: SSA 출생 1880–2024(US), INSEE 1900–2025(프랑스), SSB 1945–2025(노르웨이). 계열에 없는 이름이면 `reason`은 `not_found`, 생존자가 100명 미만이면 `insufficient_data`입니다.
해외 출생은 어느 계열에도 없으므로, 이민자에게 흔한 이름은 실제보다 젊어 보입니다. 노르웨이 계열은 1945년부터 시작하므로 그 이전 출생자는 빠져 있습니다. 프랑스와 노르웨이에도 미국 생명표를 사용합니다.
POST /api/v1/age/bulk는 `names`에 최대 100개의 이름을 받으며, 이름당 1 크레딧이고 보낸 순서대로 반환합니다.
잔액
크레딧 잔액과 오늘 남은 무료 제공량을 확인합니다. 이 호출은 과금되지 않습니다.
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
}
비라틴 문자
이름을 원래 문자로 보내면 참조 데이터와 연결합니다. 추가 매개변수 없음: 문자를 자동 감지하고 적절한 전략을 적용합니다.
아랍 문자는 단모음을 생략하므로 محمد는 "mhmd"로 음차되지만 데이터는 "muhammed"를 포함합니다. 자음 패턴으로 매칭하고 여성형 ة 표시를 유지하여 خالد (Khalid)와 خالدة (Khalida)를 구분합니다. 페르시아어와 우르두어 이름(아랍 문자)도 처리합니다.
핀인으로 변환합니다. 중국식 이름은 성이 앞에 오므로 李明은 성 李 (Li), 이름 明 (Ming)입니다. 조회 전에 성을 제거합니다. 한 글자는 완전한 이름이며 하나로 처리됩니다.
중국식과 동일한 성-이름 순서 처리이며, 일반적인 한국 성씨를 사용합니다.
히라가나와 가타카나를 올바르게 읽습니다 (ひろし → Hiroshi).
러시아어, 우크라이나어, 불가리아어, 세르비아어 이름이 직접 음차됩니다.
힌디어, 마라티어, 네팔어 이름. 묵시적 후행 모음이 처리됩니다 (राहुल → Rahul, "Rahula" 아님).
일본 한자와 중국 문자는 같은 유니코드 범위를 차지하므로 문자만으로는 구별할 수 없습니다. 한자 입력은 중국어로 읽혀집니다. 기존에 정확히 보유하지 않은 한자 이름은 만다린 음독으로 변환되는데, 일본 이름의 경우 대부분 틀립니다(健太는 이름이 켄타(Kenta)일 때 "지안 타이"로 읽힙니다). 기존에 보유한 이름은 정확히 일치하며 올바릅니다. 일본 이름은 가나 또는 로마자로 보내주시면 확실합니다.
태국어는 아랍어처럼 모음을 생략하며 자체 매칭 레이어가 필요합니다. 아직 구현되지 않아 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" }
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
스크립트를 전혀 변환할 수 없을 때는 gender: null과 source: none으로 응답합니다. source 필드를 확인하세요. script는 음차 변환을 수행했다는 뜻이고, db는 전송하신 문자를 직접 일치시켰다는 뜻입니다. 두 방식의 confidence는 다르며, 어느 것을 사용했는지 표시합니다.
응답 필드
모든 엔드포인트에서 동일합니다.
| 필드 | 타입 | 설명 |
|---|---|---|
credits_charged
|
integer
|
이 호출에서 차감된 크레딧 수입니다. |
credits_remaining
|
integer
|
이 호출 비용을 지불한 후 사용할 수 있는 잔액입니다: 구매한 크레딧과 오늘 남은 무료 제공량의 합계입니다. |
query
|
string
|
정제하기 전, 보낸 그대로의 입력값입니다. |
name
|
string
|
호칭과 성을 제거한 후 실제로 조회한 이름입니다. |
first_name
|
string
|
입력에서 분리한 이름. gender가 null이어도 반환되며 추가 크레딧이 차감되지 않습니다. |
middle_name
|
string
|
이름과 성 사이에 있는 다른 이름. 이니셜은 제외됩니다. |
last_name
|
string
|
성. van, de la 같은 접두어를 포함합니다. 한국어·중국어·일본어 표기에서는 앞에 오는 성이 여기에 들어갑니다. 사용자 이름에서는 항상 null입니다. |
name_type
|
string
|
personal, organization(Acme LLC 등) 또는 role(info@, 고객센터 등). 조직과 역할 계정에는 성별을 반환하지 않습니다. |
gender
|
string
|
남성, 여성 또는 신뢰도가 충분하지 않을 때 null입니다. |
country
|
string
|
통계가 나온 국가 또는 전 세계 통계의 경우 null입니다. |
country_source
|
string
|
국가의 출처: country, locale, ip, 또는 전 세계 기준 답변이면 null. |
sample_size
|
integer
|
이 답변의 근거가 된 기록상 인원 수입니다. 0은 소스가 감사 가능한 개수가 아니라 비율이나 존재 기록만 공개한다는 의미입니다. |
probability
|
integer
|
명시된 성별에 대한 신뢰도(50~100). 성별이 null일 때는 0입니다. |
took_ms
|
integer
|
조회를 처리하는 데 걸린 시간(밀리초 단위 정수)입니다. 사용자 측 네트워크 시간은 포함되지 않습니다. |
다른 서비스에서 제공하지 않는 두 가지 필드
source는 답변이 어디에서 나왔는지 알려줍니다: 참조 데이터베이스, 유사 매칭 또는 AI 폴백. matched_as는 유사 매칭이 일치시킨 항목의 이름을 지정합니다. 이 두 필드를 함께 사용하면 단일 결과를 얼마나 신뢰할지 결정할 수 있습니다.
| 필드 | 타입 | 설명 |
|---|---|---|
source
|
string
|
db, script, fuzzy, llm 또는 none입니다. |
confidence
|
string
|
샘플 데이터를 기반으로 높음, 중간, 낮음, 확인되지 않음 또는 알 수 없음. |
matched_as
|
string
|
유사 매칭의 경우 일치한 데이터베이스 항목입니다. 그렇지 않으면 null입니다. |
오류 코드
HTTP 상태 코드로 호출 실패를 알 수 있습니다. JSON 본문은 error에 원인을, message에 설명을 담고, 지원팀에 전달할 request_id와 아래 해당 행으로 연결되는 문서 링크도 제공합니다. 분기는 반드시 error로 하고 message로 하지 마세요: 메시지는 번역되며 문구가 바뀔 수 있습니다.
| 코드 | HTTP | 의미 |
|---|---|---|
missing_key |
401 | API key가 전송되지 않았습니다. 요청에 Authorization: Bearer header 또는 X-Api-Key header를 추가하세요. |
invalid_key |
401 | 이 API key는 유효하지 않습니다. |
revoked_key |
401 | 이 API key는 취소되었습니다. |
blocked |
403 | 이 계정은 정지되었습니다. 지원팀에 문의하세요. |
email_not_verified |
403 | 이 계정의 이메일 주소가 아직 확인되지 않았습니다. 보내드린 확인 링크를 열거나 대시보드에서 새로 요청해 주세요. |
ip_not_allowed |
403 | 이 IP 주소에서의 요청은 이 key에 대해 허용되지 않습니다. |
proxy_secret_required |
403 | 이 키는 모든 요청에 서명하는 API 마켓플레이스를 통해서만 작동합니다. 해당 마켓플레이스에서 발급받은 키를 사용하세요. |
forbidden |
403 | 이 작업을 수행할 권한이 없습니다. |
no_credits |
402 | 크레딧이 부족합니다. 더 구입하거나 일일 무료 할당량이 초기화될 때까지 기다리세요. |
missing_input |
400 | "name" 파라미터는 필수입니다. |
invalid_input |
422 | "name" 파라미터는 유효하지 않습니다. |
too_many_items |
422 | 한 번의 요청에 최대 100개의 항목을 보낼 수 있습니다. |
ai_consent_required |
422 | ai_fallback는 이름을 제3자 AI 제공업체로 전송하며, 이 계정이 이에 동의하지 않았습니다. "ai" 필드에서 해당 제공업체를 확인한 후 대시보드 설정에서 AI 조회를 활성화하세요. |
unknown_endpoint |
404 | 이 경로에는 endpoint가 없습니다. API 문서에서 URL을 확인하세요. |
method_not_allowed |
405 | 이 endpoint는 DELETE 요청을 지원하지 않습니다. |
payload_too_large |
413 | 요청 본문이 너무 큽니다. |
rate_limited |
429 | 요청이 너무 많습니다. 속도를 늦추고 잠시 후 다시 시도하세요. |
batch_not_found |
404 | 이 계정에 해당 ID의 파일 작업이 없습니다. |
batch_not_startable |
409 | 이 작업은 이미 시작되었거나 종료되었습니다. |
batch_not_finished |
409 | 이 작업은 아직 완료되지 않았습니다. 상태를 확인하고 완료되면 결과를 다운로드하세요. |
batch_in_progress |
409 | 이 작업은 처리 중이므로 지금 취소할 수 없습니다. 완료된 후 삭제하세요. |
result_gone |
410 | 이 작업에는 다운로드할 결과가 없습니다. 작업이 실패했거나, 취소되었거나, 만료되었거나, 1회용 결과가 이미 다운로드되었습니다. |
too_many_batches |
429 | 이미 100개의 파일 작업이 실행 중입니다. 새 작업을 시작하기 전에 하나가 완료될 때까지 기다리세요. |
not_ready |
503 | 이름 데이터베이스를 재구축 중입니다. 잠시 후 다시 시도하세요. |
server_error |
500 | 서버에 문제가 발생했습니다. 지원팀에 알렸습니다. |
{
"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"
}
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.
레이트 제한
정상적인 사용은 제한에 도달하지 않습니다. 상한은 유출된 키가 악용되는 것을 방지하기 위해 존재하며, IP가 아닌 API 키당 계산되므로 한 서버의 여러 고객이 서로의 할당량을 소비하지 않습니다.
현재 제한: 키당 분당 1,200 요청입니다. 더 필요하신가요? 문의하시면 계정에서 상향 조정하겠습니다.
모든 응답에는 표준 X-RateLimit-Limit 및 X-RateLimit-Remaining 헤더가 포함됩니다.
GET 요청의 공백과 비라틴 문자
Ayşe Yılmaz나 中村 같은 이름은 입력한 그대로 URL에 담을 수 없습니다. GET으로 호출할 때는 값을 퍼센트 인코딩하거나, POST로 JSON 본문에 담아 보내면 인코딩이 전혀 필요 없습니다.
Ayşe Yılmaz -> Ay%C5%9Fe%20Y%C4%B1lmaz
محمد -> %D9%85%D8%AD%D9%85%D8%AF
中村 -> %E4%B8%AD%E6%9D%91
복사하지 못했습니다. 텍스트를 선택하여 복사하세요.