demografix/demografix

Official PHP client for the Demografix APIs: genderize.io, agify.io, and nationalize.io.

Maintainers

Package info

github.com/DemografixGenderize/demografix-php

pkg:composer/demografix/demografix

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v0.1.0 2026-06-26 09:56 UTC

This package is auto-updated.

Last update: 2026-07-11 20:05:44 UTC


README

Run demographic analysis over names — predicted gender, age, and nationality — from one PHP client. The package covers genderize.io, agify.io, and nationalize.io.

Install

composer require demografix/demografix

Requires PHP 8.2 or later and the cURL extension. No runtime dependencies.

Quickstart

Construct a client, run a batch over a list of names, read the predictions, and read the remaining quota.

use Demografix\Client;

$client = new Client('YOUR_API_KEY');

$batch = $client->genderizeBatch(['peter', 'lois', 'meg', 'chris']);

$split = ['male' => 0, 'female' => 0, 'unknown' => 0];
foreach ($batch->results as $prediction) {
    $split[$prediction->gender ?? 'unknown']++;
}

// $split is the gender distribution of the list: ['male' => 2, 'female' => 2, 'unknown' => 0]
echo $batch->quota->remaining; // 24987

The client reads quota from the response. It is never cached on the client.

Construction

$client = new Client(
    apiKey: 'YOUR_API_KEY', // required
    timeout: 10.0,          // optional, seconds; default 10
);

The hosts and the User-Agent are hardcoded. They are not options. The API key is required: constructing the client with an empty or blank key raises ValidationError. One API key works across all three services.

genderize

Single name returns a result with the prediction fields and a quota.

$result = $client->genderize('peter');
$result->gender;          // "male", "female", or null
$result->probability;     // 1.0
$result->count;           // 1352696
$result->quota->remaining; // 24987

Batch (up to 10 names) returns results in input order plus one quota. Aggregate the predictions into a distribution rather than labeling any one name.

$batch = $client->genderizeBatch(['peter', 'lois', 'meg']);

$female = array_filter($batch->results, fn ($p) => $p->gender === 'female');
$femaleShare = count($female) / count($batch->results); // share of the list predicted female

agify

$result = $client->agify('michael');
$result->age;   // 57 or null
$result->count; // 311558

Batch into an age distribution across a list.

$batch = $client->agifyBatch(['michael', 'matthew', 'jane']);

$ages = array_filter(array_map(fn ($p) => $p->age, $batch->results), fn ($a) => $a !== null);
$mean = $ages === [] ? null : array_sum($ages) / count($ages); // mean predicted age of the list

nationalize

$result = $client->nationalize('nguyen');
$result->country[0]->countryId;    // "VN"
$result->country[0]->probability;  // 0.891132

Batch into a nationality mix across a list.

$batch = $client->nationalizeBatch(['nguyen', 'smith', 'garcia']);

$mix = [];
foreach ($batch->results as $prediction) {
    $top = $prediction->country[0] ?? null;
    if ($top !== null) {
        $mix[$top->countryId] = ($mix[$top->countryId] ?? 0) + 1;
    }
}
// $mix is the top-country breakdown of the list

country_id

genderize and agify accept an optional ISO 3166-1 alpha-2 country_id to scope the prediction. nationalize does not take one. The API echoes the value back uppercase.

$result = $client->genderize('kim', 'US');
$result->countryId; // "US"

$batch = $client->agifyBatch(['kim', 'andrea'], 'US');

Quota

Every result and every raised error carries a Quota read from the response headers.

Field Meaning
limit names allowed in the current window
remaining names left in the current window
reset seconds until the window resets
$batch->quota->limit;
$batch->quota->remaining;
$batch->quota->reset;

Errors

Every error extends Demografix\Exceptions\DemografixException, which carries status, the passthrough message, and a nullable quota.

Exception Status Meaning
AuthError 401 API key missing or invalid
SubscriptionError 402 subscription expired or inactive
ValidationError 422 invalid parameter; also raised client-side when a batch exceeds 10 names
RateLimitError 429 quota exhausted; quota is always populated
TransportError network failure, timeout, or non-JSON body
DemografixException other non-2xx base type

A batch of more than 10 names raises ValidationError before any HTTP call.

RateLimitError reports when the window resets. Read quota->reset to back off.

use Demografix\Exceptions\RateLimitError;

try {
    $batch = $client->agifyBatch($names);
} catch (RateLimitError $e) {
    sleep($e->quota->reset);
    $batch = $client->agifyBatch($names);
}

Methods

Method Returns country_id
genderize(string $name, ?string $countryId = null) GenderizeResult yes
genderizeBatch(array $names, ?string $countryId = null) Batch of GenderizePrediction yes
agify(string $name, ?string $countryId = null) AgifyResult yes
agifyBatch(array $names, ?string $countryId = null) Batch of AgifyPrediction yes
nationalize(string $name) NationalizeResult no
nationalizeBatch(array $names) Batch of NationalizePrediction no

Each single result exposes the prediction fields directly and a quota. Each Batch exposes results and one quota.

API keys

An API key is required. Creating one is free and includes 2,500 requests per month. Generate a key in your dashboard at genderize.io, agify.io, or nationalize.io. One key works across all three services. Full reference: https://genderize.io/documentation/api.

Tests

composer install
composer test

Tests inject a fake Transport, so they run without network access.

License

MIT. See LICENSE.