Dokumentacja REST API
Kilka endpointów, jeden format odpowiedzi. Wszystko poniżej działa na żywo z Twoim kontem.
https://namegender.com/api/v1/gender
Zarejestruj się za darmo
Markdown dla asystentów programowania, takich jak Claude Code, Cursor i Copilot. Wklej go do czatu lub przekaż asystentowi link.
Szybki start
Utwórz klucz w panelu, a następnie wyślij pierwsze zapytanie. SDK nie jest wymagany.
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
Każdy endpoint zwraca tę samą strukturę, więc możesz zmieniać dane wejściowe bez zmiany kodu parsowania.
Uwierzytelnianie
Każde żądanie przekazuje klucz API w nagłówku. Domyślnie używaj Authorization: Bearer, a X-Api-Key wtedy, gdy Twój klient HTTP wykorzystuje nagłówek Authorization do czegoś innego. Klucz umieszczony w adresie URL jest odrzucany: adresy URL trafiają do logów proxy, narzędzi analitycznych i historii przeglądarki.
Authorization: Bearer ng_live_xxxxxxxxxxxx
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
X-Api-Key: ng_live_xxxxxxxxxxxx
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
Możesz ograniczyć klucz do określonych adresów IP z poziomu panelu.
Biblioteki klienckie
Cienkie wrappery nad REST API. Wysyłają Twój klucz, budują każde żądanie i zamieniają odpowiedzi z błędem na wyjątki.
npm install namegender
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
npm install -g namegender
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
composer require namegender/namegender
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
pip install namegender-client
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
gem install namegender
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
<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>
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
dotnet add package NameGender --version 0.6.0
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
go get github.com/anpekesen/namegender-go@v0.7.0
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
remotes::install_github('anpekesen/namegender-r', ref = 'v0.7.0')
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
Install-Module NameGender
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
cargo add namegender
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
Nie potrzebujesz żadnej. API to garść prostych endpointów JSON; biblioteka zaoszczędzi Ci popołudnie, nie cały projekt. Jeśli Twojego języka nie ma na liście, dokumentacja REST zawiera przykłady gotowe do skopiowania.
Pokaż wszystkoAsystenci AI (MCP)
Korzystaj z NameGender w Claude, Cursor i każdym innym kliencie obsługującym Model Context Protocol. Zapytaj asystenta o listę imion, a wywoła API za Ciebie i pokaże dowody przy każdej odpowiedzi.
claude mcp add namegender -e NAMEGENDER_API_KEY=ng_live_... -- npx -y namegender-mcp
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
{
"mcpServers": {
"namegender": {
"command": "npx",
"args": [
"-y",
"namegender-mcp"
],
"env": {
"NAMEGENDER_API_KEY": "ng_live_..."
}
}
}
}
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
Dodaj to do pliku konfiguracyjnego MCP klienta i uruchom go ponownie.
Narzędzia
gender_from_name- Płeć na podstawie imienia lub pełnego imienia i nazwiska.
gender_from_email- Odczytuje imię z adresu e-mail; adresy funkcyjne, takie jak info@, zwracają wynik nieznany.
gender_from_username- Odczytuje imię z nazwy użytkownika lub pseudonimu.
gender_bulk- Do 100 wartości w jednym żądaniu, z podsumowaniem wskaźnika dopasowania.
name_countries- Kraje, w których imię jest zarejestrowane. Nie jest to twierdzenie o pochodzeniu.
salutation- Zwrot grzecznościowy na początek listu w języku listu; forma neutralna, gdy płeć nie jest pewna.
name_check- Czy imię i nazwisko wpisane w formularzu wygląda na prawdziwe, z uzasadnieniem. Nigdy nie nazywa imienia ani nazwiska fałszywym.
age_from_name- Wiek medianowy i przedziały wieku osób o danym imieniu w Stanach Zjednoczonych, Francji i Norwegii.
account_status- Pozostałe kredyty i dzisiejszy darmowy limit.
Każde wyszukiwanie zużywa kredyty z konta, do którego należy klucz, dokładnie tak jak bezpośrednie wywołanie API. Dostępny w oficjalnym rejestrze MCP jako io.github.anpekesen/namegender. Pakiet npm · Kod źródłowy
Płeć z imienia
Akceptuje imię lub pełne imię i nazwisko. Tytuły, imiona dodatnie i nazwiska są usuwane przed wyszukiwaniem, więc "Dr. Ayşe Yılmaz" i "Ayşe" dają ten sam wynik.
| Parameter | Typ | Opis |
|---|---|---|
name
wymagane
|
string
|
Imię do klasyfikacji. Imię lub pełne imię i nazwisko. |
country
opcjonalne
|
string
|
Kod kraju ISO 3166-1 alpha-2. Zwiększa dokładność dla imion, których płeć różni się w zależności od regionu, takich jak Andrea (mężczyzna we Włoszech, kobieta w Niemczech). |
locale
opcjonalne
|
string
|
Znacznik języka, np. de-DE lub en_US, na przykład język przeglądarki. Jego region staje się krajem, gdy nie wysłano country. Znacznik bez regionu (en, de) nie ustala kraju. |
ip
opcjonalne
|
string
|
Adres IP użytkownika końcowego. Jego kraj jest używany, gdy nie wysłano ani country, ani locale z regionem. Nie jest zapisywany. IP geolocation by DB-IP (db-ip.com). |
ai_fallback
opcjonalne
|
boolean
|
Jeśli imienia nie ma w naszych danych, poproś model językowy o oszacowanie zamiast zwracać null. Działa dopiero po włączeniu wyszukiwań AI w ustawieniach i kosztuje jeden dodatkowy kredyt. |
best_guess
opcjonalne
|
boolean
|
Zwróć przeważającą płeć, nawet gdy dowody nie osiągają progu pewności. Domyślnie wyłączone: odpowiedź bliska 50/50, która wygląda na pewną, szkodzi bardziej niż 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
}
Płeć z adresu e-mail
Wyodrębnia osobę z części lokalnej adresu, następnie ją klasyfikuje. "ayse.yilmaz84@example.com" rozwiązuje się do Ayşe.
| Parameter | Typ | Opis |
|---|---|---|
email
wymagane
|
string
|
Adres email. Używana jest tylko część przed @. |
country
opcjonalne
|
string
|
Kod kraju ISO 3166-1 alpha-2. Zwiększa dokładność dla imion, których płeć różni się w zależności od regionu, takich jak Andrea (mężczyzna we Włoszech, kobieta w Niemczech). |
locale
opcjonalne
|
string
|
Znacznik języka, np. de-DE lub en_US, na przykład język przeglądarki. Jego region staje się krajem, gdy nie wysłano country. Znacznik bez regionu (en, de) nie ustala kraju. |
ip
opcjonalne
|
string
|
Adres IP użytkownika końcowego. Jego kraj jest używany, gdy nie wysłano ani country, ani locale z regionem. Nie jest zapisywany. IP geolocation by DB-IP (db-ip.com). |
ai_fallback
opcjonalne
|
boolean
|
Jeśli imienia nie ma w naszych danych, poproś model językowy o oszacowanie zamiast zwracać null. Działa dopiero po włączeniu wyszukiwań AI w ustawieniach i kosztuje jeden dodatkowy kredyt. |
best_guess
opcjonalne
|
boolean
|
Zwróć przeważającą płeć, nawet gdy dowody nie osiągają progu pewności. Domyślnie wyłączone: odpowiedź bliska 50/50, która wygląda na pewną, szkodzi bardziej niż null. |
best_guess działa na imieniu odczytanym z adresu, a nie na samym adresie. Gdy nie da się odczytać imienia, nie ma czego wymuszać i gender pozostaje null. Pamiętaj, że wymuszona odpowiedź opiera się tu na wyodrębnieniu, które samo może być błędne.
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"
}
Płeć na podstawie nazwy użytkownika
Obsługuje camelCase, snake_case, cyfry na końcu i znaki @ na początku. "AyseYilmaz84" rozwiązuje się do Ayşe.
| Parameter | Typ | Opis |
|---|---|---|
username
wymagane
|
string
|
Nazwa użytkownika lub pseudonim. Znaki @ na początku są ignorowane. |
country
opcjonalne
|
string
|
Kod kraju ISO 3166-1 alpha-2. Zwiększa dokładność dla imion, których płeć różni się w zależności od regionu, takich jak Andrea (mężczyzna we Włoszech, kobieta w Niemczech). |
locale
opcjonalne
|
string
|
Znacznik języka, np. de-DE lub en_US, na przykład język przeglądarki. Jego region staje się krajem, gdy nie wysłano country. Znacznik bez regionu (en, de) nie ustala kraju. |
ip
opcjonalne
|
string
|
Adres IP użytkownika końcowego. Jego kraj jest używany, gdy nie wysłano ani country, ani locale z regionem. Nie jest zapisywany. IP geolocation by DB-IP (db-ip.com). |
ai_fallback
opcjonalne
|
boolean
|
Jeśli imienia nie ma w naszych danych, poproś model językowy o oszacowanie zamiast zwracać null. Działa dopiero po włączeniu wyszukiwań AI w ustawieniach i kosztuje jeden dodatkowy kredyt. |
best_guess
opcjonalne
|
boolean
|
Zwróć przeważającą płeć, nawet gdy dowody nie osiągają progu pewności. Domyślnie wyłączone: odpowiedź bliska 50/50, która wygląda na pewną, szkodzi bardziej niż 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"
}
Żądanie zbiorcze
Wyślij do 100 imion w jednym żądaniu. Użyj tego zamiast pętli: jedno wywołanie zbiorcze dla 100 imion to jedna podróż w obie strony i jedno zdeduplikowane wyszukiwanie.
| Parameter | Typ | Opis |
|---|---|---|
names
wymagane
|
string[]
|
Tablica imion. Maksymalnie 100 pozycji. |
type
opcjonalne
|
string
|
Co stanowią pozycje: imię, email lub nazwa użytkownika. Domyślnie imię. |
country
opcjonalne
|
string
|
Zastosowane do każdej pozycji w żądaniu. |
locale
opcjonalne
|
string
|
Znacznik języka, którego region staje się krajem dla każdego elementu, gdy nie wysłano country. |
ip
opcjonalne
|
string
|
Adres IP użytkownika końcowego, którego kraj obowiązuje dla każdego elementu, gdy nie wysłano country ani locale z regionem. Nie jest zapisywany. 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" }
]
}
Wyniki są zwracane w tej samej kolejności, w której je wysłałeś. Punkty są pobierane za każde imię, a całe żądanie jest odrzucane przed wykonaniem pracy, jeśli Twoje saldo jest niewystarczające, więc nigdy nie otrzymasz półprzetworzonej partii.
Blok podsumowania pokazuje wskaźnik zgodności na pierwszy rzut oka, abyś mógł zdecydować, czy dane wejściowe wymagają czyszczenia przed przetworzeniem reszty.
Zadania plikowe
Prześlij plik CSV lub XLSX o rozmiarze do 100 MB i do 1 000 000 wierszy i odbierz go z kolumnami płci dodanymi do każdego wiersza. Jeden kredyt za wiersz, pobierany tylko wtedy, gdy zadanie się zakończy.
-
1.
POST /batchesWyślij plik i name_column. Zadanie trafia od razu do kolejki. -
2.
GET /batches/{id}Odczytuj zadanie, aż status będzie completed lub failed. poll_after_seconds mówi, ile czekać między odczytami. -
3.
GET /batches/{id}/resultPobierz wynik. Wraca w formacie, w którym został przesłany.
| Parameter | Typ | Opis |
|---|---|---|
file
wymagane
|
file
|
CSV, TSV lub XLSX z wierszem nagłówka. |
name_column
wymagane
|
string
|
Nagłówek kolumny z imionami, dokładnie tak jak w pliku. Wymagany, chyba że start=false. |
country_column
opcjonalne
|
string
|
Nagłówek kolumny z kodem kraju w każdym wierszu. |
country
opcjonalne
|
string
|
Domyślny kraj dla wierszy bez kraju. |
ai_fallback
opcjonalne
|
boolean
|
Pytać model AI o imiona spoza zbioru danych. Wymaga zgody na AI w Ustawieniach. |
best_guess
opcjonalne
|
boolean
|
Zwracać bardziej prawdopodobną płeć nawet przy słabych dowodach. |
delete_after_download
opcjonalne
|
boolean
|
Wynik można pobrać raz, potem zostaje usunięty. |
start
opcjonalne
|
boolean
|
false: tylko przesłać i sprawdzić. Domyślnie 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 jest wymagane do uruchomienia: odgadnięta kolumna, która okaże się błędna, zużyłaby kredyty na niewłaściwe dane. Wyślij start=false, aby najpierw zobaczyć kolumny, podgląd i koszt, a następnie uruchom zadanie.
Wyślij nagłówek Idempotency-Key. Ponowna próba z tym samym kluczem zwraca pierwsze zadanie zamiast otwierać drugie.
Jednocześnie w kolejce lub w trakcie może być do 3 zadań. Zadanie, które się nie rozpoczęło, można anulować, a kredyt zostanie zwrócony; zadania w trakcie przetwarzania nie można zatrzymać.
Webhooki
Dodaj endpoint w sekcji Webhooki w panelu, a wyślemy do niego podpisane żądanie POST, gdy zadanie plikowe się zakończy lub nie powiedzie, bez potrzeby odpytywania.
| Zdarzenie | Typ | Opis |
|---|---|---|
batch.completed
|
BatchJob
|
Zadanie zakończone. Treść zawiera zadanie dokładnie tak, jak zwraca je GET /batches/{id}. |
batch.failed
|
BatchJob
|
Zadanie zakończyło się błędem i nie zostało obciążone. Rozgałęziaj według error.code. |
credits.low
|
CreditsAlert
|
Przy obecnym tempie kredytów wystarczy na 7 dni lub mniej. Sprawdzane co godzinę; odnowienia subskrypcji są uwzględniane. |
credits.depleted
|
CreditsAlert
|
Saldo jest puste, a żądania są odrzucane kodem 402. Sprawdzane co godzinę. |
webhook.test
|
object
|
Wysyłane tylko przez „Wyślij zdarzenie testowe” w panelu i tylko do tego endpointu. |
| Nagłówek | Typ | Opis |
|---|---|---|
NameGender-Signature
wymagane
|
string
|
t=<sekundy unix>,v1=<hex>. Po odnowieniu sekretu przez 24 godziny występuje drugie v1. |
NameGender-Event-Id
wymagane
|
string
|
Identyfikator zdarzenia. Taki sam przy każdej ponownej próbie tego samego zdarzenia. |
NameGender-Delivery-Attempt
wymagane
|
integer
|
1 przy pierwszej próbie, maksymalnie 8. |
Weryfikuj każde żądanie
v1 to HMAC-SHA256 ze znacznika czasu, kropki i surowej treści, z sekretem Twojego endpointu. Porównuj w stałym czasie, akceptuj żądanie, jeśli pasuje dowolne v1, i odrzucaj znacznik czasu odbiegający o ponad pięć minut od Twojego zegara. Biblioteki klienckie robią to wszystko w jednym wywołaniu.
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" }
}
}
}
- Odpowiedz dowolnym kodem 2xx w ciągu 10 sekund, a pracę wykonaj później.
- Każda inna odpowiedź, także przekierowanie, jest ponawiana do 7 razy w ciągu około 45 godzin. Jeśli endpoint zawodzi przez trzy dni, zostaje wyłączony i dostajesz e-mail.
- Ponowna próba ma ten sam identyfikator, a kolejność nie jest gwarantowana. Usuwaj duplikaty po NameGender-Event-Id, a aktualny stan zadania odczytuj przez GET.
- Odnowienie sekretu w panelu pozostawia stary sekret podpisujący przez 24 godziny, więc zaktualizujesz serwer bez utraty zdarzeń.
- Mogą pojawić się nowe typy zdarzeń. Na typ, którego nie obsługujesz, odpowiedz 2xx i go zignoruj.
Rozkład geograficzny
Zwraca kraje, w których zarejestrowane jest dane imię. Zwracane są dwie listy i celowo nie są łączone: `registrations` zawiera zmierzoną liczbę, porównywalną tylko wśród jedenastu krajów publikujących statystyki imion oparte na liczbach, a `attested_in` oznacza obecność bez przypisanej wagi.
| Parameter | Typ | Opis |
|---|---|---|
name
wymagane
|
string
|
Nazwa do wyszukania. |
limit
opcjonalne
|
integer
|
Ile krajów ze statystykami wymienić w `registrations`. 1–100, domyślnie 25. Udziały nie są przeliczane dla krótszej listy. |
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"]
}
Jeden kredyt na żądanie. `share` jest obliczany względem wszystkich krajów ze statystykami, więc sumuje się do 100 tylko wtedy, gdy `limit` nie skraca listy; `counted_countries` również liczy kraje przed skróceniem. `attested_in` nie zawiera procentów, ponieważ brak statystyk do ich obliczenia.
Zwrot grzecznościowy
Zamienia imię i nazwisko w zwrot grzecznościowy gotowy do listu lub e-maila, w dziesięciu językach: „Sehr geehrte Frau Dr. Müller,“, „Sayın Ahmet Bey,“, „Madame,“, „山田様“. Rozpoznanie płci jest wliczone i kosztuje ten sam jeden kredyt. Każda odpowiedź zawiera wiersz formalny, nieformalny i neutralny oraz części wiersza formalnego.
| Parameter | Typ | Opis |
|---|---|---|
name
wymagane
|
string
|
Pełne imię i nazwisko z tytułami („Dr. Anna Müller“). Wyślij to lub `first_name` i `last_name`. |
first_name, last_name
opcjonalne
|
string
|
Użyj ich zamiast `name`, gdy Twój CRM przechowuje dane w osobnych polach. Nic nie jest analizowane. |
email
opcjonalne
|
string
|
Adres e-mail, używany, gdy nie podano imienia i nazwiska. Nazwa jest odczytywana z części przed @, bez znaków diakrytycznych (Mueller, nie Müller); info@ i inne adresy funkcyjne otrzymują zwrot dla organizacji. |
language
opcjonalne
|
string
|
Język zwrotu: en, en-US, en-GB, de, de-AT, de-CH, fr, es, it, pt, pt-PT, pt-BR, nl, tr, pl, ja. Bez niego: język z `locale`, potem główny język kraju, potem angielski. Nieobsługiwany język to błąd, nigdy ciche przełączenie na angielski. |
country, locale, ip
opcjonalne
|
string
|
Wskazówka kraju dla rozpoznania płci, jak w endpointach płci. Wybiera język tylko wtedy, gdy nie wysłano `language`. |
gender
opcjonalne
|
string
|
`male`, `female` lub `neutral`, jeśli już to wiesz. Zastępuje rozpoznanie; `neutral` zawsze daje formę neutralną. |
min_probability
opcjonalne
|
integer
|
Najniższe prawdopodobieństwo dla zwrotu z płcią, 50–100. Domyślnie 90. |
title
opcjonalne
|
string
|
Tytuł naukowy przechowywany w osobnym polu, np. `Dr.` Używany w zwrotach niemieckich i angielskich. |
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"
}
Błędna płeć jest gorsza niż żadna, więc forma z płcią jest używana tylko wtedy, gdy płeć jest znana z co najmniej `min_probability`, a język ma potrzebną mu część imienia lub nazwiska. W przeciwnym razie `form` ma wartość `neutral`, a `reason` podaje powód. Firmy i adresy funkcyjne dostają `form: organization`. `best_guess` i `ai_fallback` nie mają tu zastosowania.
POST /api/v1/salutation/bulk przyjmuje do 100 nazw w `names`, jeden kredyt za każdą, z tymi samymi opcjami dla każdej nazwy.
Sprawdzanie imienia i nazwiska
Mówi, czy imię i nazwisko wpisane w formularzu rejestracji lub kontaktowym wygląda jak dane prawdziwej osoby, i dlaczego. Wychwytuje przypadkowe stukanie w klawiaturę („asdf qwerty“), wartości zastępcze („Test Test“, „John Doe“, „n/a“), postacie fikcyjne („Mickey Mouse“), wulgaryzmy oraz cyfry, symbole lub adresy e-mail w polu imienia. Jeden kredyt za każde imię i nazwisko.
| Parameter | Typ | Opis |
|---|---|---|
name
wymagane
|
string
|
Imię i nazwisko w postaci wpisanej w formularzu. Wyślij to lub `first_name` i `last_name`. |
first_name, last_name
opcjonalne
|
string
|
Użyj ich zamiast `name`, gdy Twój formularz ma osobne pola. |
country, locale, ip
opcjonalne
|
string
|
Wskazówka kraju, jak w endpointach płci. Pomaga w rozbiorze imienia i nazwiska oraz w wyszukiwaniu w rejestrach. |
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` ma wartość `implausible`, gdy występuje sygnał o wysokiej wadze (wzór z klawiatury, powtórzone litery, wartość zastępcza, wulgaryzm, e-mail lub URL), `suspicious` przy sygnale średnim (postać fikcyjna, cyfry, symbole, nazwa firmy, brak samogłosek, bardzo długie) lub dwóch niskich, a w pozostałych przypadkach `plausible`. `score` przyjmuje wartości od 0 do 100 dla Twojego własnego progu. Imię znalezione w oficjalnych rejestrach urodzeń go podnosi; imię, którego nigdy nie widzieliśmy, samo go nie obniża. Nazwiska są oceniane tylko po ich kształcie: za tym endpointem nie stoi żaden zbiór danych nazwisk.
Przetestowano na 4 610 prawdziwych imionach w dziewięciu pismach, samodzielnie i w parze z nazwiskiem: żadne nie zostało oznaczone jako podejrzane ani nieprawdopodobne. Nazwiska takie jak Null, Test czy Cockburn, dwuliterowe imiona takie jak Ng oraz pojedyncze imiona są celowo pomijane.
POST /api/v1/name-check/bulk przyjmuje do 100 nazw w `names`, jeden kredyt za każdą, z podsumowaniem trzech ocen.
Wiek na podstawie imienia
Ile lat mają żyjące osoby o danym imieniu: wiek medianowy, środkowa połowa (`age_range`) i środkowe 80% (`age_range_80`). Brittany w Stanach Zjednoczonych: mediana 36, połowa między 32 a 38. Jeden kredyt za każde imię.
| Parameter | Typ | Opis |
|---|---|---|
name
wymagane
|
string
|
Imię lub pełne imię i nazwisko; używane jest imię. |
gender
opcjonalne
|
string
|
`male` lub `female`, aby użyć tylko danych tej płci. Mężczyźni o imieniu Leslie są o 16 lat starsi od kobiet o tym imieniu. |
country, locale, ip
opcjonalne
|
string
|
Wskazówka kraju, jak w endpointach płci. Obsługiwane: US, FR i NO. Bez wskazówki używana jest seria Stanów Zjednoczonych, a `country_source` ma wartość `default`. Inny kraj zwraca `reason: country_not_covered` i nic nie kosztuje. |
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
}
Metoda: zarejestrowane urodzenia według imienia, płci i roku, a każdy rok ważony udziałem tej kohorty urodzeń, która wciąż żyje (kohortowe tablice trwania życia SSA). Źródła: urodzenia SSA 1880–2024 (US), INSEE 1900–2025 (Francja), SSB 1945–2025 (Norwegia). `reason` ma wartość `not_found` dla imienia spoza serii i `insufficient_data` poniżej 100 żyjących osób.
Urodzenia za granicą nie trafiają do żadnej serii, więc imiona popularne wśród imigrantów wyglądają na młodsze, niż są. Seria norweska zaczyna się w 1945 roku, więc brakuje osób urodzonych wcześniej. Tablica trwania życia Stanów Zjednoczonych jest używana także dla Francji i Norwegii.
POST /api/v1/age/bulk przyjmuje do 100 imion w `names`, jeden kredyt za każde, w kolejności wysłania.
Saldo
Sprawdź saldo kredytów i to, ile zostało z dzisiejszego darmowego limitu. To wywołanie nie jest płatne.
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
}
Skrypty niełacińskie
Wyślij imię w jego oryginalnym alfabecie, a my połączymy je z danymi referencyjnymi. Bez dodatkowych parametrów: automatycznie rozpoznajemy alfabet i dobieramy odpowiednią strategię.
Pismo arabskie pomija samogłoski krótkie, dlatego محمد transkrybuje się na "mhmd", podczas gdy nasze dane zawierają "muhammed". Dopasowujemy na podstawie wzoru spółgłosek i zachowujemy znak żeński ة, aby خالد (Khalid) i خالدة (Khalida) pozostały oddzielne. Obejmuje również imiona perskie i urdu zapisane alfabetem arabskim.
Konwertowane na Pinyin. Nazwisko pojawia się na początku w języku chińskim, więc 李明 ma nazwisko 李 (Li) i imię 明 (Ming) — usuwamy nazwisko przed wyszukiwaniem. Pojedynczy znak to pełne imię i jest traktowany jako jedno.
Takie samo obsługiwanie nazwiska na początku jak w chińskim, z użyciem powszechnych koreańskich nazwisk.
Hiragana i katakana są odczytywane prawidłowo (ひろし → Hiroshi).
Imiona rosyjskie, ukraińskie, bułgarskie i serbskie transkrybują się bezpośrednio.
Imiona hindi, marathi i nepalskie. Obsługujemy samogłoskę końcową (राहुल → Rahul, nie "Rahula").
Japońskie kanji i chińskie znaki zajmują ten sam zakres Unicode, dlatego nie możemy ich rozróżnić na podstawie samych znaków. Wprowadzenie Han jest odczytywane jako chiński: nazwa kanji, którą już nie posiadamy dokładnie, otrzymuje wymowę mandaryńską, która dla japońskiej nazwy jest zwykle błędna (健太 czytane jako "jian tai", podczas gdy nazwa to Kenta). Nazwy, które posiadamy, pasują dokładnie i są poprawne. Aby mieć pewność, wyślij japońskie nazwy w kana lub alfabecie łacińskim.
Tajski pomija samogłoski jak arabski i potrzebuje własnej warstwy dopasowania. Jeszcze nie zbudowane, zwraca 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" }
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
Gdy nie możemy w ogóle przełożyć skryptu, odpowiedź to gender: null z source: none. Sprawdź pole source: script oznacza, że przepisaliśmy transliterację, db oznacza, że dopasowaliśmy bezpośrednio wysłane znaki. Te dwa niosą różne zaufanie i pokażemy ci, które otrzymałeś.
Pola odpowiedzi
Identyczne we wszystkich endpointach.
| Pole | Typ | Opis |
|---|---|---|
credits_charged
|
integer
|
Ile kredytów pobrano za to wywołanie. |
credits_remaining
|
integer
|
Saldo do wykorzystania po opłaceniu tego wywołania: kupione kredyty plus to, co zostało z dzisiejszego darmowego limitu. |
query
|
string
|
Dane wejściowe dokładnie w takiej postaci, w jakiej je wysłano, przed jakimkolwiek czyszczeniem. |
name
|
string
|
Imię, które faktycznie sprawdziliśmy po usunięciu tytułów i nazwisk. |
first_name
|
string
|
Imię wyodrębnione z danych wejściowych. Zwracane także, gdy gender ma wartość null, bez dodatkowych kosztów. |
middle_name
|
string
|
Kolejne imiona między pierwszym imieniem a nazwiskiem. Inicjały są pomijane. |
last_name
|
string
|
Nazwisko wraz z przedrostkami, np. van lub de la. Dla nazw użytkowników zawsze null. |
name_type
|
string
|
personal, organization (Acme Sp. z o.o.) lub role (info@, obsługa klienta). Organizacje i role nie otrzymują płci. |
gender
|
string
|
male, female, lub null, gdy nie mamy wystarczającej pewności. |
country
|
string
|
Kraj, z którego pochodzą statystyki, lub null dla globalnego agregatu. |
country_source
|
string
|
Skąd pochodzi kraj: country, locale, ip lub null, gdy odpowiedź jest globalna. |
sample_size
|
integer
|
Liczba zarejestrowanych osób, na których opiera się ta odpowiedź. 0 oznacza, że źródło publikuje proporcje lub poświadczenia, a nie liczebność, którą możemy zweryfikować. |
probability
|
integer
|
Pewność co do podanej płci, od 50 do 100. 0, gdy płeć to null. |
took_ms
|
integer
|
Czas, jaki zajęło nam obsłużenie wyszukiwania, w pełnych milisekundach. Nie obejmuje czasu sieci po Twojej stronie. |
Dwa pola, których nie oferują inne usługi
source mówi, skąd pochodzi odpowiedź: z bazy referencyjnej, z dopasowania rozmytego czy z rezerwowego modelu AI. matched_as wskazuje wpis, na który trafiło dopasowanie rozmyte. Razem pozwalają Ci ocenić, na ile ufać jednemu wynikom zamiast przyjmować go na wiarę.
| Pole | Typ | Opis |
|---|---|---|
source
|
string
|
db, script, fuzzy, llm, lub none. |
confidence
|
string
|
wysoka, średnia, niska, niezweryfikowana lub nieznana, na podstawie dostępnych danych. |
matched_as
|
string
|
W przypadku dopasowania rozmytego — wpis z bazy, który się dopasował. W przeciwnym razie null. |
Kody błędów
Kod statusu HTTP informuje, że wywołanie się nie powiodło. Treść JSON podaje następnie przyczynę w error, wyjaśnia ją w message i zawiera request_id do przekazania pomocy technicznej oraz link do odpowiedniego wiersza dokumentacji poniżej. Opieraj logikę na error, nigdy na message: komunikaty są tłumaczone i mogą zostać przeredagowane.
| Kod | HTTP | Znaczenie |
|---|---|---|
missing_key |
401 | Nie przesłano klucza API. Dodaj do żądania nagłówek Authorization: Bearer lub nagłówek X-Api-Key. |
invalid_key |
401 | Ten klucz API jest nieprawidłowy. |
revoked_key |
401 | Ten klucz API został wycofany. |
blocked |
403 | To konto zostało wstrzymane. Skontaktuj się z pomocą techniczną. |
email_not_verified |
403 | Adres e-mail tego konta nie został jeszcze potwierdzony. Otwórz link potwierdzający, który wysłaliśmy, albo poproś o nowy w panelu. |
ip_not_allowed |
403 | Żądania z tego adresu IP nie są dozwolone dla tego klucza. |
proxy_secret_required |
403 | Ten klucz działa wyłącznie przez rynek API, który podpisuje każde żądanie. Użyj klucza wydanego Ci tam. |
forbidden |
403 | Nie masz uprawnień do wykonania tej czynności. |
no_credits |
402 | Skończyły się Ci kredyty. Kup więcej lub czekaj na reset codziennego bezpłatnego limitu. |
missing_input |
400 | Parametr "name" jest wymagany. |
invalid_input |
422 | Parametr "name" jest nieprawidłowy. |
too_many_items |
422 | Maksymalnie 100 elementów można wysłać w jednym żądaniu. |
ai_consent_required |
422 | ai_fallback przesyła nazwę do zewnętrznego dostawcy AI, na co to konto nie wyraziło zgody. Sprawdź pole "ai", aby dowiedzieć się, który to dostawca, a następnie włącz wyszukiwania AI w ustawieniach pulpitu. |
unknown_endpoint |
404 | Pod tą ścieżką nie istnieje endpoint. Sprawdź adres URL w dokumentacji API. |
method_not_allowed |
405 | Ten endpoint nie akceptuje żądań DELETE. |
payload_too_large |
413 | Treść żądania jest zbyt duża. |
rate_limited |
429 | Zbyt wiele żądań. Zwolnij tempo i spróbuj ponownie za chwilę. |
batch_not_found |
404 | Na tym koncie nie ma zadania plikowego o tym identyfikatorze. |
batch_not_startable |
409 | To zadanie zostało już uruchomione lub zamknięte. |
batch_not_finished |
409 | To zadanie jeszcze się nie zakończyło. Sprawdź jego status i pobierz wynik po zakończeniu. |
batch_in_progress |
409 | To zadanie jest przetwarzane i nie można go teraz anulować. Usuń je po zakończeniu. |
result_gone |
410 | To zadanie nie ma wyniku do pobrania. Zakończyło się błędem, zostało anulowane, wygasło lub jego jednorazowy wynik został już pobrany. |
too_many_batches |
429 | Masz już 100 uruchomionych zadań plikowych. Poczekaj, aż jedno się zakończy, zanim uruchomisz kolejne. |
not_ready |
503 | Baza danych imion jest odbudowywana. Spróbuj za chwilę. |
server_error |
500 | Coś poszło nie tak po naszej stronie. Zostaliśmy powiadomieni. |
{
"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"
}
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.
Limity częstotliwości
Normalne użytkowanie nie powoduje osiągnięcia limitu. Limit istnieje po to, aby zatrzymać wyciekły klucz przed nadużyciem. Liczy się na klucz API, a nie na adres IP, dzięki czemu kilka klientów na jednym serwerze nie konsumuje nawzajem swojego limitu.
Obecny limit: 1 200 żądań na minutę na klucz. Potrzebujesz więcej? Skontaktuj się z nami, a podniesiosiemy limit na Twoim koncie.
Każda odpowiedź zawiera standardowe nagłówki X-RateLimit-Limit i X-RateLimit-Remaining.
Spacje i litery spoza alfabetu łacińskiego w żądaniach GET
Imienia takiego jak Ayşe Yılmaz czy 中村 nie da się przesłać w adresie URL w postaci, w jakiej zostało wpisane. Zakoduj wartość procentowo (percent-encoding), gdy wywołujesz GET, albo wyślij ją w treści JSON metodą POST i całkowicie pomiń kodowanie.
Ayşe Yılmaz -> Ay%C5%9Fe%20Y%C4%B1lmaz
محمد -> %D9%85%D8%AD%D9%85%D8%AF
中村 -> %E4%B8%AD%E6%9D%91
Kopiowanie nie powiodło się. Zaznacz i skopiuj tekst.