# Use GenderAPI.io V2 with Python

> Call GenderAPI.io V2 from Python with a standard-library example. Send names, emails and usernames, process mixed batches and read data/meta response fields.

Canonical HTML: https://www.genderapi.io/integrations/python

Last reviewed: 2026-09-27

## Runtime and example download

Python 3.10+. Downloadable HTTP integration example; not a separately published SDK.

- [Download the example](https://www.genderapi.io/examples/v2/genderapi_v2.py)

## Set up a server-side Python project

This guide calls the GenderAPI.io V2 endpoint https://api.genderapi.io/api/v2/gender with a Bearer API key. Use Python 3.10 or later and download genderapi_v2.py into your project. The example uses urllib.request and json from Python’s standard library; no pip package is required.

Set GENDERAPI_API_KEY in your server environment. The placeholder below is not a working key. Keep real credentials out of committed files, notebooks you share and client-side applications. Importing the module or running it without a demo flag does not send a request.

**Configure your Python environment**

```bash
python3 --version
export GENDERAPI_API_KEY="YOUR_API_KEY"
```

- [Download genderapi_v2.py](https://www.genderapi.io/examples/v2/genderapi_v2.py)
- [Verify your key with the free usage endpoint](https://www.genderapi.io/docs/v2/authentication#environment-setup)

## Make one explicit dataset-only request

Save the following as single.py beside the downloaded file and run python3 single.py. The helper sends type: name, value: Alice and options.ai_mode: off as JSON. Read the estimate from data and the request and billing details from meta. A successful call uses 1 credit, including an unknown result; the sample name does not guarantee a prediction.

make_item accepts name, email or username and requires an explicit AI mode. Add country only when you have relevant context. The helper requires a 24-character hexadecimal API key before sending. This validates format, not whether the key exists. It also rejects successful IP-trial responses as an access mismatch; that check occurs after the response and cannot undo a trial charge.

**Single lookup in Python**

```python
from genderapi_v2 import GenderAPIError, make_item, predict

try:
    response = predict(make_item("name", "Alice", ai_mode="off"))
except GenderAPIError as error:
    # Record a reference; do not log the whole error response.
    print("Request failed:", error.request_id)
    raise SystemExit(1)
else:
    result = response["data"]
    print(result["result_status"], result["gender"])
    print(result["confidence"], result["confidence_kind"])
    print(response["meta"]["usage"])
```

- [All single-request fields](https://www.genderapi.io/docs/v2/request-parameters)

## Keep the result and its evidence together

An inferred association is not a person's self-declared gender. Keep the original input, the returned evidence and any information provided by the person separate. An unknown result is a valid outcome; it should not become a guessed category in your application.

| Field | How to use it |
| --- | --- |
| `data.gender / data.result_status` | Use male or female only when identified. Preserve native JSON null when the result is unknown. |
| `data.name / data.match` | Inspect the returned name and selected candidate. A substring match does not prove that the input belongs to someone with that given name. |
| `data.confidence / data.confidence_kind` | Confidence is on a 0–1 scale or null. observed_frequency comes from stored counts; model_reported is an AI score. Evaluate thresholds separately for each kind. |
| `data.source / data.sample_count` | Distinguish dataset, ai and none. AI results have no stored sample count. A sample count is not a measured accuracy score. |
| `meta.access.mode` | Confirm api_key for an account integration. Missing or unrecognized keys can instead use the shared IP trial. |
| `meta.usage` | Read charged_credits and billing_status. A successful unknown is billable. A lost response does not establish that the request was free. |

- [Response fields and unknown outcomes](https://www.genderapi.io/docs/v2/responses)
- [Accuracy and confidence explained](https://www.genderapi.io/accuracy-methodology)
- [Data sources and the dated database profile](https://www.genderapi.io/data-provenance)

## Process a mixed batch and keep row IDs

GenderAPI.io V2 uses POST https://api.genderapi.io/api/v2/gender/batch for mixed batches: up to 50 items with an account key or 10 for the IP trial. These examples require an account key. Give every item a stable, unique id and explicit AI mode. A batch can mix names, emails and usernames, with optional country context on each item.

Read every item in data and the summary in meta.summary. HTTP 200 can include item errors; an all-failed batch can be a top-level Problem response containing the results. Successful unknowns count as succeeded. The original index and id let you attach an outcome to the correct source row.

For larger jobs, divide input into groups of at most 50 and submit sequentially at first. Save each response and its usage before advancing. Stop on transport, account or unconfirmed-billing failures and reconcile the current group. Add concurrency only after checking your account limits; a batch-size limit is not a throughput guarantee.

**Batch lookup in Python**

```python
from genderapi_v2 import GenderAPIError, make_item, predict_batch

items = [
    make_item("name", "Alice", ai_mode="off", item_id="row-1"),
    make_item("email", "alex@example.com", ai_mode="off", item_id="row-2"),
    make_item("username", "sample_handle", ai_mode="off", item_id="row-3"),
]
try:
    response = predict_batch(items)
except GenderAPIError as error:
    # Retained error.response can include batch results and billing.
    print("Batch needs review:", error.request_id)
    raise SystemExit(1)
else:
    for item in response["data"]:
        if "error" in item:
            print(item["id"], "failed", item["error"]["code"])
        else:
            result = item["data"]
            print(item["id"], result["result_status"], result["gender"])
    print(response["meta"]["summary"])
    print(response["meta"]["usage"])
    if response["meta"]["summary"]["failed"]:
        raise SystemExit(2)
```

- [Batch input, results and billing](https://www.genderapi.io/docs/v2/batch)

## Choose when to use AI

forceToGenderize is optional for names, email addresses and usernames. With it enabled, omit ai_mode or use fallback; off and always conflict with it and return 422. A positive starting balance is enough to begin a request even if its final charge takes the balance below zero.

Nickname mode can return a gender with name: null. It can also return an unknown result. Neither ordinary fallback nor nickname inference guarantees a correct or non-null answer.

This Python helper always requires ai_mode. To allow nickname inference, use make_item('username', 'prenses', ai_mode='fallback', force_to_genderize=True). The helper maps force_to_genderize to the JSON field forceToGenderize.

| Request option | Behavior | Credits for a successful lookup |
| --- | --- | --- |
| options.ai_mode: off | Use the dataset only. | 1, including an unknown result |
| options.ai_mode: fallback | Try the dataset, then ordinary AI when no gender is returned. This is the single-request default. | 1 total, including AI fallback |
| options.ai_mode: always | Ask AI directly. | 2 |
| forceToGenderize: true | Try the dataset first, then allow AI to interpret a personal nickname or alias even without a real given name. | 1 for a resolved dataset result; 2 total if AI is used |

- [AI options and nickname inference](https://www.genderapi.io/docs/v2/ai-options)
- [Credits and usage](https://www.genderapi.io/docs/v2/credits-and-usage)

## Decide what to do after a failure

The examples send each operation once. They do not retry automatically: a new submission is a new billable operation. A timeout or connection failure means the client did not receive a complete response; it does not prove that the server stopped or that no credits were charged.

Keep the returned request ID and billing state with your job record. The error object retains the response for controlled inspection, but it can contain the original input; do not put the whole object, response or API key into routine logs.

| Outcome | Application decision |
| --- | --- |
| Successful unknown | Keep null, reason and usage. This is a completed billable result, not a failed row to retry automatically. |
| 422 validation error | Correct the input identified by the Problem Details fields before making a new request. |
| 401 / 403 | Review account access or available credits. Repeatedly submitting the same request will not resolve the underlying issue. |
| 429 | Respect Retry-After when present. Confirm the error and billing state, then schedule a deliberate later attempt. |
| Network error, timeout or unreadable response | Record that the result and charge are not confirmed. Reconcile before resubmitting; the client cannot cancel completed server work. |
| billing_status: unconfirmed | charged_credits and remaining_credits can be null. Contact support with request_id before retrying; do not replace null with zero. |
| Some batch items failed | Store completed items first. Review failed items and their billing; resubmit only the eligible failures, not the whole batch. |

- [Problem Details and retry decisions](https://www.genderapi.io/docs/v2/errors-and-retries)
- [Credits and billing confirmation](https://www.genderapi.io/docs/v2/credits-and-usage)

## Understand this example’s transport behavior

The urllib timeout is 10 seconds for blocking socket operations, not a guaranteed total wall-clock deadline for the entire request. The example disables HTTP redirects, parses successful JSON and retains HTTP Problem responses. It never retries automatically.

Local tests use synthetic transport fixtures for success, unknowns, partial batches, account access and failures. They verify the example’s control flow; they do not measure live API availability, inference accuracy or production latency.

**Optional explicit Python demos**

```bash
python3 genderapi_v2.py --demo single
# Run separately to submit another billable sample batch:
python3 genderapi_v2.py --demo batch
```

- [Python urllib.request reference](https://docs.python.org/3/library/urllib.request.html)
- [Python HTTPError reference](https://docs.python.org/3/library/urllib.error.html)

## Why does Python print None instead of null?

Python’s JSON decoder maps JSON null to None. Preserve that unknown value. Do not turn it into a default gender or zero confidence when storing or exporting a result.

## Will an unknown result use credits?

Yes. A successful ordinary lookup costs 1 credit even when gender is null. Ordinary fallback AI is included in that credit. Always-AI costs 2; forceToGenderize costs 1 for a resolved dataset result or 2 when AI runs.

## Does this example retry a failed request?

No. Each new request is an independent operation. Inspect the error, per-item results and billing state before deciding whether to resubmit. A missing response does not establish that the previous attempt was free.

## Is this a package I need to install?

No. Download the example directly from this GenderAPI.io guide. It has no third-party runtime dependency and is not a separately published SDK. Review and adapt it for your application; the GenderAPI.io V2 documentation remains the API contract.

## Reference documentation

- [GenderAPI.io V2 authentication](https://www.genderapi.io/docs/v2/authentication)
- [V2 response fields](https://www.genderapi.io/docs/v2/responses)
- [Batch results and limits](https://www.genderapi.io/docs/v2/batch)
- [Error and retry reference](https://www.genderapi.io/docs/v2/errors-and-retries)
