# Username Generator & Checker (`protocol/username-generator-checker`) Actor

Generate brand-safe, tone-specific usernames with an LLM pipeline, then verify availability across GitHub, X, Twitch, and YouTube in one run.

- **URL**: https://apify.com/protocol/username-generator-checker.md
- **Developed by:** [Protocol](https://apify.com/protocol) (community)
- **Categories:** AI, Social media, Developer tools
- **Stats:** 13 total users, 0 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 ai username generator & checkers

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 Username Generator

Generate brand-safe, tone-specific username ideas with an LLM, then verify availability across GitHub, X, Instagram, Threads, TikTok, Twitch, and YouTube in a single run. You get a ranked shortlist with a per-platform `available` / `taken` / `unknown` verdict, confidence scores, and naming-quality signals — so you can pick a handle that fits your brand and is actually free where you need it.

Built for founders naming a startup, creators picking a public handle, and developers who want one consistent identity across platforms — without checking half a dozen sites by hand.

- **Generate + verify + rank in one run** — more than an LLM prompt, more than an availability checker.
- **Fast:** ≈8s for a typical 10 names × 2 platforms run (large 20 × 4 runs take ~17s).
- **Low cost:** ~$0.08 for a typical 10 names × 4 platforms run ($2.00 / 1,000 checks); a max 20 × 7 run costs ~$0.28.
- **No logins, no browser automation:** unauthenticated, point-in-time checks with confidence scores; ambiguous responses are reported honestly as `unknown`.
- **Agent-ready:** flat JSON dataset plus a grouped summary record — wires into MCP, Make, Zapier, and n8n.

***

### Quick start

1. [Create a free Apify account](https://console.apify.com/sign-up) (or sign in).
2. Open this Actor's page and go to the **Input** tab.
3. Add at least one `keywords` entry — everything else has a sensible default.
4. Click **Start** and wait a few seconds.
5. Open the **Storage** tab to view the ranked dataset, or read the `OUTPUT` key-value record for the single best pick.

***

### What this Actor does

1. **Generates** up to 20 candidates from your keywords, brand/personal name, niche, and tone using a cost-optimized LLM pipeline (DeepSeek primary, GPT-4o-mini fallback via OpenRouter).
2. **Filters** them deterministically — profanity, homoglyph/leetspeak lookalikes (`d3vil` is caught by banning `devil`), your custom banned words, and each platform's handle rules (length, allowed characters).
3. **Verifies** availability with unauthenticated HTTP checks over datacenter proxies — no browser automation, no logins, no credentials sent to any platform.
4. **Ranks** the survivors by naming quality, adjusted for real availability, and writes a flat dataset (one row per username × platform) plus a grouped `OUTPUT` summary that names the single best pick.

***

### Why use it

- **Get names, not just availability.** The LLM proposes on-brand candidates in the tone you choose — you are not feeding it your own list.
- **Pick a name that is free *everywhere*.** The grouped summary names the single candidate open across all the platforms you care about.
- **Stop checking handles by hand.** One run replaces opening seven sites in seven tabs for every idea.

***

### Supported platforms

| Platform        | What is checked                            | Reliability                                                                            |
| --------------- | ------------------------------------------- | --------------------------------------------------------------------------------------- |
| **GitHub**      | Profile 404 vs 200                          | High — most reliable check                                                              |
| **Threads**     | WebFinger discovery lookup                  | High                                                                                     |
| **Instagram**   | Profile page `<title>` signal               | Medium-high                                                                              |
| **Twitch**      | Channel existence                           | High                                                                                     |
| **YouTube**     | Handle / channel exists                     | High                                                                                     |
| **TikTok**      | Embedded profile JSON                       | Reliable for `taken`; never reports `available` (see below)                             |
| **X** (formerly Twitter) | Profile reachability               | Variable — 30–50% return `unknown` due to login walls; **optional, not in the default platform list** |

> **Two platforms behave specially, by design.** **X** often returns `unknown` (login wall — opt in via `platforms` and expect a higher `unknown` rate), and **TikTok** never returns `available` (anti-enumeration — it only emits `taken` or `unknown`). Both are deliberate honesty measures, not bugs; the ranking step downweights any `unknown`. Full explanations in [Known limitations](#known-limitations) and the [FAQ](#faq).

***

### Input

Only `keywords` is required. Everything else has a sensible default, so the smallest valid input is a single keyword.

| Field          | Type       | Default        | Description                                                                                                       |
| -------------- | ---------- | -------------- | ----------------------------------------------------------------------------------------------------------------- |
| `keywords`     | `string[]` | — (required)   | Seed words/themes to build names around, e.g. `["vault", "alpha"]`.                                               |
| `brandName`    | `string`   | —              | Existing brand whose fragments to weave in (e.g. `BrandCraft` → `brandcrafthq`).                                  |
| `personalName` | `string`   | —              | Personal name for individual/creator handles (e.g. `Ray` → `raybuilds`).                                          |
| `niche`        | `string`   | —              | Industry/niche (e.g. `fintech`, `indie gaming`) — drives naming conventions.                                      |
| `tone`         | enum       | `Professional` | One of `Professional`, `Minimal`, `Gamer`, `Creative`.                                                            |
| `platforms`    | `string[]` | `["github"]`   | Any of `github`, `threads`, `instagram`, `twitch`, `youtube`, `tiktok`, `x` (lowercase; use `x`, not `twitter`). `x` is optional and not selected by default — see [Supported platforms](#supported-platforms). |
| `maxLength`    | `integer`  | `20`           | Max handle length (hard cap 30). Set ≤ 15 when targeting X; ≤ 24 when targeting TikTok.                           |
| `bannedWords`  | `string[]` | `[]`           | Words to exclude — matched after de-leeting, so `d3vil` is caught by banning `devil`.                             |
| `count`        | `integer`  | `10`           | Candidates to generate (hard cap **20** per run).                                                                 |
| `inputMode`    | enum       | `full`         | `full` = generate **and** verify (billable). `generate_only` = generate without checks (free, for brainstorming). |

#### Example input — founder / startup

```json
{
    "keywords": ["launch", "build"],
    "niche": "developer tools",
    "tone": "Professional",
    "platforms": ["github", "x"],
    "count": 10
}
```

#### Example input — creator / gamer

```json
{
    "keywords": ["stream", "play"],
    "tone": "Gamer",
    "platforms": ["twitch", "youtube"],
    "count": 10
}
```

***

### Output

The Actor writes to two places:

1. **Dataset** — one row per **candidate × selected platform** (10 names × 2 platforms = up to 20 rows). Up to 20 candidates per run; the row count is *not* capped at 20.
2. **Key-value store `OUTPUT`** — a grouped per-name summary with the top pick and a machine-readable `chargeable` / `degraded` verdict. This is the record AI agents should read first.

#### Dataset fields

| Field                                       | Meaning                                                                                      |
| ------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `username`                                  | The generated candidate.                                                                     |
| `normalizedUsername`                        | Lowercased/stripped form used for checks and cache keys.                                     |
| `platform`                                  | `github` / `threads` / `instagram` / `twitch` / `youtube` / `tiktok` / `x`.                   |
| `status`                                    | `available`, `taken`, `invalid`, `unknown`, `rate_limited`, or `unverified` (generate-only). |
| `confidence`                                | 0–100 *verification* certainty (cache hit 100, HTTP-verified 90) — not naming quality.       |
| `reasonCode`                                | Stable machine-readable code to branch on: `PROFILE_NOT_FOUND`, `PROFILE_EXISTS`, `LOGIN_WALL`, `REQUEST_TIMEOUT`, `RATE_LIMITED`, `AMBIGUOUS_SIGNAL`, `CHECK_FAILED`, `RULES_INVALID`, `UNVERIFIED_GENERATE_ONLY`. |
| `reason`                                    | Human-readable, platform-aware explanation of the verdict.                                   |
| `debug`                                     | Nested low-level detail `{ verificationMethod, httpStatus?, timedOut? }` (not a CSV column).  |
| `verification_method`                       | *Deprecated* (kept for back-compat; use `reasonCode` / `debug.verificationMethod`). How the status was found, e.g. `http_404`, `http_200`, `cache_hit`, `none`. |
| `rankingScore`                              | 0–100 naming quality, adjusted for availability.                                             |
| `rankingRationale`                          | Short human-readable reason for the rank.                                                    |
| `statusReason`                              | *Deprecated* (kept for back-compat; use `reason`). Why a status was assigned (e.g. login wall → `unknown`). |
| `brandFit` / `readability` / `memorability` | 0–100 LLM naming scores.                                                                     |
| `isHighConfidence`                          | `true` when `confidence ≥ 80` and status is `available`/`taken`.                             |
| `platformRulesValid`                        | Passed that platform's handle rules.                                                         |
| `runId`                                     | Apify run ID for traceability.                                                               |

#### Example output row

```json
{
    "username": "buildvaulthq",
    "normalizedUsername": "buildvaulthq",
    "platform": "github",
    "status": "available",
    "confidence": 90,
    "reasonCode": "PROFILE_NOT_FOUND",
    "reason": "GitHub profile not found — the handle appears available.",
    "debug": { "verificationMethod": "http_404", "httpStatus": 404 },
    "verification_method": "http_404",
    "rankingScore": 82,
    "rankingRationale": "Strong brand fit, available on GitHub, easy to read",
    "statusReason": "Verified via http_404",
    "brandFit": 88,
    "readability": 80,
    "memorability": 78,
    "isHighConfidence": true,
    "platformRulesValid": true,
    "runId": "abc123"
}
```

***

### How availability checking works

- **Unauthenticated HTTP only.** The Actor requests public profile/channel URLs and maps the HTTP response to a status. No credentials are ever sent to GitHub, Threads, Instagram, Twitch, YouTube, TikTok, or X, and raw external HTML is never stored in your dataset or logs.
- **Datacenter proxies.** Checks run through Apify datacenter proxies with session rotation — no residential proxies, keeping runs cheap and fast.
- **No browser automation.** Ambiguous responses degrade to `unknown` rather than being force-resolved with a headless browser. This is why X (which gates profiles behind a login wall) frequently returns `unknown`.
- **10-second pipeline deadline.** A global deadline flips any still-pending checks to `unknown` and proceeds to scoring, so a slow platform can never blow the run-time budget.
- **Caching.** Confirmed-`taken` handles are cached in a key-value store, so repeat runs over trending names skip redundant proxy calls.

***

### Run modes & pricing

This Actor uses **pay-per-event** pricing at **$2.00 / 1,000 checks**. You choose the work per run with `inputMode`:

| `inputMode`      | Work performed                                              | Billing                                                        |
| ---------------- | ----------------------------------------------------------- | -------------------------------------------------------------- |
| `full` (default) | Generate + Tier-1 filter + availability verification        | Charged per verified result at **$2.00 / 1,000 checks**        |
| `generate_only`  | Generate + Tier-1 filter only (rows come back `unverified`) | **Free — no charge.** Ideal for brainstorming before committing |

Charged per verified result ($0.002/row) when the run succeeds and at least one platform was verified. A typical run (10 names × 4 platforms) costs ~$0.08. Runs that fail before producing output, or that come back **degraded** (zero platforms verifiable — all `unknown`/`rate_limited`), are **not** charged. `generate_only` runs are always free. There is no separate user tier and no reduced name cap — every mode supports up to 20 names.

***

### Usage via API

Run the Actor programmatically with the Apify API client. Supply your [Apify API token](https://console.apify.com/account/integrations).

#### Python

```bash
pip install apify-client
```

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_API_TOKEN>")

run_input = {
    "keywords": ["launch", "build"],
    "tone": "Professional",
    "platforms": ["github", "x"],
    "count": 10,
    "inputMode": "full",
}

## Start the run and wait for it to finish
run = client.actor("protocol/username-generator-checker").call(run_input=run_input)

## Read the per-row dataset
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["username"], item["platform"], item["status"], item["rankingScore"])

## Read the grouped summary (best pick + chargeable/degraded verdict)
summary = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")
print(summary["value"])
```

#### JavaScript / TypeScript

```bash
npm install apify-client
```

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

const client = new ApifyClient({ token: '<YOUR_APIFY_API_TOKEN>' });

const run = await client.actor('protocol/username-generator-checker').call({
    keywords: ['stream', 'play'],
    tone: 'Gamer',
    platforms: ['twitch', 'youtube'],
    count: 10,
    inputMode: 'full',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.table(items.map((i) => ({ name: i.username, platform: i.platform, status: i.status })));
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/protocol~username-generator-checker/run-sync-get-dataset-items?token=%3CYOUR_APIFY_API_TOKEN%3E" \
  -H 'Content-Type: application/json' \
  -d '{ "keywords": ["vault", "alpha"], "platforms": ["github"], "count": 5 }'
```

***

### Use with AI agents (MCP)

The Actor is built to be driven by AI agents. The `INPUT_SCHEMA.json` exposes typed fields with enum dropdowns and defaults, so an MCP client (e.g. Claude Desktop via the [Apify MCP Server](https://docs.apify.com/platform/integrations/mcp)) can call it with minimal prompting. Agents should read the grouped `OUTPUT` record — it carries the single best candidate and a machine-readable `chargeable`/`degraded` verdict, so the agent does not have to reduce the flat dataset itself. Invalid input returns a structured error code rather than a silent failure (see [Run-level error codes](#run-level-error-codes)).

Connect via the [Apify MCP Server](https://docs.apify.com/platform/integrations/mcp) with a client config like:

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=protocol/username-generator-checker",
                "--header",
                "Authorization: Bearer <YOUR_APIFY_API_TOKEN>"
            ]
        }
    }
}
```

***

### Run-level error codes

Most failures are reported per-row via `reasonCode` (see [Dataset fields](#dataset-fields)). A small set of run-level codes cover failures before any row can be produced — for example, invalid top-level input. The Actor always returns one of these rather than failing silently:

| Code                          | Meaning                                                                  |
| ------------------------------ | ------------------------------------------------------------------------- |
| `ERR_INVALID_INPUT`            | Input failed schema validation (e.g. missing `keywords`, `count` > 20).   |
| `ERR_MISSING_API_KEY`          | The Actor's LLM provider credential is not configured (operator-side).   |
| `ERR_LLM_PIPELINE_FAILED`      | Both the primary and fallback LLM engines failed or timed out.           |
| `ERR_ALL_PLATFORMS_RATE_LIMITED` | Every selected platform returned a rate-limit response — run degraded. |
| `ERR_OUTPUT_SCHEMA_VIOLATION`  | An internal output failed schema validation before being written.        |

***

### FAQ

**Why does X return `unknown` so often, and why isn't it checked by default?**
X gates many profiles behind a login wall. Rather than scrape past it with a headless browser, the Actor honestly reports `unknown` (30–50% of X checks). Because of this, X is **not** included in the default `platforms` list — add `x` explicitly when you need it, and treat `unknown` as "could not confirm," not "taken."

**Why does TikTok never return `available`?**
TikTok intentionally returns the same status code whether a handle was never registered or belongs to a banned account — there is no unauthenticated way to distinguish the two. To avoid false positives, this Actor's TikTok adapter only ever reports `taken` or `unknown`, never `available`. Expect most genuinely free TikTok handles to come back `unknown`; this is a deliberate platform anti-enumeration measure, not a bug, and the ranking step already downweights candidates with any `unknown` result.

**Can a name marked `available` be taken later?**
Yes. Results are a point-in-time snapshot. A handle can be claimed by someone else before you register it, and `available` may reflect a recently-released handle still in a platform grace window. Re-confirm before relying on it.

**Will the same input always return the same names?**
No. LLM generation is non-deterministic — the same input can produce different candidates across runs. The availability verdicts for a given handle are deterministic.

**How many names can I generate per run?**
Up to 20, in any mode. Larger batches require multiple runs.

**How do I brainstorm cheaply before committing?**
Run with `inputMode: "generate_only"`. It generates and filters names without availability checks (status `unverified`) and is free. Switch to `full` when you want verified results.

**Is my input data sent anywhere?**
Keyword and name inputs are sent to a third-party LLM provider (via OpenRouter) to generate candidates. See Data & privacy below.

**Can I connect this to Zapier, Make, n8n, or a webhook?**
Yes. The Actor works with any tool that can call the Apify API — including Make, Zapier, and n8n integrations and [Apify webhooks](https://docs.apify.com/integrations/webhooks) (e.g. notify on run success). See [Usage via API](#usage-via-api) for direct API/SDK calls, or [Use with AI agents (MCP)](#use-with-ai-agents-mcp) for MCP clients.

***

### Known limitations

| Limitation                   | What to expect                                                                                |
| ---------------------------- | --------------------------------------------------------------------------------------------- |
| X `unknown` rate, optional | 30–50% of X checks return `unknown` due to login walls — expected, not a bug. X is **not in the default platform list**; opt in explicitly via `platforms`. |
| TikTok never reports `available` | TikTok collapses "never registered" and "banned" into one ambiguous code — the adapter only ever emits `taken` or `unknown`, so expect a near-100% `unknown` rate on free handles. Not a bug. |
| No browser automation        | Ambiguous responses degrade to `unknown` rather than being force-resolved.                    |
| Point-in-time availability   | A handle marked `available` may be claimed before you register it. Re-confirm before relying. |
| Grace-window handles         | `available` may reflect a recently-released handle still in a platform grace window.          |
| Non-deterministic generation | The same input may produce different candidates on different runs.                            |
| Max 20 names per run         | Hard cap; larger batches require multiple runs.                                               |

***

### Data & privacy

- **Keyword and name inputs are sent to a third-party LLM provider** (via OpenRouter) to generate candidates. **Do not include personal data** you do not want shared with an LLM provider. `personalName`-derived outputs persist in the run's dataset and exports.
- **Availability checks are unauthenticated** — no credentials are sent to any platform, and no raw external HTML is stored in your dataset or logs.
- **Data retention:** datasets are retained per your Apify account settings. **Delete the run to erase its outputs.**

***

### Support

Found a bug or want a platform added? Open an issue on the Actor's **Issues** tab in the Apify Console. Feature requests (preset naming modes, availability monitoring/watchlist, bulk validation) are tracked on the roadmap.

# Actor input Schema

## `keywords` (type: `array`):

Required. Seed words or themes the usernames should be built around (e.g. \["vault", "alpha"]). Provide at least one. Each keyword is woven into generated candidates where natural. Do not include personal data you don't want sent to an LLM provider.

## `brandName` (type: `string`):

Optional. An existing brand name whose fragments should be incorporated into candidates where natural (e.g. "BrandCraft" may yield "brandcrafthq"). Leave empty if naming from scratch.

## `personalName` (type: `string`):

Optional. A personal name to incorporate for individual/creator handles (e.g. "Ray" may yield "raybuilds"). Note: name-derived outputs persist in the run's dataset and exports.

## `niche` (type: `string`):

Optional. Industry, niche, or category the username is for (e.g. "fintech", "indie gaming", "food blogging"). Drives industry naming conventions in generation — fintech favors short/trust-evoking names, gaming favors thematic/clan-style, creator brands favor memorable/personal.

## `tone` (type: `string`):

Optional. Naming tone applied to all candidates. Must be exactly one of: "Professional" (corporate, trust-evoking), "Minimal" (short, clean, lowercase feel), "Gamer" (thematic, edgy, gaming-culture style), "Creative" (playful, unexpected wordplay). Defaults to "Professional".

## `platforms` (type: `array`):

Optional. Platforms to verify availability on. Allowed values: "github", "x", "twitch", "youtube", "threads", "instagram", "tiktok" (lowercase, exactly as listed — e.g. use "x", not "twitter"). Defaults to \["github"], the most reliable check. "x" is optional and not selected by default — it frequently returns status "unknown" due to login walls, so select it deliberately. "tiktok" is also optional and not selected by default — TikTok's anti-enumeration design means it can confirm a handle is taken but cannot confirm one is available, so expect a high "unknown" rate for genuinely free names; this is a platform limitation, not a bug. Each candidate is checked on every selected platform (one output row per candidate-platform pair).

## `maxLength` (type: `integer`):

Optional. Maximum character length for generated usernames. Hard cap 30 (YouTube/Instagram/Threads' limit — the longest supported platforms). Defaults to 20, a safe cross-platform value; note X allows only 15 characters and TikTok only 24, so set the limit accordingly when targeting those platforms. Values above 30 are rejected.

## `bannedWords` (type: `array`):

Optional. Words that must never appear in generated usernames (e.g. competitor names, sensitive terms). Matching is applied after normalization and de-leeting, so "d3vil" is caught by banning "devil". Defaults to \[] (no extra filtering beyond the built-in profanity list).

## `count` (type: `integer`):

Optional. How many username candidates to generate. Hard cap 20 per run — this bounds LLM cost and keeps availability checks within the run-time budget; a higher count is rejected before generation. Defaults to 10.

## `inputMode` (type: `string`):

Optional. "full" (default) generates candidates AND verifies availability on the selected platforms — the complete, billable pipeline. "generate\_only" generates and filters candidates but skips all availability checks: rows come back with status "unverified", it is much cheaper and non-billable, ideal for fast iterative brainstorming before committing to a full verification run. No other value is accepted in V1 ("validate" is planned but not yet available).

## Actor input object example

```json
{
  "keywords": [
    "brand",
    "craft"
  ],
  "tone": "Professional",
  "platforms": [
    "github"
  ],
  "maxLength": 20,
  "bannedWords": [],
  "count": 10,
  "inputMode": "full"
}
```

# Actor output Schema

## `shortlist` (type: `string`):

Ranked username candidates as dataset rows — one row per candidate x selected platform — each carrying availability status, a machine-readable reasonCode, confidence, and ranking scores. In full mode rows are availability-verified; in generate\_only mode rows are status "unverified". Field-level detail is in dataset\_schema.json.

# 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 = {
    "keywords": [
        "brand",
        "craft"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("protocol/username-generator-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 = { "keywords": [
        "brand",
        "craft",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("protocol/username-generator-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 '{
  "keywords": [
    "brand",
    "craft"
  ]
}' |
apify call protocol/username-generator-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,protocol/username-generator-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/gNrbCNpnNhmNEmnon/builds/CBRjQgJcBrU4Bgitg/openapi.json
