Skip to main content

telegram-init-data

PyPI version Python versions PyPI Downloads License: MIT

Python library for parsing, validating, and signing Telegram Mini Apps initialization data on the server side. API-compatible in spirit with @tma.js/init-data-node.

Features

  • Validate init data signature and expiration
  • Parse URL-encoded init data into typed Python objects
  • Sign init data for testing and development
  • Full type hints
  • Optional FastAPI integration
  • Third-party validation (data signed by Telegram directly)

Installation

pip install telegram-init-data

With FastAPI support:

pip install telegram-init-data[fastapi]

Quick Start

Validation

from telegram_init_data import validate, parse

bot_token = "YOUR_BOT_TOKEN"
init_data = "query_id=AAHdF6IQAAAAAN0XohDhrOrc&user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%7D&auth_date=1662771648&hash=c501b71e775f74ce10e377dea85a7ea24ecd640b223ea86dfe453e0eaed2e2b2"

try:
    validate(init_data, bot_token)
    parsed = parse(init_data)
    print(parsed["user"]["first_name"])
except Exception as e:
    print(f"Validation failed: {e}")

FastAPI

from fastapi import FastAPI, Depends, HTTPException
from telegram_init_data import validate, parse

app = FastAPI()

def verify_init_data(init_data: str) -> dict:
    bot_token = "YOUR_BOT_TOKEN"
    try:
        validate(init_data, bot_token)
        return parse(init_data)
    except Exception as e:
        raise HTTPException(status_code=401, detail=str(e))

@app.post("/user/profile")
async def get_profile(init_data: dict = Depends(verify_init_data)):
    user = init_data.get("user")
    if not user:
        raise HTTPException(status_code=400, detail="User data not found")
    return {"user_id": user["id"], "name": user["first_name"]}

Signing (tests / development)

from telegram_init_data import sign, is_valid
from datetime import datetime

bot_token = "YOUR_BOT_TOKEN"

test_data = {
    "query_id": "test_query_id",
    "user": {
        "id": 123456789,
        "first_name": "John",
        "last_name": "Doe",
        "username": "johndoe",
        "language_code": "en",
    },
    "auth_date": datetime.now(),
}

signed_data = sign(test_data, bot_token, datetime.now())

if is_valid(signed_data, bot_token):
    print("Valid")

API Reference

validate(value, token, options=None)

Validate Telegram Mini App init data.

Parameter Type Description
value `str dict`
token str Bot token from @BotFather
options dict, optional expires_in (seconds, default 86400)

Raises: SignatureMissingError, AuthDateInvalidError, ExpiredError, SignatureInvalidError

is_valid(value, token, options=None)

Same checks as validate, returns bool instead of raising.

parse(value)

Parse init data into a structured object. Returns InitData.

sign(data, token, auth_date, options=None)

Sign init data for testing. Returns a URL-encoded string.

Types

class InitData(TypedDict):
    query_id: Optional[str]
    user: Optional[User]
    receiver: Optional[User]
    chat: Optional[Chat]
    chat_type: Optional[ChatType]
    chat_instance: Optional[str]
    start_param: Optional[str]
    can_send_after: Optional[int]
    auth_date: int
    hash: str
    signature: Optional[str]

class User(TypedDict):
    id: int
    first_name: str
    last_name: Optional[str]
    username: Optional[str]
    language_code: Optional[str]
    is_bot: Optional[bool]
    is_premium: Optional[bool]
    added_to_attachment_menu: Optional[bool]
    allows_write_to_pm: Optional[bool]
    photo_url: Optional[str]

class Chat(TypedDict):
    id: int
    type: ChatType
    title: Optional[str]
    username: Optional[str]
    photo_url: Optional[str]

class ChatType(str, Enum):
    SENDER = "sender"
    PRIVATE = "private"
    GROUP = "group"
    SUPERGROUP = "supergroup"
    CHANNEL = "channel"

Exceptions

Exception When
TelegramInitDataError Base class
AuthDateInvalidError Invalid or missing auth_date
SignatureInvalidError Signature mismatch
SignatureMissingError Missing hash / signature
ExpiredError Init data expired

Options

# Custom TTL (1 hour)
validate(init_data, bot_token, {"expires_in": 3600})

# Disable expiration check
validate(init_data, bot_token, {"expires_in": 0})

Testing

pip install -e ".[dev]"
pytest
pytest --cov=telegram_init_data --cov-report=html

Examples

See [examples/](examples/) for basic usage and a FastAPI app.

FastAPI with Authorization header

from fastapi import FastAPI, Depends, HTTPException, Header
from telegram_init_data import parse, is_valid

app = FastAPI()

def get_init_data(authorization: str = Header(None)):
    if not authorization:
        raise HTTPException(status_code=401, detail="Authorization header missing")
    if not authorization.startswith("tma "):
        raise HTTPException(status_code=401, detail="Invalid authorization format")

    init_data = authorization[4:]
    bot_token = "YOUR_BOT_TOKEN"

    if not is_valid(init_data, bot_token):
        raise HTTPException(status_code=401, detail="Invalid init data")

    return parse(init_data)

@app.get("/me")
async def get_current_user(init_data: dict = Depends(get_init_data)):
    user = init_data.get("user")
    if not user:
        raise HTTPException(status_code=400, detail="User data not found")
    return {
        "id": user["id"],
        "name": user.get("first_name", ""),
        "username": user.get("username"),
        "is_premium": user.get("is_premium", False),
    }

Development

git clone https://github.com/iCodeCraft/telegram-init-data.git
cd telegram-init-data
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
pytest
black telegram_init_data tests
isort telegram_init_data tests
mypy telegram_init_data

License

MIT. See LICENSE.

Changelog

See CHANGELOG.md.

Metadata

Release files for telegram-init-data 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for telegram-init-data 1.1.0
File Size Uploaded
telegram_init_data-1.1.0.tar.gz 16.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for telegram-init-data 1.1.0
File Interpreter ABI Platform
telegram_init_data-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.3 kB

Release files / telegram_init_data-1.1.0.tar.gz

Download URL telegram_init_data-1.1.0.tar.gz
Size 16.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a42e66e422145b70ef90dd172f2b82c221acf7f5c4f754e0be7ecf9bdd170bff
BLAKE2b-256 checksum
How to use checksums
99666261f370cde758539eb21c7fb6c868946babba5c741262dbb7b3712158a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.0

Release files / telegram_init_data-1.1.0-py3-none-any.whl

Download URL telegram_init_data-1.1.0-py3-none-any.whl
Size 15.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17494c62a3f85bade8ddeea3c5e1f89cfd46d632b2c0ff226adcac78ef22a598
BLAKE2b-256 checksum
How to use checksums
55391b22839b2d26664b25027d320bc0336b8171ebc77462a5015d6e575cf417
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.0

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page