# How to Interpret the Results from user-scanner Scans: A Complete Guide

> Master user-scanner scan interpretation. Learn to understand TAKEN, AVAILABLE, ERROR, and SKIPPED statuses for clear insights.

- Repository: [Kaif/user-scanner](https://github.com/kaifcodec/user-scanner)
- Tags: how-to-guide
- Published: 2026-08-30

---

**The user-scanner tool reports scan outcomes through a `Result` object with four possible statuses—`TAKEN`, `AVAILABLE`, `ERROR`, and `SKIPPED`—each providing human-readable labels and machine-readable export formats.**

Learning to interpret the results from user-scanner scans is essential for effective username enumeration and digital footprint analysis. The open-source tool `kaifcodec/user-scanner` structures all output through a centralized `Result` class defined in [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py), which standardizes status codes, console formatting, and data export across every site module.

## Understanding the Result Object and Status Codes

Every site check returns a `Result` instance containing a **status** and **reason**. The status is implemented as a Python `Enum` named `Status` with four possible values:

- **`TAKEN`** — The target exists on the site (username claimed or email registered).
- **`AVAILABLE`** — The target does not exist.
- **`ERROR`** — The module failed to reach the site or encountered an exception.
- **`SKIPPED`** — The check was intentionally bypassed (e.g., a "loud" site when `--allow-loud` is disabled).

The human-readable conversion happens via `Status.to_label()`. According to the source code in [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py), labels differ based on the scan type:

- **Usernames**: `TAKEN` renders as *"Found"* and `AVAILABLE` renders as *"Not Found"*.
- **Email addresses**: `TAKEN` renders as *"Registered"* and `AVAILABLE` renders as *"Not Registered"*.

### Contextual Data Injection

Before display or export, the orchestrator in [`user_scanner/core/orchestrator.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/orchestrator.py) enriches each `Result` with contextual metadata. It calls `Result.update(**params)` to inject `username`, `site_name`, `category`, and optionally `url` into the object. This separation allows site modules to remain simple while the orchestrator handles presentation logic.

## Anatomy of Console Output

The `get_console_output` method in [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py) assembles the visual feedback you see in the terminal. Each line follows a consistent pattern containing:

- **Status Icon**: `[✔]` for FOUND, `[✘]` for NOT FOUND, `[!]` for ERROR, `[~]` for SKIPPED.
- **Site Name**: The platform being checked.
- **Optional URL**: Displayed only when the `--verbose` (`-v`) flag is active.
- **Username**: The target handle if provided.
- **Status Label**: "Found", "Not Found", etc.
- **Reason**: Failure explanation in parentheses when applicable.
- **Extra & Media**: Key/value pairs displayed as a tree-like list for profile metadata and media URLs.

### Controlling Output Visibility

Not every result appears in the console. The orchestrator respects the `show_all` configuration flag and the `Result.is_visible` property defined at lines 92-96 of [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py). By default, the tool suppresses noisy or irrelevant results unless you explicitly request comprehensive output.

## Exporting Results to JSON and CSV

For integration with external tools, the `Result` class provides three export methods:

- **`to_dict()`**: Returns a clean dictionary suitable for JSON or CSV serialization. This method deliberately removes the internal `is_email` flag to avoid leaking implementation details (lines 84-91).
- **`to_json()`**: Produces a pretty-printed JSON string for programmatic consumption (lines 96-99).
- **`to_csv()`**: Generates a CSV row with **neutralized cells** to prevent formula injection attacks in spreadsheet applications (lines 26-33).

The CSV sanitization logic detects leading characters like `=`, `+`, `-`, and `@`, prefixing them with a tab character to neutralize potential malicious formulas.

## Handling Extra Metadata and Media

Beyond basic status codes, each `Result` object stores two additional fields:

- **`extra`**: Contains metadata such as profile IDs, visibility flags, or custom messages extracted by the site module.
- **`media`**: URLs to profile pictures or other assets associated with the discovered account.

These fields appear in both console output (as indented key/value trees) and in JSON/CSV exports, enabling downstream tools to enrich reports with profile details.

## Practical Examples

### Command-Line Usage

Run a basic username scan:

```bash

# Standard scan

user-scanner -u alice

# Verbose mode includes URLs

user-scanner -u alice -v

```

Sample console output:

```

[✔] GitHub https://github.com/alice (alice): Found
[✘] Reddit: Not Found (Username not reserved)
[!] Twitter: Error (Connection timed out)
[~] Pinterest: Skipped (Loud site disabled)

```

### Programmatic Python Usage

Import the orchestrator and configuration helpers to process results in code:

```python
from user_scanner.core.orchestrator import run_user_full
from user_scanner.core.helpers import ScanConfig

# Configure scan parameters

cfg = ScanConfig(username="alice", verbose=True)

# Execute scan

results = run_user_full("alice", cfg)

for r in results:
    # Human-readable terminal line

    print(r.get_console_output(cfg))
    
    # Machine-readable JSON

    json_data = r.to_json()
    print(json_data)

```

### Parsing Exported JSON

When using the `--output json` flag, parse the results as follows:

```python
import json
from pathlib import Path

# Load exported results

data = json.loads(Path("output.json").read_text())

for entry in data:
    status = entry["status"]
    site = entry["site_name"]
    
    if status == "Found":
        print(f"Account exists on {site}")
    elif status == "Error":
        print(f"Check failed for {site}: {entry.get('reason')}")

```

## Summary

- The `Result` class in [`user_scanner/core/result.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/result.py) standardizes all output through four statuses: `TAKEN`, `AVAILABLE`, `ERROR`, and `SKIPPED`.
- Status labels adapt to the target type—usernames display "Found"/"Not Found" while emails show "Registered"/"Not Registered" via `Status.to_label()`.
- Console output uses icons (`[✔]`, `[✘]`, `[!]`, `[~]`) and respects visibility rules controlled by the `show_all` flag and `Result.is_visible`.
- Machine-readable exports include `to_dict()`, `to_json()`, and `to_csv()`, with CSV output specifically neutralized to prevent formula injection.
- The orchestrator in [`user_scanner/core/orchestrator.py`](https://github.com/kaifcodec/user-scanner/blob/main/user_scanner/core/orchestrator.py) enriches raw results with `username`, `site_name`, `category`, and URL data before display.

## Frequently Asked Questions

### What does the `[!]` icon mean in user-scanner output?

The `[!]` icon indicates an `ERROR` status, meaning the site module could not complete the check due to network issues, rate limiting, or site structure changes. The specific failure reason appears in parentheses immediately after the site name, providing diagnostic context for troubleshooting connection timeouts or HTTP errors.

### How do I export user-scanner results to CSV safely?

Use the `Result.to_csv()` method, which automatically neutralizes dangerous leading characters (`=`, `+`, `-`, `@`) by prefixing them with a tab character. This sanitization prevents CSV injection attacks when opening results in spreadsheet applications like Excel or Google Sheets.

### Why do some results show as `[~]` SKIPPED instead of checking the site?

Results marked with `[~]` indicate the `SKIPPED` status, triggered when a site module is intentionally bypassed. This commonly occurs with "loud" sites that might alert the target or cause IP bans when the `--allow-loud` flag is not enabled, or when specific category filters exclude certain platforms from the scan.

### What is the difference between `to_dict()` and `to_json()` in the Result class?

`to_dict()` returns a native Python dictionary suitable for further processing or CSV conversion, while `to_json()` returns a pretty-printed JSON string ready for file export or API transmission. The dictionary method strips internal flags like `is_email` that are irrelevant to end users, ensuring clean data serialization.