Skip to main content

Unofficial but friendly Python client for the Crypto Bot (Crypto Pay) API

Project description

CryptoBot Python

PyPI version Python tests pre-commit.ci status Documentation Status codecov GitHub License Ask DeepWiki

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

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cryptobot_python-1.1.0.tar.gz (201.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cryptobot_python-1.1.0-py3-none-any.whl (22.7 kB view details)

Uploaded Python 3

File details

Details for the file cryptobot_python-1.1.0.tar.gz.

File metadata

  • Download URL: cryptobot_python-1.1.0.tar.gz
  • Upload date:
  • Size: 201.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cryptobot_python-1.1.0.tar.gz
Algorithm Hash digest
SHA256 fc65225c26949d302e6ec9341f93873c67edc72de65e81a70a592efa1032bafd
MD5 7d6cc27ea04d9668acf4886d9ff4abf6
BLAKE2b-256 84b6df90efdc35b791841ade532ba38962613445b2cc21b0e7c09bd6121978d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for cryptobot_python-1.1.0.tar.gz:

Publisher: python-publish.yml on ragnarok22/cryptobot_python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cryptobot_python-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cryptobot_python-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c0390622f8108dcc84a118d930d1604a880934addc5c45d669db82f413ad03a3
MD5 5515b420d396dee193ed920757d8db53
BLAKE2b-256 54aec5231dab675e0ff321dd6e4f6f125c44ba97448749f080032df231a81073

See more details on using hashes here.

Provenance

The following attestation bundles were made for cryptobot_python-1.1.0-py3-none-any.whl:

Publisher: python-publish.yml on ragnarok22/cryptobot_python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page