# AI Face Age Estimator (`faceanalysis2/face-age-estimator`) Actor

Face-analysis API to predict age, attractiveness score (with gender) or a 478-point 3D face mesh with head pose from image URLs, one analysis per run. Includes face bounding box and crop. Get fast JSON results via a dedicated face-analysis API.

- **URL**: https://apify.com/faceanalysis2/face-age-estimator.md
- **Developed by:** [DataDolphin](https://apify.com/faceanalysis2) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## AI Face Age Estimator

Estimate the **apparent age** of a face in any image. Instead of age, a run can also return an **attractiveness score with gender** or a **478-point 3D face mesh with head pose** (yaw, pitch, roll). Age and attractiveness results can include the **face bounding box** and a **cropped face image**.

The Actor calls our own face-analysis API directly, running the same age-estimation model we use in production. It does not scrape websites, so results are fast, structured and consistent.

### What can you use it for?

- Age estimation for user-generated photos, profile pictures, or research datasets
- Enriching image catalogs with age, gender and attractiveness metadata
- Face alignment, AR and avatar pipelines that need MediaPipe-compatible landmarks
- Checking head pose (frontal vs. turned) before downstream processing

### How to use

1. Add one or more public image URLs to **Image URLs**.
2. Pick **one analysis**: Age estimation, Attractiveness score (+ gender) or Face mesh.
3. Click **Start**. Results appear in the **Output** tab and can be exported as JSON, CSV, Excel or via API.

Each run performs **exactly one analysis**. To get both age and attractiveness for the same images, start one run with `age` and another run with `attractiveness`.

Only the primary (largest) face in each image is analyzed.

### Pricing

This Actor uses **pay-per-event** pricing. You pay per result, and each successfully analyzed image is one result:

| Event | Price |
|---|---|
| Result (one analyzed image) | $4.00 per 1,000 results |
| Actor start | $0.00005 per run |

Images that fail (no face detected, invalid or unreachable image, API errors) are **not written to the dataset and not charged**. They are listed in the `FAILED_IMAGES` record instead (see [Output](#output)). If you set a maximum cost per run, the Actor stops cleanly when the limit is reached and keeps all results produced so far.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `imageUrls` | array of strings | – | Public HTTP(S) image URLs (max 15 MB, max 4500 px per side). |
| `analysis` | string | `"age"` | Exactly one of `age`, `attractiveness`, `facemesh`. |
| `returnBoundaryBox` | boolean | `true` | Face x, y, width, height (age & attractiveness). |
| `saveFaceCrop` | boolean | `false` | Save a JPEG crop of the face and return its URL (age & attractiveness). |
| `returnGender` | boolean | `true` | Gender with the attractiveness analysis. |
| `returnKeypoints` | boolean | `true` | 478 normalized x, y, z landmarks (face mesh). |
| `returnFrontalizedKeypoints` | boolean | `false` | 478 pose-corrected landmarks (face mesh). |
| `returnPose` | boolean | `true` | Yaw, pitch, roll and frontal deviation (face mesh). |
| `maxConcurrency` | integer | `5` | Parallel requests (1–20). |

The older `analyses` array field is still accepted for existing integrations, but only with a single value (e.g. `["age"]`). A run that asks for more than one analysis fails immediately with an input error and nothing is charged.

Example input:

```json
{
    "imageUrls": ["https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg"],
    "analysis": "age",
    "saveFaceCrop": true
}
```

### Output

One dataset item per successfully analyzed image. It contains only the fields of the selected analysis.

Age (`"analysis": "age"`):

```json
{
    "imageUrl": "https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg",
    "status": "success",
    "analysis": "age",
    "apiVersion": "1.1",
    "age": 25.42,
    "boundaryBox": { "x": 113, "y": 89, "width": 142, "height": 180 },
    "faceCropUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/face-000000.jpg"
}
```

Attractiveness (`"analysis": "attractiveness"`):

```json
{
    "imageUrl": "https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg",
    "status": "success",
    "analysis": "attractiveness",
    "apiVersion": "1.1",
    "attractivenessScore": 7.42,
    "attractivenessScoreAdjusted": 8.11,
    "gender": "male",
    "boundaryBox": { "x": 113, "y": 89, "width": 142, "height": 180 }
}
```

- `attractivenessScore` is the raw 0–10 model score; `attractivenessScoreAdjusted` is calibrated (3.5–10) and recommended for display.
- Bounding-box coordinates refer to the image after downscaling its longest side to 1000 px.
- Face mesh (`"analysis": "facemesh"`): `keypoints`, `frontalizedKeypoints` (478 × `{x, y, z}`) and `headPose` (`yaw`, `pitch`, `roll`, `off_frontal_deg`, `frontal_deviation`).

#### Failed images

Failed images are not added to the dataset (so they are not charged). When at least one image fails, the run saves a `FAILED_IMAGES` record in its default key-value store, and the run's status message says how many failed:

```json
[
    {
        "imageUrl": "https://example.com/no-face.jpg",
        "analysis": "age",
        "error": { "code": "NO_FACE_DETECTED", "message": "..." }
    }
]
```

Error codes: `VALIDATION_ERROR`, `IMAGE_TOO_LARGE`, `IMAGE_DIMENSIONS_TOO_LARGE`, `INVALID_IMAGE`, `NO_FACE_DETECTED`, `IMAGE_URL_UNREACHABLE`, `UPSTREAM_ERROR`, `UPSTREAM_TIMEOUT`, `INTERNAL_ERROR`, `NETWORK_ERROR`. Temporary server errors are retried automatically.

### Run it via API

```bash
curl -X POST "https://api.apify.com/v2/acts/faceanalysis2~face-age-estimator/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"imageUrls": ["https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg"], "analysis": "age"}'
```

### Limitations and responsible use

- Age, gender and attractiveness are **estimates of appearance**, not facts about a person. Don't use them as the sole basis for decisions about people (e.g. age verification for legal compliance, hiring, credit or access decisions).
- Face images and derived data can be **biometric personal data** under GDPR and similar laws. Make sure you have a legal basis and any required consent for the images you process.
- Images must be publicly reachable URLs; private, local or unreachable addresses are refused.

### Support

Found a problem, or need another output field or higher volumes? Open an issue in the **Issues** tab of this Actor and we'll get back to you.

# Actor input Schema

## `imageUrls` (type: `array`):

Public HTTP(S) URLs of images to analyze. The largest (primary) face in each image is analyzed. Max 15 MB and 4500 px per side; larger sides are downscaled to 1000 px before analysis.

## `analysis` (type: `string`):

Choose ONE analysis to run for every image. Each run returns only this analysis. To get several analyses (e.g. age and attractiveness) for the same images, start a separate run for each. You pay per successfully analyzed image; failed images are not charged.

## `returnBoundaryBox` (type: `boolean`):

Include x, y, width and height of the detected face (age and attractiveness analyses). Coordinates refer to the image after downscaling to max 1000 px.

## `saveFaceCrop` (type: `boolean`):

Save a JPEG crop of the detected face to the run's key-value store and add its URL to the result.

## `returnGender` (type: `boolean`):

Include the detected gender (male / female) when the attractiveness analysis is selected.

## `returnKeypoints` (type: `boolean`):

Include 478 normalized x, y, z landmarks.

## `returnFrontalizedKeypoints` (type: `boolean`):

Include 478 pose-corrected landmarks.

## `returnPose` (type: `boolean`):

Include yaw, pitch, roll, off\_frontal\_deg and frontal\_deviation.

## `maxConcurrency` (type: `integer`):

How many API requests run in parallel.

## Actor input object example

```json
{
  "imageUrls": [
    "https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg"
  ],
  "analysis": "age",
  "returnBoundaryBox": true,
  "saveFaceCrop": false,
  "returnGender": true,
  "returnKeypoints": true,
  "returnFrontalizedKeypoints": false,
  "returnPose": true,
  "maxConcurrency": 5
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `faceCrops` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrls": [
        "https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg"
    ],
    "analysis": "age"
};

// Run the Actor and wait for it to finish
const run = await client.actor("faceanalysis2/face-age-estimator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "imageUrls": ["https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg"],
    "analysis": "age",
}

# Run the Actor and wait for it to finish
run = client.actor("faceanalysis2/face-age-estimator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrls": [
    "https://howolddoyoulook.com/static/images/sample/portrait_example_male.jpg"
  ],
  "analysis": "age"
}' |
apify call faceanalysis2/face-age-estimator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,faceanalysis2/face-age-estimator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CCQoGddowfA2emIgu/builds/guBBLBdX9El02VzaZ/openapi.json
