CryptoBot Python
Unofficial but friendly Python client for the Crypto Bot API (v1.0 - stable). It provides typed models, sane defaults, and synchronous/async clients for invoices, transfers, checks, balances, exchange rates, statistics, and webhook handling.
Features
- Synchronous
httpx-based API client (CryptoBotClient) - Async
httpx-based API client (AsyncCryptoBotClient) - Dataclass models for API responses (
Invoice,Transfer,Check,Balance,ExchangeRate,Currency,AppStats) - Enum guard rails for assets, statuses, check statuses, and paid button names
- Mainnet/testnet support with configurable timeouts and retries
- Pagination iterators for invoices, transfers, and checks
- FastAPI-powered webhook listener with signature verification and optional replay protection
- Custom exception model (
CryptoBotError) with API code/name fields
Installation
Requires Python 3.10+.
Using uv (recommended)
uv add cryptobot-python
Using pip
pip install cryptobot-python
Extras
Install webhook server dependencies (FastAPI + Uvicorn) only when needed:
uv add "cryptobot-python[webhook]"
# or
pip install "cryptobot-python[webhook]"
Install documentation tooling extras:
uv add "cryptobot-python[docs]"
# or
pip install "cryptobot-python[docs]"
Quick Start
import os
from cryptobot import CryptoBotClient
from cryptobot.models import Asset
client = CryptoBotClient(
api_token=os.environ["CRYPTOBOT_API_TOKEN"],
is_mainnet=True,
timeout=5.0,
max_retries=2,
retry_backoff=0.5,
)
app = client.get_me()
print(app.name)
invoice = client.create_invoice(
asset=Asset.USDT,
amount=5.25,
description="Coffee order #42",
)
print(invoice.invoice_id, invoice.bot_invoice_url)
To use testnet instead of mainnet:
client = CryptoBotClient(api_token=os.environ["CRYPTOBOT_TESTNET_TOKEN"], is_mainnet=False)
Retry behavior is optional and disabled by default (max_retries=0). The default retryable status codes are
429, 500, 502, 503, 504.
client = CryptoBotClient(
api_token=os.environ["CRYPTOBOT_API_TOKEN"],
max_retries=3,
retry_backoff=0.5,
retryable_status_codes={429, 500, 502, 503, 504},
)
Async usage:
import asyncio
import os
from cryptobot import AsyncCryptoBotClient
from cryptobot.models import Asset
async def main():
async with AsyncCryptoBotClient(api_token=os.environ["CRYPTOBOT_API_TOKEN"], max_retries=2) as client:
app = await client.get_me()
print(app.name)
invoice = await client.create_invoice(asset=Asset.USDT, amount=5.25, description="Async order #42")
print(invoice.invoice_id, invoice.bot_invoice_url)
asyncio.run(main())
Core API
CryptoBotClient methods:
| Category | Methods |
|---|---|
| App | get_me() |
| Invoices | create_invoice(...), get_invoices(...), delete_invoice(...) |
| Transfers | transfer(...), get_transfers(...) |
| Checks | create_check(...), get_checks(...), delete_check(...) |
| Balance & Rates | get_balances(), get_exchange_rates(), get_currencies() |
| Statistics | get_stats(...) |
| Pagination | iter_invoice_pages(...), iter_invoices(...), iter_transfer_pages(...), iter_transfers(...), iter_check_pages(...), iter_checks(...) |
AsyncCryptoBotClient provides the same methods with await, plus async iterators for
all pagination helpers.
List methods like get_invoices(...), get_transfers(...), and get_checks(...) accept IDs as a
comma-separated string ("1,2,3") or list[int] ([1, 2, 3]).
Iterator helpers accept page_size and start_offset to support controlled pagination scans.
Transfer with idempotency
from cryptobot.errors import CryptoBotError
from cryptobot.models import Asset
try:
transfer = client.transfer(
user_id=123456789,
asset=Asset.TON,
amount=0.5,
spend_id="reward_2026_02_10_user_123456789",
comment="Cashback reward",
)
print(transfer.transfer_id, transfer.status)
except CryptoBotError as exc:
print(exc.code, exc.name)
Crypto checks
Create a check that any user (or a specific user) can activate:
from cryptobot.models import Asset
check = client.create_check(asset=Asset.USDT, amount=1.0)
print(check.check_id, check.bot_check_url)
# Pin a check to a specific user
check = client.create_check(asset=Asset.TON, amount=0.25, pin_to_user_id=123456789)
# List and delete checks
checks = client.get_checks(asset=Asset.USDT, status="active")
client.delete_check(check_id=checks[0].check_id)
App statistics
stats = client.get_stats(
start_at="2026-01-01T00:00:00Z",
end_at="2026-03-01T00:00:00Z",
)
print(stats.volume, stats.unique_users_count, stats.paid_invoice_count)
Webhooks
Use the built-in listener to validate incoming signatures and process updates:
import os
from cryptobot.webhook import InMemoryReplayKeyStore, Listener
def handle_webhook(headers, data):
if data.get("update_type") == "invoice_paid":
payload = data.get("payload", {})
print("Paid invoice:", payload.get("invoice_id"))
listener = Listener(
host="0.0.0.0",
callback=handle_webhook,
api_token=os.environ["CRYPTOBOT_API_TOKEN"],
replay_store=InMemoryReplayKeyStore(),
replay_ttl_seconds=3600,
port=2203,
url="/webhook",
log_level="info",
)
listener.listen()
Listener accepts both sync and async callback functions.
For custom dedupe behavior, pass replay_key_resolver(data, raw_body, headers) with a stable key strategy.
For custom webhook stacks, use cryptobot.webhook.check_signature(...) to verify
crypto-pay-api-signature against the raw request body.
Development
uv sync
make lint
make test
make docs
Documentation
- Docs: https://cryptobot-python.readthedocs.io/
- API reference: https://cryptobot-python.readthedocs.io/en/latest/modules.html
- Webhook security guide: https://cryptobot-python.readthedocs.io/en/latest/webhook_security.html
- Crypto Pay API: https://help.send.tg/en/articles/10279948-crypto-pay-api
Contributing
Issues and pull requests are welcome. Before opening a PR:
make lint
make test
See CONTRIBUTING.md and AGENTS.md for project workflow and coding standards.
Metadata
Release files for cryptobot-python 1.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cryptobot_python-1.1.2.tar.gz | 223.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cryptobot_python-1.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 246.2 kB
Release files / cryptobot_python-1.1.2.tar.gz
| Download URL | cryptobot_python-1.1.2.tar.gz |
|---|---|
| Size | 223.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9ddc034c7dd4e761705f5758ae7bf9225df3b08e22750ca7b4f824a33ef59a7c
|
|
BLAKE2b-256 checksum How to use checksums |
9eda6ae1712c31f02909ea9363cb9f6fce3d46f0d9615529ec9bfd64c31c702a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / cryptobot_python-1.1.2-py3-none-any.whl
| Download URL | cryptobot_python-1.1.2-py3-none-any.whl |
|---|---|
| Size | 22.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9b513ea84baa63808cafc48ecd7a5a0aefab45feebbec12e20e1d101badd4e0d
|
|
BLAKE2b-256 checksum How to use checksums |
fde8b935e4d8acabfb86f7e11354d7832448652e01637c07f6f83442d81f90e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log