TypeScript · Gender prediction
Batch gender prediction in TypeScript
When you have a list of contacts, the batch endpoint accepts 1 to 50 items in one request and returns results in the same order. Each item has an id you choose, a type of name, email or username, a value, and an optional country for names. In TypeScript you can model the item result as a type with an optional data prediction or an optional error, then branch on which one is present.
A 200 batch response can still contain item-level errors, such as a provider failure on one entry, while the rest succeed. The example logs those by id instead of resending the whole batch. Successful items carry the usual prediction, so the code narrows on result_status and reads reason when the answer is unknown. Note that batch items default to ai_mode off, so they use the dataset only.
Steps
- 1
Install the dev dependencies and export FINOWL_API_KEY.
- 2
Build up to 50 BatchItem objects with unique ids, adding country to name items when known.
- 3
Send them with predictBatch and match results back to your records by id or index.
- 4
Store unknown results and item errors separately so you can review or retry individual items later.
npm install --save-dev typescript tsx @types/node// gender-batch.ts (run with: npx tsx gender-batch.ts)
type BatchItem = { id: string; type: "name" | "email" | "username"; value: string; country?: string };
type Prediction = {
result_status: "identified" | "unknown";
gender: string | null;
confidence: number | null;
source: string;
country: string | null;
reason: "not_found" | "no_name_candidate" | "ambiguous" | "insufficient_evidence" | null;
};
type BatchResult = {
index: number;
id: string;
charged_credits: number;
data?: Prediction;
error?: { code: string; status: number };
};
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
async function predictBatch(items: BatchItem[]): Promise<BatchResult[]> {
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch("https://api.finowl.co/v1/gender/batch", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.FINOWL_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ items }),
signal: AbortSignal.timeout(30_000),
});
if (res.ok) return ((await res.json()) as { data: BatchResult[] }).data;
const code = ((await res.json().catch(() => ({}))) as { error?: { code?: string } }).error?.code ?? "unknown_error";
if (res.status === 400) throw new Error("Batch rejected, nothing was charged (" + code + ")");
if (res.status === 401) throw new Error("Unauthorized: check FINOWL_API_KEY");
if (res.status === 429 && code === "rate_limited") {
await sleep((Number(res.headers.get("retry-after")) || 1) * 1000);
continue;
}
throw new Error("Finowl error " + res.status + ": " + code);
}
throw new Error("Batch still rate limited");
}
async function main(): Promise<void> {
const results = await predictBatch([
{ id: "c1", type: "name", value: "Jean", country: "FR" },
{ id: "c2", type: "name", value: "Jean", country: "US" },
{ id: "c3", type: "email", value: "li.wei@example.com" },
]);
for (const item of results) {
if (item.error || !item.data) {
console.warn(item.id + ": failed with " + (item.error?.code ?? "no data"));
continue;
}
const p = item.data;
if (p.result_status === "unknown") {
console.log(item.id + ": unknown (" + p.reason + ")");
} else {
console.log(item.id + ": " + p.gender + " confidence=" + p.confidence + " country=" + p.country);
}
}
}
main().catch((err: unknown) => {
console.error(err instanceof Error ? err.message : err);
process.exitCode = 1;
});IN PRODUCTION
Production tips
Never resend a whole batch because one item failed. Retry only the failed ids in a new request, since the successful items were already charged.
Validation is all-or-nothing: one bad item, such as a duplicate id or an id longer than 64 characters, rejects the full batch with a 400 and no credits are spent.
Use charged_credits on each result to reconcile spend in your own records, especially when mixing name, email and username items in a single import job.
Each lookup costs 1 credit (3 when it requests AI), with 100 free credits every month. See pricing and error codes.
A FEW GOOD QUESTIONS
Common questions
Related guides
- Check email breaches in TypeScript with typed results
- Check breached passwords in TypeScript
- Predict gender from names in Python
- Predict gender from a name in Node.js
- Predict gender from names in Go with net/http
- Predict gender from names in Java 17
- Gender analytics from names for fintech audiences
- Gender insights from names for e-commerce analytics
- Gender estimates for SaaS user research and analytics
Batch gender prediction in TypeScript
Grab an API key, paste the example and run it. 100 free credits every month.