From 08da1a9492bcec1ee3265200d79bcf232e6e1c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 06:58:28 +0200 Subject: [PATCH 01/24] Add .editorconfig for consistent coding styles --- .editorconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..561c0be --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{js,php,py}] +indent_style = space +indent_size = 4 From 8c12297192bfe616fb396287e3da3422593a8c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 06:59:06 +0200 Subject: [PATCH 02/24] Create .gitignore with standard ignore patterns Add common ignore patterns for Node, Python, PHP, OS, IDE, and temporary files. --- .gitignore | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0eef7fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Node / JavaScript +node_modules/ +dist/ +npm-debug.log +yarn-error.log +package-lock.json +yarn.lock + +# Python +__pycache__/ +*.pyc +*.pyo +*.pyd + +# PHP +vendor/ +*.log + +# Logs +*.log + +# OS +.DS_Store +Thumbs.db +Desktop.ini + +# IDE +.vscode/ +.idea/ + +# Temp files +*.tmp +*.swp + +# GitHub Pages / Build cache +.sass-cache/ +.cache/ + +# Ignore tg_points.json if you don’t want to push updates automatically +# data/tg_points.json From 65c55acee69da8b1b2004afb9e07682042a723c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:00:11 +0200 Subject: [PATCH 03/24] Add accuracy and limitations section to accuracy.md --- accuracy.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 accuracy.md diff --git a/accuracy.md b/accuracy.md new file mode 100644 index 0000000..06e6eda --- /dev/null +++ b/accuracy.md @@ -0,0 +1,60 @@ +# Accuracy & Limitations + +CreationDate estimates Telegram account creation dates based on +a long-term collected dataset of Telegram **private user accounts** +with known creation periods. + +The estimation uses linear interpolation between verified UserID +anchor points. + +--- + +## How Accurate Is It? + +The dataset was collected and refined over several years and includes +only **private user accounts** (no bots, groups, or channels). + +Typical accuracy: + +- **Year accuracy:** very high +- **Month accuracy:** very high +- **Granularity:** usually within weeks +- **Older accounts:** may vary slightly more, but still reliable on a monthly level + +In most cases, the estimated creation date closely reflects the real +account creation period. + +--- + +## Why This Is Still an Estimate + +Telegram does not publicly expose exact account creation dates. + +While UserIDs are assigned sequentially, the allocation rate is not +perfectly constant over time. + +Factors that can affect precision: + +- Variations in Telegram user growth rate +- Internal Telegram ID allocation behavior +- Large-scale onboarding waves + +--- + +## Limitations + +- Only **private user accounts** are supported +- Bot accounts are intentionally excluded +- Groups and channels are not supported + (IDs starting with `-100...` are invalid) +- Negative or non-user UserIDs are rejected + +--- + +## Important Notice + +This project provides **high-quality estimates**, not official data. + +Dates should not be treated as legally or technically authoritative. + +Use this information responsibly. From ffc1cb63bde6cf9d1175ac6b44cb5cc8ef279cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:03:29 +0200 Subject: [PATCH 04/24] Create CODE_OF_CONDUCT.md for community guidelines Added a Code of Conduct to guide community contributions. --- .github/CODE_OF_CONDUCT.md | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..59a33f5 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,41 @@ +# Contributing to CreationDate + +Thank you for your interest in contributing to CreationDate! Contributions from the community help improve this project and make it more useful for everyone. + +## How to Contribute + +### 1. Reporting Bugs +* Check the [Issues](https://github.com/wizardloop/CreationDate/issues) to see if the bug has already been reported. +* If not, open a new issue with a clear description of the problem and steps to reproduce it. + +### 2. Suggesting Features +* Open an issue with your feature request. +* Include a clear description and, if possible, examples of how it would work. + +### 3. Submitting Pull Requests +* Fork the repository and clone it to your local machine. +* Create a new branch for your changes: `git checkout -b feature-name`. +* Make your changes with clear commit messages. +* Test your changes locally. +* Push your branch and submit a Pull Request (PR) to the `main` branch. + +### 4. Adding UserID Points +* Update `data/tg_points.json` with additional Telegram UserID points. +* Ensure the JSON format remains valid. + +### 5. Improving Documentation +* Suggestions or corrections to the README or other documentation are welcome. +* Update examples, formatting, or clarity. + +### 6. Code Style +* Keep code clean and readable. +* Use consistent indentation and naming conventions. +* Add comments where necessary. + +### 7. License and Code of Conduct +* By contributing, you agree that your contributions will be licensed under the [MIT License](https://github.com/wizardloop/CreationDate/LICENSE). +* Follow the [Code of Conduct](https://github.com/wizardloop/CreationDate/.github/CODE_OF_CONDUCT.md) when interacting with the community. + +--- + +We appreciate all contributions, big or small! Thank you for helping improve CreationDate. From b685453b904155b6bfa0e7e65c2b37aa53893a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:05:21 +0200 Subject: [PATCH 05/24] Update CONTRIBUTING.md --- .github/{CODE_OF_CONDUCT.md => CONTRIBUTING.md} | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename .github/{CODE_OF_CONDUCT.md => CONTRIBUTING.md} (90%) diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CONTRIBUTING.md similarity index 90% rename from .github/CODE_OF_CONDUCT.md rename to .github/CONTRIBUTING.md index 59a33f5..6aa8006 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CONTRIBUTING.md @@ -1,6 +1,8 @@ # Contributing to CreationDate -Thank you for your interest in contributing to CreationDate! Contributions from the community help improve this project and make it more useful for everyone. +Thank you for your interest in contributing to CreationDate! + +Contributions from the community help improve this project and make it more useful for everyone. ## How to Contribute From 2aa9a973c58f87406d57cbfca85433dc689a5171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:06:52 +0200 Subject: [PATCH 06/24] Create pull request template Added a pull request template to guide contributors. --- .github/PULL_REQUEST_TEMPLATE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..2cd5e58 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,21 @@ +## Description + +Please include a summary of the changes and the related issue. +Please also include relevant motivation and context. + +Fixes # (issue) + +## Type of Change + +- [ ] Bug fix +- [ ] New feature +- [ ] Documentation update +- [ ] Code refactor +- [ ] Other (please describe): + +## Checklist + +- [ ] My code follows the project’s code style +- [ ] I have tested my changes locally +- [ ] I have added necessary documentation +- [ ] I have updated CHANGELOG.md if applicable From b41ac9b84ad4b305753763e7e238f5a2592a906e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:07:28 +0200 Subject: [PATCH 07/24] Create SECURITY.md for security policy Add a security policy document for reporting vulnerabilities and supported versions. --- .github/SECURITY.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..7199779 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Reporting a Vulnerability +If you discover a security vulnerability in CreationDate, please report it by contacting [wizardloop.t.me] immediately. + +Do not open a public issue with sensitive security information. + +## Supported Versions +All released versions are considered supported unless otherwise noted. From 55d47caa5fd4b999a0f9cd0ea2c44f17f850b018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:11:38 +0200 Subject: [PATCH 08/24] Create bug report template in ISSUE_TEMPLATE Added a bug report template to the issue tracker for better bug reporting. --- .github/ISSUE_TEMPLATE/bug_report.yml | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..8d3cd7e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,30 @@ +name: Bug report +description: Create a report to help us improve CreationDate +title: "[BUG] " +labels: bug +assignees: [] +body: + - type: markdown + attributes: + value: | + **Describe the bug** + A clear and concise description of what the bug is. + + **To Reproduce** + Steps to reproduce the behavior: + 1. Go to '...' + 2. Click on '...' + 3. See error + + **Expected behavior** + Describe what you expected to happen. + + **Screenshots** + If applicable, add screenshots to help explain your problem. + + **Environment (please complete the following information):** + - Browser / OS / Language: + - CreationDate version: + + **Additional context** + Add any other context about the problem here. From 0f33f2d7636038633a9c49a694b5efd258445883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:12:27 +0200 Subject: [PATCH 09/24] Create feature request issue template Add a feature request template for GitHub issues. --- .github/ISSUE_TEMPLATE/feature_request.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..88660af --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,17 @@ +name: Feature request +description: Suggest an idea for CreationDate +title: "[FEATURE] " +labels: enhancement +assignees: [] +body: + - type: markdown + attributes: + value: | + **Describe the feature** + A clear and concise description of what you want to happen. + + **Use Case** + Explain why this feature would be useful. + + **Additional context** + Add any other context or screenshots about the feature request here. From 067580d365ac604649766a82e99e0771acdd92f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:14:14 +0200 Subject: [PATCH 10/24] Enhance feature request template with new fields Updated feature request template to include additional fields for feature description and usage example. --- .github/ISSUE_TEMPLATE/feature_request.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 88660af..2c2472e 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -3,7 +3,24 @@ description: Suggest an idea for CreationDate title: "[FEATURE] " labels: enhancement assignees: [] +body:name: Feature Request +description: Suggest a new feature! +title: "[Feature] " +labels: [enhancement, feature] body: + - type: textarea + id: description + attributes: + label: Feature Description + description: Please describe the new feature you'd like to see. + validations: + required: true + - type: textarea + id: example + attributes: + label: Usage Example + description: Show a code example or output illustrating how this feature would work. + - type: markdown attributes: value: | From 20c07160566d5e2577b18952418421686537d085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:15:17 +0200 Subject: [PATCH 11/24] Revise feature request template for better usability Updated the feature request template to enhance clarity and engagement. --- .github/ISSUE_TEMPLATE/feature_request.yml | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 2c2472e..611b3fb 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,10 +1,5 @@ -name: Feature request -description: Suggest an idea for CreationDate -title: "[FEATURE] " -labels: enhancement -assignees: [] -body:name: Feature Request -description: Suggest a new feature! +name: Feature Request ✨ +description: Suggest a magical new feature! title: "[Feature] " labels: [enhancement, feature] body: @@ -21,14 +16,3 @@ body: label: Usage Example description: Show a code example or output illustrating how this feature would work. - - type: markdown - attributes: - value: | - **Describe the feature** - A clear and concise description of what you want to happen. - - **Use Case** - Explain why this feature would be useful. - - **Additional context** - Add any other context or screenshots about the feature request here. From 0740d5d9212efa8d71ca5b508d37a326a1d70528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:16:01 +0200 Subject: [PATCH 12/24] Revise bug report template for clarity and detail Updated bug report template with new structure and fields. --- .github/ISSUE_TEMPLATE/bug_report.yml | 53 +++++++++++++-------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 8d3cd7e..897f3f2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,30 +1,27 @@ -name: Bug report -description: Create a report to help us improve CreationDate -title: "[BUG] " -labels: bug -assignees: [] +name: Bug Report 🐞 +description: Report a bug or issue. +title: "[Bug] " +labels: [bug] body: - - type: markdown + - type: textarea + id: bug attributes: - value: | - **Describe the bug** - A clear and concise description of what the bug is. - - **To Reproduce** - Steps to reproduce the behavior: - 1. Go to '...' - 2. Click on '...' - 3. See error - - **Expected behavior** - Describe what you expected to happen. - - **Screenshots** - If applicable, add screenshots to help explain your problem. - - **Environment (please complete the following information):** - - Browser / OS / Language: - - CreationDate version: - - **Additional context** - Add any other context about the problem here. + label: What happened? + description: Clearly describe the problem and what you expected to happen. + validations: + required: true + - type: textarea + id: steps + attributes: + label: Steps to Reproduce + description: List the exact steps to reproduce this bug. + - type: input + id: env + attributes: + label: Environment + description: PHP version and OS. + - type: textarea + id: logs + attributes: + label: Relevant logs/output + description: Include any output or error logs if relevant. From b2f254eb6d6c40e341c09ae2a76176a13ce374d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 07:16:42 +0200 Subject: [PATCH 13/24] Add improvement/question issue template This template allows users to suggest improvements or ask questions, with fields for description and PR submission intent. --- .../ISSUE_TEMPLATE/improvement_question.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/improvement_question.yml diff --git a/.github/ISSUE_TEMPLATE/improvement_question.yml b/.github/ISSUE_TEMPLATE/improvement_question.yml new file mode 100644 index 0000000..c01c501 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/improvement_question.yml @@ -0,0 +1,18 @@ +name: Improvement / Question πŸ€” +description: Suggest an improvement or ask a question. +title: "[Q] " +labels: [question, improvement] +body: + - type: textarea + id: description + attributes: + label: Description / Question + description: Clearly describe your suggestion or question. + validations: + required: true + - type: checkboxes + id: pr + attributes: + label: Are you planning to submit a PR? + options: + - label: Yes, I will submit a PR with this improvement/answer. From 13c6b737928ff7424adc4c3b1223a06f7876f7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:21:14 +0200 Subject: [PATCH 14/24] Add estimateCreationDate and interpolate functions --- examples/php/estimate.php | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 examples/php/estimate.php diff --git a/examples/php/estimate.php b/examples/php/estimate.php new file mode 100644 index 0000000..686f624 --- /dev/null +++ b/examples/php/estimate.php @@ -0,0 +1,43 @@ + $a[0] <=> $b[0]); + + if ($userId <= $points[0][0]) { + return new DateTimeImmutable($points[0][1]); + } + + foreach ($points as $i => $p) { + if (!isset($points[$i+1])) break; + + [$id1, $d1] = $points[$i]; + [$id2, $d2] = $points[$i+1]; + + if ($userId >= $id1 && $userId <= $id2) { + return interpolate($userId, $id1, $d1, $id2, $d2); + } + } + + [$id1, $d1] = $points[count($points)-2]; + [$id2, $d2] = $points[count($points)-1]; + + return interpolate($userId, $id1, $d1, $id2, $d2); +} + +function interpolate(int $uid, int $id1, string $d1, int $id2, string $d2): DateTimeImmutable +{ + if ($id1 === $id2) { + return new DateTimeImmutable($d1); + } + + $t1 = strtotime($d1); + $t2 = strtotime($d2); + $ratio = ($uid - $id1) / ($id2 - $id1); + + $ts = (int) ($t1 + ($t2 - $t1) * $ratio); + $res = (new DateTimeImmutable())->setTimestamp($ts); + + return $res > new DateTimeImmutable() ? new DateTimeImmutable() : $res; +} From 8d8fefcadba008dc8d23cd55fba16e417bf3194e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:21:51 +0200 Subject: [PATCH 15/24] Implement date estimation functions in estimate.py Add functions to estimate telegram creation date based on user ID and points. --- examples/php/estimate.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 examples/php/estimate.py diff --git a/examples/php/estimate.py b/examples/php/estimate.py new file mode 100644 index 0000000..4c0d755 --- /dev/null +++ b/examples/php/estimate.py @@ -0,0 +1,29 @@ +from datetime import datetime + +def interpolate(uid, id1, d1, id2, d2): + if id1 == id2: + return datetime.fromisoformat(d1) + + t1 = datetime.fromisoformat(d1).timestamp() + t2 = datetime.fromisoformat(d2).timestamp() + + ratio = (uid - id1) / (id2 - id1) + ts = t1 + (t2 - t1) * ratio + + result = datetime.fromtimestamp(ts) + return min(result, datetime.utcnow()) + +def estimate_telegram_creation_date(user_id, points): + points.sort(key=lambda x: x[0]) + + if user_id <= points[0][0]: + return datetime.fromisoformat(points[0][1]) + + for i in range(len(points)-1): + id1, d1 = points[i] + id2, d2 = points[i+1] + + if id1 <= user_id <= id2: + return interpolate(user_id, id1, d1, id2, d2) + + return interpolate(user_id, *points[-2], *points[-1]) From 9a3ac9baba306a7b69a0301bb3084bcc94f6b93e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:22:20 +0200 Subject: [PATCH 16/24] Delete examples/php/estimate.py --- examples/php/estimate.py | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 examples/php/estimate.py diff --git a/examples/php/estimate.py b/examples/php/estimate.py deleted file mode 100644 index 4c0d755..0000000 --- a/examples/php/estimate.py +++ /dev/null @@ -1,29 +0,0 @@ -from datetime import datetime - -def interpolate(uid, id1, d1, id2, d2): - if id1 == id2: - return datetime.fromisoformat(d1) - - t1 = datetime.fromisoformat(d1).timestamp() - t2 = datetime.fromisoformat(d2).timestamp() - - ratio = (uid - id1) / (id2 - id1) - ts = t1 + (t2 - t1) * ratio - - result = datetime.fromtimestamp(ts) - return min(result, datetime.utcnow()) - -def estimate_telegram_creation_date(user_id, points): - points.sort(key=lambda x: x[0]) - - if user_id <= points[0][0]: - return datetime.fromisoformat(points[0][1]) - - for i in range(len(points)-1): - id1, d1 = points[i] - id2, d2 = points[i+1] - - if id1 <= user_id <= id2: - return interpolate(user_id, id1, d1, id2, d2) - - return interpolate(user_id, *points[-2], *points[-1]) From 37f8cc329f10e37dda563f6c8a3be7003531458b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:22:50 +0200 Subject: [PATCH 17/24] Add estimate.py for estimating creation dates --- examples/python/estimate.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 examples/python/estimate.py diff --git a/examples/python/estimate.py b/examples/python/estimate.py new file mode 100644 index 0000000..4c0d755 --- /dev/null +++ b/examples/python/estimate.py @@ -0,0 +1,29 @@ +from datetime import datetime + +def interpolate(uid, id1, d1, id2, d2): + if id1 == id2: + return datetime.fromisoformat(d1) + + t1 = datetime.fromisoformat(d1).timestamp() + t2 = datetime.fromisoformat(d2).timestamp() + + ratio = (uid - id1) / (id2 - id1) + ts = t1 + (t2 - t1) * ratio + + result = datetime.fromtimestamp(ts) + return min(result, datetime.utcnow()) + +def estimate_telegram_creation_date(user_id, points): + points.sort(key=lambda x: x[0]) + + if user_id <= points[0][0]: + return datetime.fromisoformat(points[0][1]) + + for i in range(len(points)-1): + id1, d1 = points[i] + id2, d2 = points[i+1] + + if id1 <= user_id <= id2: + return interpolate(user_id, id1, d1, id2, d2) + + return interpolate(user_id, *points[-2], *points[-1]) From 6724a4b0d0c0e74a29bc8e6cc9957897391f449a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:23:46 +0200 Subject: [PATCH 18/24] Add README for UserID reference dataset This README provides detailed information about the Telegram UserID reference dataset, including its origin, accuracy, format, usage, limitations, and contribution guidelines. --- data/README.md | 119 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 data/README.md diff --git a/data/README.md b/data/README.md new file mode 100644 index 0000000..29c119d --- /dev/null +++ b/data/README.md @@ -0,0 +1,119 @@ +# Telegram UserID Reference Dataset + +This directory contains the core dataset used by **CreationDate** +to estimate Telegram account creation dates. + +The main file is: + +- `tg_points.json` + +It serves as a reference map between Telegram **private user IDs** +and their known or strongly verified creation periods. + +--- + +## Data Origin + +The dataset was collected and refined over several years through +long-term observation. + +It is based on **real private Telegram user accounts** whose creation +periods are known or can be reliably inferred. + +No private Telegram APIs, leaked databases, or automated scraping +methods were used. + +--- + +## What This Dataset Includes + +- βœ… Private Telegram user accounts only +- ❌ No bots +- ❌ No groups +- ❌ No channels +- ❌ No service or system accounts + +UserIDs belonging to groups or channels +(e.g. IDs starting with `-100...`) are intentionally excluded. + +--- + +## Accuracy Characteristics + +- **Year accuracy:** very high +- **Month accuracy:** very high +- **Typical deviation:** weeks +- **Older accounts:** slightly wider margin, still reliable on a monthly level + +This dataset is optimized for **temporal accuracy**, not completeness. + +--- + +## Data Format + +Each entry in `tg_points.json` follows this structure: + +```json +[user_id, "YYYY-MM-DD"] +``` + +Example: + +```json +[2768409, "2013-11-01"] +``` + +Where: + +- `user_id` is a Telegram private user ID +- `YYYY-MM-DD` represents the account creation date or period anchor + +The file must remain: +- Valid JSON +- Chronologically consistent +- Sorted or sortable by UserID + +--- + +## How It Is Used + +These reference points act as **anchor nodes**. + +CreationDate estimates unknown UserIDs by applying +**linear interpolation** between the closest known points. + +Accuracy improves as: +- More anchor points are added +- Coverage across different years increases + +--- + +## Limitations + +- The dataset does **not** represent all Telegram users +- Dates are **estimates**, not official Telegram data +- Precision depends on surrounding anchor density + +--- + +## Contributing Data + +If you wish to contribute: + +- Only include **private user accounts** +- Exclude bots, groups, and channels +- Ensure dates are reasonable and verifiable +- Maintain chronological consistency + +Please follow the guidelines in: + +`.github/CONTRIBUTING.md` + +--- + +## Legal & Ethical Notice + +This dataset does **not** contain personal data beyond numeric UserIDs +and estimated creation periods. + +It is intended for research, development, and educational purposes only. From e8579bb989255122f7a0a57b1668df07c1d93a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:24:27 +0200 Subject: [PATCH 19/24] Add JSON schema for UserID reference Defines a JSON schema for Telegram private user ID anchor points, including validation rules and examples. --- data/schema.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 data/schema.json diff --git a/data/schema.json b/data/schema.json new file mode 100644 index 0000000..6909549 --- /dev/null +++ b/data/schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Telegram UserID Reference Point", + "description": "Schema for Telegram private user ID anchor points used for creation date estimation.", + "type": "array", + "items": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": [ + { + "type": "integer", + "description": "Telegram private user ID", + "minimum": 1 + }, + { + "type": "string", + "description": "Observed account creation date (YYYY-MM-DD)", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$" + } + ] + }, + "examples": [ + [2768409, "2013-11-01"], + [805158066, "2019-07-15"], + [6926984452, "2024-01-09"] + ] +} From f37728802d3607307c65c16750a8e5efc33aa4cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:25:08 +0200 Subject: [PATCH 20/24] Add tg_points.json with timestamped data Added a JSON file containing timestamped data points. --- data/tg_points.json | 214 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 data/tg_points.json diff --git a/data/tg_points.json b/data/tg_points.json new file mode 100644 index 0000000..19e1690 --- /dev/null +++ b/data/tg_points.json @@ -0,0 +1,214 @@ +[ + [0, "2013-08-14"], + [2768409, "2013-11-01"], + [7679610, "2013-12-31"], + [11538514, "2014-02-01"], + [15835244, "2014-02-20"], + [23646077, "2014-02-26"], + [38015510, "2014-03-01"], + [44634663, "2014-05-06"], + [46145305, "2014-05-15"], + [54845238, "2014-09-20"], + [63263518, "2014-10-27"], + [101260938, "2015-03-06"], + [101323197, "2015-03-13"], + [111220210, "2015-04-21"], + [103258382, "2015-05-27"], + [103151531, "2015-06-03"], + [116812045, "2015-07-23"], + [122600695, "2015-07-24"], + [109393468, "2015-08-08"], + [112594714, "2015-08-15"], + [124872445, "2015-08-17"], + [130029930, "2015-09-03"], + [125828524, "2015-10-05"], + [133909606, "2015-10-07"], + [157242073, "2015-11-06"], + [143445125, "2015-12-01"], + [148670295, "2016-01-08"], + [152079341, "2016-01-22"], + [171295414, "2016-03-09"], + [181783990, "2016-04-10"], + [222021233, "2016-06-08"], + [225034354, "2016-06-18"], + [278941742, "2016-09-10"], + [285253072, "2016-10-18"], + [294851037, "2016-11-19"], + [297621225, "2016-12-16"], + [328594461, "2017-01-28"], + [337808429, "2017-02-21"], + [341546272, "2017-02-22"], + [352940995, "2017-02-24"], + [369669043, "2017-03-31"], + [400169472, "2017-07-31"], + [805158066, "2019-07-15"], + [1974255900, "2021-10-12"], + [5031711230, "2021-12-06"], + [5022636255, "2021-12-10"], + [5045293264, "2022-01-13"], + [5070164216, "2022-01-19"], + [5149590651, "2022-01-22"], + [5177789190, "2022-01-24"], + [5288930461, "2022-01-27"], + [5207110227, "2022-02-03"], + [5210565134, "2022-02-09"], + [5196353812, "2022-02-15"], + [5124771193, "2022-02-22"], + [5170390109, "2022-02-28"], + [5169485538, "2022-03-01"], + [5260388619, "2022-03-02"], + [5106451106, "2022-03-05"], + [5179102906, "2022-03-12"], + [5155903109, "2022-03-22"], + [5268253519, "2022-03-22"], + [5153900870, "2022-03-22"], + [5047148663, "2022-04-05"], + [5144324763, "2022-04-06"], + [5244529493, "2022-04-19"], + [5396515972, "2022-04-21"], + [5308260177, "2022-04-25"], + [5349830748, "2022-04-29"], + [5271530336, "2022-04-30"], + [5259159476, "2022-05-06"], + [5166844465, "2022-05-09"], + [5394432429, "2022-05-23"], + [5351497367, "2022-05-24"], + [5505809357, "2022-05-27"], + [5433708969, "2022-05-28"], + [5488407539, "2022-05-29"], + [5598262640, "2022-06-11"], + [5596032583, "2022-06-16"], + [5159326926, "2022-06-16"], + [5434011049, "2022-06-29"], + [5542245357, "2022-07-07"], + [5428357996, "2022-07-11"], + [5468950164, "2022-07-14"], + [5468433192, "2022-07-20"], + [5442755368, "2022-07-23"], + [5546930145, "2022-07-24"], + [5363536419, "2022-08-01"], + [5451256696, "2022-08-06"], + [5519218712, "2022-08-14"], + [5694365966, "2022-08-28"], + [5721138769, "2022-09-23"], + [5601951167, "2022-10-02"], + [5515826405, "2022-10-03"], + [5705427359, "2022-10-06"], + [5735455201, "2022-10-07"], + [5744374534, "2022-10-10"], + [5681900282, "2022-10-17"], + [5595045952, "2022-10-23"], + [5340744210, "2022-10-26"], + [5765259845, "2022-10-30"], + [5558980075, "2022-10-30"], + [5472518401, "2022-11-02"], + [5795660441, "2022-11-06"], + [5559594088, "2022-11-10"], + [5931294587, "2022-11-19"], + [5859861622, "2022-11-19"], + [5627539474, "2022-12-02"], + [5862080962, "2022-12-13"], + [5839137822, "2022-12-16"], + [5983753471, "2022-12-23"], + [5815100469, "2022-12-29"], + [5964221956, "2023-01-09"], + [5806925457, "2023-01-12"], + [5567880858, "2023-01-25"], + [6271031786, "2023-02-12"], + [6254094947, "2023-02-27"], + [5804028268, "2023-03-05"], + [6277658932, "2023-03-17"], + [5802659303, "2023-03-21"], + [5869978651, "2023-03-24"], + [5738347976, "2023-04-25"], + [5854845236, "2023-04-27"], + [6074830852, "2023-05-01"], + [5891297818, "2023-05-04"], + [6175817126, "2023-05-07"], + [6001287799, "2023-05-10"], + [5994561143, "2023-05-16"], + [6108395402, "2023-05-18"], + [5904140174, "2023-05-20"], + [6135597783, "2023-05-24"], + [6180394472, "2023-05-29"], + [6000582627, "2023-05-30"], + [6188508923, "2023-06-22"], + [6326011828, "2023-07-07"], + [6523424924, "2023-08-02"], + [6684986493, "2023-09-25"], + [6765129195, "2023-11-02"], + [6827058708, "2023-11-06"], + [6514802524, "2023-11-16"], + [6749492866, "2023-11-22"], + [6401027363, "2023-11-25"], + [6451891234, "2023-12-02"], + [6513268158, "2023-12-02"], + [6829119388, "2023-12-02"], + [6947316117, "2023-12-15"], + [6545049031, "2023-12-19"], + [6926984452, "2024-01-09"], + [6536173556, "2024-01-11"], + [6670760749, "2024-01-14"], + [6903333095, "2024-01-31"], + [6854829938, "2024-02-01"], + [6715889959, "2024-02-05"], + [6732829831, "2024-02-11"], + [6559717847, "2024-02-25"], + [6720229740, "2024-03-17"], + [6606876583, "2024-03-17"], + [7002435197, "2024-04-06"], + [7104310277, "2024-04-19"], + [6703731755, "2024-05-05"], + [7085776398, "2024-05-10"], + [6651640269, "2024-05-18"], + [6872061796, "2024-05-25"], + [7242296450, "2024-05-29"], + [7254607307, "2024-06-10"], + [7293965553, "2024-06-16"], + [7409259451, "2024-06-20"], + [7280136256, "2024-07-04"], + [7363299295, "2024-07-25"], + [7224009547, "2024-08-02"], + [7458668365, "2024-08-02"], + [7243375923, "2024-08-25"], + [7078066115, "2024-09-08"], + [7357703634, "2024-09-10"], + [7832006200, "2024-09-19"], + [7793034911, "2024-09-23"], + [7747102337, "2024-11-06"], + [7831448272, "2024-11-11"], + [7273085448, "2024-11-21"], + [7450316621, "2024-12-02"], + [7664959631, "2024-12-19"], + [7342300216, "2025-01-16"], + [7825518194, "2025-01-16"], + [8173852075, "2025-02-21"], + [8135088730, "2025-03-05"], + [8044853035, "2025-03-20"], + [7591351660, "2025-03-21"], + [7964511972, "2025-03-26"], + [7899152800, "2025-04-08"], + [7708562823, "2025-05-10"], + [7829910989, "2025-05-11"], + [7852083588, "2025-06-02"], + [7870888707, "2025-06-08"], + [7817256746, "2025-06-18"], + [7915901421, "2025-07-07"], + [8179125032, "2025-07-09"], + [8238766847, "2025-07-31"], + [8343786378, "2025-08-08"], + [8369442459, "2025-08-08"], + [8096742229, "2025-08-31"], + [7834356221, "2025-09-01"], + [8461579295, "2025-09-11"], + [8200159552, "2025-09-12"], + [7912577935, "2025-09-15"], + [8017192943, "2025-10-05"], + [8325327280, "2025-10-13"], + [8117852491, "2025-10-14"], + [8384648263, "2025-10-23"], + [8393200797, "2025-10-25"], + [8209194945, "2025-10-26"], + [8480708838, "2025-11-05"], + [8559682245, "2025-11-11"] +] From fc940a482cf8633204103b9fc6cdf07ef70f3216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?= <67387949+WizardLoop@users.noreply.github.com> Date: Sun, 25 Jan 2026 08:49:28 +0200 Subject: [PATCH 21/24] Add initial HTML structure for Creation Date API --- api/index.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 api/index.html diff --git a/api/index.html b/api/index.html new file mode 100644 index 0000000..e8affd5 --- /dev/null +++ b/api/index.html @@ -0,0 +1,12 @@ + + + + +Creation Date API + + + +

+
+
+

From 4aa841d946d4275d44611f62d109706490e93858 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?=
 <67387949+WizardLoop@users.noreply.github.com>
Date: Sun, 25 Jan 2026 09:58:37 +0200
Subject: [PATCH 22/24] Add Creation date estimation functionality

---
 api/api.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 api/api.js

diff --git a/api/api.js b/api/api.js
new file mode 100644
index 0000000..ded1179
--- /dev/null
+++ b/api/api.js
@@ -0,0 +1,62 @@
+const urlParams = new URLSearchParams(window.location.search);
+const useridStr = urlParams.get('userid');
+
+function sendJSON(obj){
+    document.body.innerHTML = '';
+    const pre = document.createElement('pre');
+    pre.textContent = JSON.stringify(obj, null, 2);
+    document.body.appendChild(pre);
+}
+
+function estimateTelegramCreationDate(userId, points){
+    points.sort((a,b)=>a[0]-b[0]);
+    if(userId <= points[0][0]) return new Date(points[0][1]);
+
+    for(let i=0;i= id1 && userId <= id2) return interpolate(userId,id1,date1,id2,date2);
+    }
+
+    const [id1,date1] = points[points.length-2], [id2,date2] = points[points.length-1];
+    return interpolate(userId,id1,date1,id2,date2);
+}
+
+function interpolate(userId,id1,date1,id2,date2){
+    if(id1===id2) return new Date(date1);
+    const t1 = new Date(date1).getTime(), t2 = new Date(date2).getTime();
+    const ts = t1 + (t2-t1)*((userId-id1)/(id2-id1));
+    const result = new Date(ts);
+    return result > new Date() ? new Date() : result;
+}
+
+function getAccountAgeString(createdDate){
+    const now = new Date();
+    let years = now.getFullYear() - createdDate.getFullYear();
+    let months = now.getMonth() - createdDate.getMonth();
+    if(months < 0){ years--; months += 12; }
+    if(years >= 1) return `${years} ${years===1?'year':'years'}`;
+    if(months >= 1) return `${months} ${months===1?'month':'months'}`;
+    return 'less than a month';
+}
+
+if(!useridStr || isNaN(useridStr)){
+    sendJSON({error:"Invalid userid"});
+} else if(useridStr.startsWith('-')){
+    sendJSON({error:"Invalid userid (cannot start with -)"});
+} else {
+    const userid = parseInt(useridStr,10);
+    fetch('../data/tg_points.json')
+        .then(res => res.json())
+        .then(points => {
+            const creationDate = estimateTelegramCreationDate(userid, points);
+            sendJSON({
+                userid,
+                creation_date: creationDate.toISOString().split('T')[0],
+                account_age: getAccountAgeString(creationDate)
+            });
+        })
+        .catch(err => {
+            console.error(err);
+            sendJSON({error:"Cannot load tg_points.json"});
+        });
+}

From 75917a6fb59f14e18f2e2f12038905d60b546906 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?=
 <67387949+WizardLoop@users.noreply.github.com>
Date: Sun, 25 Jan 2026 10:03:18 +0200
Subject: [PATCH 23/24] Add initial changelog for version 1.0.0

Documented the initial release of the project and its features.
---
 CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 CHANGELOG.md

diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..3e8ddaf
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,37 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+---
+
+## [1.0.0] - 2026-01-25
+
+### Added
+- Initial release of **CreationDate**
+- Browser-based API to estimate Telegram user creation dates from UserID
+- JSON dataset of Telegram accounts (`data/tg_points.json`)
+- Core estimation algorithm implemented in:
+  - PHP (`examples/php/estimate.php`)
+  - Python (`examples/python/estimate.py`)
+- Static API interface (`api/index.html` + `api.js`)
+- Documentation (`README.md`, `data/README.md`)
+- Schema file for dataset (`data/schema.json`)
+- Contribution guidelines (`.github/CONTRIBUTING.md`)
+- Code of Conduct (`.github/CODE_OF_CONDUCT.md`)
+- Security policy (`.github/SECURITY.md`)
+- GitHub issue templates:
+  - Bug report
+  - Feature request
+  - Improvement / question
+- Pull Request template
+- `.gitignore` configured for multiple environments (Node, Python, logs, OS, IDE)
+
+### Changed
+- N/A (first release)
+
+### Fixed
+- N/A (first release)
+
+---
+
+

From b1c4cf9dbbfe616e8089a7d94457407e0896e1f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wizard=20Loop=20=F0=9F=A7=99=E2=80=8D=E2=99=82=EF=B8=8F?=
 <67387949+WizardLoop@users.noreply.github.com>
Date: Sun, 25 Jan 2026 10:13:00 +0200
Subject: [PATCH 24/24] Enhance README with project details and usage examples

Updated README.md to include project overview, features, API usage, and contribution guidelines.
---
 README.md | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 256 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 1567dcb..dc0084e 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,257 @@
 # CreationDate
-CreationDate is an open-source, lightweight project that estimates the creation date of Telegram account.
+
+[![Accuracy](https://img.shields.io/badge/accuracy-weeks_to_month-green)](#accuracy--limitations)
+[![Platform](https://img.shields.io/badge/platform-browser%20%7C%20static-lightgrey)](#api-usage)
+[![Status](https://img.shields.io/badge/status-stable-brightgreen)](#)
+
+[![GitHub issues](https://img.shields.io/github/issues/wizardloop/CreationDate)](https://github.com/wizardloop/CreationDate/issues)
+[![License](https://img.shields.io/github/license/wizardloop/CreationDate)](LICENSE)
+[![GitHub stars](https://img.shields.io/github/stars/wizardloop/CreationDate?style=social)](https://github.com/wizardloop/CreationDate)
+[![GitHub forks](https://img.shields.io/github/forks/wizardloop/CreationDate?style=social)](https://github.com/wizardloop/CreationDate)
+
+---
+
+## Overview
+
+**CreationDate** is a lightweight, browser-based API and dataset for estimating  
+the **creation date of Telegram private user accounts** using only their numeric **UserID**.
+
+The project is based on a curated dataset of Telegram accounts with **known creation dates**,  
+collected over several years, and applies **linear interpolation** to estimate unknown accounts.
+
+No Telegram API, no authentication, no backend, no rate limits.
+
+---
+
+## Features
+
+- Estimate Telegram account creation date from UserID
+- Returns exact date (`YYYY-MM-DD`) and human-readable account age
+- Fully client-side (static files only)
+- Reusable core algorithm (PHP / Python examples included)
+- Easy GitHub Pages deployment
+- Transparent and auditable dataset
+
+---
+
+⚠️ **Notice**  
+This project provides **estimates only**, based on publicly observed UserID growth patterns.
+
+---
+
+## How It Works
+
+Telegram assigns numeric UserIDs in roughly ascending order over time.  
+CreationDate uses a reference dataset of known `(UserID β†’ creation date)` points.
+
+For a given UserID, the algorithm:
+
+1. Sorts known UserID points
+2. Finds the surrounding range
+3. Applies linear interpolation between timestamps
+4. Prevents future-dated results
+
+---
+
+## API Usage
+
+The API is fully static and browser-based.
+
+### Endpoint
+
+`/api/?userid=TELEGRAM_USER_ID`
+
+### Example
+
+https://wizardloop.github.io/CreationDate/api/?userid=208238248
+
+### Successful Response
+
+```json
+{
+  "userid": 208238248,
+  "creation_date": "2016-04-10",
+  "account_age": "8 years"
+}
+```
+
+### Error Response
+
+```json
+{
+  "error": "Invalid userid"
+}
+```
+
+---
+
+## Using the API from Code
+
+### JavaScript (Browser)
+
+```javascript
+fetch("https://wizardloop.github.io/CreationDate/api/?userid=208238248")
+  .then(res => res.json())
+  .then(data => console.log(data));
+```
+
+### PHP
+
+```php
+