# Instagram Account Age Checker — Creation Date, Country, Joined (`steadyfetch/instagram-account-age-checker`) Actor

Instagram account age checker: see when an Instagram account was created (month and year), the country it is based in, whether it is verified, and how many times it changed its username. Paste handles, profile links or ids. From $4.50 per 1,000 accounts; an account with no record is never charged.

- **URL**: https://apify.com/steadyfetch/instagram-account-age-checker.md
- **Developed by:** [Steadyfetch Team](https://apify.com/steadyfetch) (community)
- **Categories:** Social media, Lead generation, Automation
- **Stats:** 9 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.50 / 1,000 accounts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instagram Account Age Checker — Country, Date Joined

**Instagram account age checker: see when an Instagram account was created and the country it is based in, straight from Instagram's own "About this account" panel. Paste handles, profile links or account ids and get one row per account: country, the month and year it joined, its age in months, verified and private flags, and how many times it changed its username. $4.50 per 1,000 accounts; an account with no record is never charged.**

Built for growth agencies, brand-safety teams and influencer vetting: check where a creator's account is based in before a deal, spot a brand-new account posing as an old one, or flag a handle that has been renamed. No login, no cookies, no proxy to set up. Nothing is charged for starting a run, and an account that does not exist, or whose panel names nothing, carries no result fee.

**Using an AI agent?** Pin this actor in Apify's MCP server with one link: `https://mcp.apify.com?tools=steadyfetch/instagram-account-age-checker`

- **Actor id:** `steadyfetch/instagram-account-age-checker`
- **Input:** `{ "usernames": ["nike", "@aesop", "1771059415"] }` — `usernames` is the one field you have to set: handles, @handles, profile links or numeric account ids.
- **Cap the bill:** set `maxTotalChargeUsd` on the run (a run option, not Actor input), e.g. `0.50` for 100 accounts — the run stops when it reaches it.
- **Price:** $0.005 per account on the Apify free plan, $0.0045 from Gold. Full table below.
- **How often it changes:** almost never — where an account is based and the month it joined stay put, so check each account once and re-run only new ones.

*Unofficial. Not affiliated with, endorsed by, or sponsored by Instagram or Meta Platforms, Inc.*

### What you get

One row per account:

| Column | What it holds |
|---|---|
| `username` · `userId` · `profileUrl` | who the account is |
| `country` | the country Instagram's panel says the account is based in — `null` when the panel names none |
| `dateJoined` | the month and year the account joined, exactly as Instagram words it ("November 2011") |
| `dateJoinedMonth` | the same month as `YYYY-MM` ("2011-11"), ready to sort and filter |
| `accountAgeMonths` | whole months from the join month to the month of the run |
| `isVerified` · `isPrivate` | the verified badge, and whether the account is private (`null` when you named it by id) |
| `formerUsernamesCount` | how many times the account changed its username, as a number (`0` = never) |
| `charged` · `chargedEvents` · `status` · `statusReason` | what the row was charged, and why it says what it says |

Every column is always present, and nothing is guessed: an empty field is `null`, never an empty string or an invented value.

### What a row looks like

```json
{
  "username": "nike",
  "userId": "13460080",
  "profileUrl": "https://www.instagram.com/nike/",
  "country": "United States",
  "dateJoined": "November 2011",
  "dateJoinedMonth": "2011-11",
  "accountAgeMonths": 179,
  "isVerified": true,
  "isPrivate": false,
  "formerUsernamesCount": 0,
  "charged": true,
  "chargedEvents": { "account": 1 },
  "status": "delivered"
}
```

### Price

You pay per account delivered, and nothing else:

| Event | When it is charged | Apify free plan | Bronze | Silver | Gold and up |
|---|---|---|---|---|---|
| `account` | each account whose "About this account" panel named a country or a join date | $0.005 | $0.0048 | $0.0046 | $0.0045 |

Per 1,000 accounts that is $5.00 on the Apify free plan, $4.80 on Bronze, $4.60 on Silver and $4.50 per 1,000 from Gold. No start fee, ever. The same account named twice in one run — say by handle and by id — is read once and charged once.

### What the country means

`country` is the country Instagram itself shows under "Account based in" on the account's "About this account" panel. Instagram decides it; the account holder does not type it, and it can differ from where a person happens to be today. Instagram leaves it out for some accounts — often private ones — and then `country` is `null` while the join date is still delivered (and charged, because it is an answer). If you need the country on every row, filter on `country != null`.

### Dates are month and year

Instagram publishes the join date as a month and a year, never a day. `dateJoined` keeps Instagram's own words, `dateJoinedMonth` is the same month as `YYYY-MM`, and `accountAgeMonths` counts whole months up to the month the run happened. Nothing here invents a day of the month.

### Honest rows: what "not charged" actually means

Every account you name gets exactly one row. An account that was not delivered leaves an uncharged row whose `status` says which of these happened:

- **`nothing_found`** — Instagram has no account at that handle or id, or its "About this account" panel names no country and no join date. The row says which. A definitive answer: a re-run answers the same.
- **`not_public`** — the account is private and its panel names nothing.
- **`your_limit_reached`** / **`out_of_time`** — your result limit, your maximum cost per run or the run clock stopped it first.
- **`plan_limit_reached`** — the Apify free plan's daily allowance for this actor (below); the row says when it resets.
- **`limit_reached`** — this run reached its limit before it could look the account up; a new run with the accounts on those rows collects them.
- **`try_again`** — the read did not go through. Temporary, says nothing about the account, and a re-run is the fix.
- **`not_accepted`** / **`not_supported`** — a value this actor cannot use (a post link, a number too short to be an id), or an answer it does not read yet. The row says what to paste instead.

None of these is charged, and the run still finishes successfully. A time limit ends the collecting, never the delivering: accounts already in hand are always written out. The last row of every run is a receipt: delivered, asked for, what stopped the run, and the charged total. Results may fail when Instagram changes; failed items are never charged.

### How often this data changes

Where an account is based and the month it joined almost never change, and the username count only ever goes up. So there is no repeat memory and no "only new" mode: every run reads each account you name fresh and charges it again, and the record rarely changes — re-run only new accounts, the ones you have not checked yet.

### Use it as an API endpoint (Standby)

You can also call this actor like an API: send the accounts in one web request and get their rows back in the same response, with no run to start and no dataset to read. The address is `https://steadyfetch--instagram-account-age-checker.apify.actor`, also shown on the actor's **Endpoints** tab, where you can try it from the browser.

```bash
curl -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  "https://steadyfetch--instagram-account-age-checker.apify.actor/?usernames=nike,aesop"
```

| Setting | What it does |
|---|---|
| `usernames` | Handles, @handles, profile links or numeric account ids — comma-separated, or the parameter repeated. A JSON body `{"usernames": ["nike"]}` works too. |
| `resultsLimit` | The most accounts to look up in this request. One request looks up at most 25 accounts (3 on the Apify free plan); send a longer list in several requests, or run the actor. |

The answer is JSON: `rows` (one per account you named, the same fields as a dataset row), `summary` (the receipt), `delivered`, `charged`, and `notes` saying what to do about anything not delivered. You are charged exactly as a run charges, per account delivered. The endpoint keeps no memory of earlier requests. If the charge for a request cannot be completed, its accounts are not sent and nothing is charged.

### Limits and good manners

**Max accounts** defaults to 100, so for a longer list set it to the length of the list (up to 5,000) — accounts past it are not looked up. **Max accounts** and **Max run seconds** take any number you type: a bigger ask runs at this actor's ceiling instead of being refused, and one uncharged row says what was asked for and what was used. A number of 8 digits or more is read as an account id (one lookup instead of two); paste a shorter id, or an all-numeric username, as its profile link.

On the Apify free plan this actor makes at most 60 Instagram lookups per account in any 24 hours — two per account named by handle, one per account named by id — and accounts on the free plan share one daily allowance on this actor. Past either, the run keeps everything it already delivered, ships one uncharged row saying when it resets (UTC), and charges nothing past it. That row is `retryable: true` and carries `retryAfter` (the exact reset time) and `reason: "free_plan_allowance"`, and so do the run summary row and the OUTPUT record, so a script running a list can wait for that time instead of starting runs that are held the same way. Paid Apify plans carry no daily allowance.

A bare Start with no account looks up three well-known brand accounts as a sample, at no result fee, so you can see the output. Only what Instagram shows any visitor is returned: nothing private, nothing behind a login.

### Related actors

- The full profile of accounts you already know — followers, bio, category and public contacts: **Instagram Bio Scraper** — https://apify.com/steadyfetch/instagram-profile-details-scraper
- Find accounts by keyword or hashtag: **Instagram Account Search** — https://apify.com/steadyfetch/instagram-account-search-scraper
- One account's own posts: **Instagram Profile Posts Scraper** — https://apify.com/steadyfetch/instagram-profile-posts

### Reliability

Each account is looked up directly rather than scraped from Instagram's own web pages, which is why there is nothing to log into and nothing to configure. When a lookup cannot be answered, the run says so on an uncharged row and finishes successfully — a failed read is never billed and never dressed up as a missing account.

### Support

Something off, or a column you need that is not here? Open an issue on the Issues tab — we usually reply within a couple of hours.

If it earned its keep, a rating helps other buyers find it, and saving the actor keeps it one click away.

# Changelog

This Actor's version history is a separate document: https://apify.com/steadyfetch/instagram-account-age-checker/changelog.md

# Actor input Schema

## `usernames` (type: `array`):

Instagram accounts, one per line — "nike", "@nike" or https://www.instagram.com/nike/ all work, and a pasted spreadsheet column is split. A number of 8 digits or more is read as an account id; a shorter number (or an all-numeric username) goes in as its profile link. An account that does not exist, or whose "About this account" panel names nothing, is never charged. A post or reel link is refused with a row saying so. Left empty, the run looks up three sample brand accounts at no result fee.

## `resultsLimit` (type: `integer`):

The most accounts this run delivers (default 100) — set it to the length of your list, up to 5,000. Accounts past the cap are not looked up and leave an uncharged row saying so, so a long paste can never cost more than you meant. An account that could not be delivered does not use up one of these slots — the next account on your list takes it. This actor delivers at most 5,000 accounts in one run: ask for more and the run continues at 5,000, with one uncharged row saying so.

## `maxRunSeconds` (type: `integer`):

The run stops cleanly before this many seconds and reports what is left, instead of being killed by a timeout. A time limit ends the collecting, never the delivering: accounts already in hand are always written out. One run lasts at most 3,600 seconds and needs at least 30: ask outside that and the run continues at the nearest of the two, with one uncharged row saying so.

## Actor input object example

```json
{
  "usernames": [],
  "resultsLimit": 100,
  "maxRunSeconds": 600
}
```

# Actor output Schema

## `accounts` (type: `string`):

One row per account delivered: the country it is based in (`country`, empty when Instagram's "About this account" panel names none), the month and year it joined as the panel words it (`dateJoined`) with `dateJoinedMonth` (YYYY-MM) and `accountAgeMonths` at the run date, `isVerified`, `isPrivate` (empty on a numeric-id input) and `formerUsernamesCount`. Every row carries `charged`, `chargedEvents` and `status`, so the invoice reconciles from the dataset itself: only rows with charged = true were billed the `account` event.

## `misses` (type: `string`):

One uncharged row for every account that was not delivered, with `status` saying which: `nothing_found` (Instagram has no account there, or its panel names no country and no join date), `not_public` (a private account whose panel names nothing), `your_limit_reached` (your result limit or cost cap stopped it first), `out_of_time` (the run clock), `try_again` (the read failed and a re-run is the fix), `not_accepted` (the value was not an account this actor can look up, or Instagram refused it), `not_supported` (an answer this actor does not read yet), `limit_reached` (this run reached its limit), `plan_limit_reached` (the Apify free plan's daily allowance). A limit typed above this actor's own ceiling adds one `info` row instead of refusing the run. None of these is charged.

## `summary` (type: `string`):

Accounts delivered, what was asked for, what stopped the run and the charged total, as one record.

# 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 = {
    "usernames": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyfetch/instagram-account-age-checker").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 = { "usernames": [] }

# Run the Actor and wait for it to finish
run = client.actor("steadyfetch/instagram-account-age-checker").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 '{
  "usernames": []
}' |
apify call steadyfetch/instagram-account-age-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyfetch/instagram-account-age-checker"
        }
    }
}
```

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/NWYDXMhzMic72jz5H/builds/tiBIKzrbAAXNmYQ1x/openapi.json
