Gramix API client for Python (Unofficial Fragment API)
A synchronous, fully typed client requiring Python 3.11+. It uses the standard library and has no runtime dependencies.
Installation
From a clone of the standalone GitHub repository:
python -m pip install .
Once the v1.0.0 tag is published, install that release directly (requires Git):
python -m pip install "gramix-api @ git+https://github.com/gramix-io/gramix-python-sdk.git@v1.0.0"
Alternatively, install the wheel attached to a GitHub Release with
python -m pip install ./gramix_api-1.0.0-py3-none-any.whl.
PyPI installation is available only after a separate PyPI publication.
Quick start
Set GRAMIX_API_KEY in your environment. Purchase examples below create real,
paid orders when executed with an active key. Persist each idempotency key
before sending its request; generate a distinct key (for example uuid.uuid4().hex)
for every new purchase.
import os
from gramix import GramixClient
client = GramixClient(os.environ["GRAMIX_API_KEY"])
balance = client.get_balance()
deposit = client.get_deposit_details()
purchase = client.purchase_stars(
recipient_name="telegram_user",
payment_currency="usdt",
stars=500,
idempotency_key="stars_20260729_0001",
)
premium = client.purchase_premium(
recipient_name="telegram_user",
payment_currency="gram",
duration=6,
idempotency_key="premium_20260729_0001",
)
gram = client.purchase_gram(
recipient_name="telegram_user",
payment_currency="gram",
gram=2,
idempotency_key="gram_20260729_0001",
)
orders = client.list_orders(limit=20, offset=0)
order = client.get_order(purchase["orderId"])
Every method returns the contents of the successful response's data field.
The client validates the documented structure before returning it.
API methods
All paths below are relative to https://api.gramix.io/api/v1.
| Python method | HTTP endpoint | Arguments / result |
|---|---|---|
get_balance() |
GET /wallets/balance |
Decimal strings: gram, usdt |
get_deposit_details() |
POST /wallets/balance |
TON address and required memo |
purchase_stars(recipient_name, payment_currency, stars, idempotency_key) |
POST /purchase/stars |
50–1,000,000 integer Stars; gram or usdt |
purchase_premium(recipient_name, payment_currency, duration, idempotency_key) |
POST /purchase/premium/{duration} |
3, 6, or 12 integer months; gram or usdt |
purchase_gram(recipient_name, payment_currency, gram, idempotency_key) |
POST /purchase/gram |
1–10,000 integer GRAM; payment currency gram |
list_orders(limit=20, offset=0) |
GET /orders |
data, total, limit, offset; limit 1–100 |
get_order(order_id) |
GET /orders/{id} |
One order by UUID |
Python arguments use snake_case; the client sends the API's camelCase JSON
fields. Returned values are typed dictionaries retaining the original API keys.
GET requests and deposit requests have no JSON body. Purchase requests carry
Content-Type: application/json and idempotency-key; every request includes
x-api-key and Accept: application/json.
Recipients use lowercase Telegram usernames without @. Idempotency keys
contain 8–64 ASCII letters, digits, underscores, or hyphens.
Always include the deposit memo in the TON transfer. A purchase response means
acceptance for asynchronous processing; use get_order(purchase["orderId"])
or webhooks to track completion. Order currency uses usd for USDT payments.
Keep monetary values as strings or use decimal.Decimal, avoiding float rounding.
from decimal import Decimal
available_usdt = Decimal(balance["usdt"])
Balances and amounts must be decimal strings with four fractional digits. Order and webhook timestamps are validated as ISO 8601 datetimes and retained as strings. Unknown response fields are retained for forward compatibility.
Pagination
offset = 0
while True:
page = client.list_orders(limit=100, offset=offset)
for order in page["data"]:
print(order["id"], order["status"])
offset += len(page["data"])
if not page["data"] or offset >= page["total"]:
break
Orders are newest first. New orders arriving during pagination can shift offsets;
deduplicate by id when collecting a changing order history.
The contract is documented in the Gramix API reference.
Errors
- Non-2xx responses raise
ApiErrorand preservehttp_status,api_status_code,response, andraw_body. - Network, timeout, and incomplete HTTP response failures raise
TransportError. - Redirects are not followed; HTTP 3xx responses raise
ApiErrorwithout sending the API key or purchase request to the redirect destination. - Successful but malformed responses raise
InvalidResponseError. - Invalid method arguments raise
ValueError.
All SDK response and transport exceptions inherit from GramixError:
from gramix import ApiError, InvalidResponseError, TransportError
try:
balance = client.get_balance()
except ApiError as exc:
print(f"API rejected the request: HTTP {exc.http_status}")
except TransportError:
print("Request outcome is unknown; check connectivity before retrying.")
except InvalidResponseError:
print("The API response does not match the documented format.")
Do not automatically repeat a purchase with a new idempotency key after a network error. Retry the same request with the same key; use a new key only for a new purchase. The SDK does not retry automatically. The same precaution applies when a purchase returns an unreadable or malformed response.
Webhooks
import json
from gramix import parse_webhook_event
event = parse_webhook_event(json.loads(request_body))
This validates the documented payload shape but does not authenticate the
sender. The public API documentation currently defines no webhook signature.
Confirm order state with get_order(event["orderId"]) before granting value.
Return HTTP 2xx promptly, handle duplicates idempotently, and do not assume
events arrive in order.
The constructor accepts base_url, timeout, and a custom transport for
private gateways and tests. A custom base URL receives the API key, so use only
a trusted HTTP(S) endpoint. Custom transports implement
Callable[[Request, float], tuple[int, bytes]] and are responsible for redirect
policy, response cleanup, and wrapping network errors in TransportError.
Development
python -m pip install -e ".[dev]"
PYTHONPATH=src python -m unittest discover -s tests -v
python -m ruff check .
python -m ruff format --check .
python -m mypy src/gramix tests
python -m build
python -m twine check dist/*
Tests use fixtures and a local HTTP server; they require no API key and create no real purchases. CI tests Python 3.11–3.14 on Linux and 3.11/3.14 on Windows and macOS, and checks typing, lint, formatting, and distributable artifacts.
Releases
Update src/gramix/_version.py and CHANGELOG.md, then push the commit to
main. Once CI passes, create and push a matching version tag (for example,
v1.0.0):
git tag v1.0.0
git push origin v1.0.0
The tag workflow checks the package version and runs the full CI matrix. If all jobs pass, it publishes a GitHub Release with the wheel and source distribution attached. A failed job does not publish a release. This does not upload to PyPI.
License
MIT, copyright Gramix.io. Commercial use, modification, and redistribution are allowed under the license terms.
Release files for gramix-api 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gramix_api-1.0.0.tar.gz | 20.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gramix_api-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.7 kB
Release files / gramix_api-1.0.0.tar.gz
| Download URL | gramix_api-1.0.0.tar.gz |
|---|---|
| Size | 20.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d028dc9f935d0ab0e965a15b936f10859602ea0624bf3d12e5a025fad548349b
|
|
BLAKE2b-256 checksum How to use checksums |
69ed94fea2b1276b5ab456c18e822c72815673a4fee1908ec58fda84f59576c4
|
| 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 Sep 25, 2026.
Transparency logRelease files / gramix_api-1.0.0-py3-none-any.whl
| Download URL | gramix_api-1.0.0-py3-none-any.whl |
|---|---|
| Size | 13.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
60b60a96918c711124590b3e28d2f1cbbb2e812f915c3adb855799c9730f5e83
|
|
BLAKE2b-256 checksum How to use checksums |
b82d8507e8bf3584186dceb7dfd4c219e79b74bf6be65c199fcfb8faea7869f1
|
| 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 Sep 25, 2026.
Transparency log