No project description provided
Project description
emailcentralpy
Python SDK for the Email Central API.
Install
pip install emailcentralpy
Requires Python 3.10+. The only dependency is requests.
Quickstart
Construct a client
from emailcentral import Client
client = Client(api_key="YOUR_API_KEY")
By default the client talks to https://email-central.net/api/v1. Pass base_url= to point it elsewhere (e.g. a staging environment):
client = Client(api_key="YOUR_API_KEY", base_url="https://staging.email-central.net/api/v1")
List products
products = client.list_products()
for p in products:
print(p.id, p.name, p.price_usd, p.stock)
price_mills on Product is the raw price in mills (1/1000 of a dollar) as returned by the API. price_usd is a convenience property that divides it by 1000.
Check balance
cents = client.balance()
print(f"${cents / 100:.2f}")
Buy accounts
result = client.buy(product_id=1, quantity=5)
print(result.purchase_id, result.new_balance_cents)
for item in result.items:
print(item)
To make a purchase safely retryable (e.g. if your process crashes or the connection drops mid-request), pass an idempotency_key. Reusing the same key returns the original purchase result instead of charging again:
result = client.buy(product_id=1, quantity=5, idempotency_key="order-2026-08-05-001")
If you reuse a key while the original call is still in flight, the API responds with 409 request_in_progress, which surfaces as an APIError with code == "request_in_progress".
Each string in result.items is one purchased account, in the form email:password or, for Graph-capable products, email:password:refreshToken:clientId.
List transactions
page = client.transactions(page=1)
for tx in page.transactions:
print(tx.order_no, tx.amount_cents, tx.status)
print(page.page, page.total_pages, page.total)
Handling errors
Any non-2xx response raises emailcentral.APIError, with status (HTTP status code), code (the API's error string), and message:
from emailcentral import APIError
try:
client.buy(product_id=999, quantity=1)
except APIError as e:
print(e.status, e.code, e.message)
Reading a Graph inbox
If a purchased item came from a Graph-capable product, its string includes a refresh token and client ID that let you read the mailbox directly through Microsoft Graph. This path never touches the Email Central API or your API key.
from emailcentral import parse_account, exchange_token, read_inbox
result = client.buy(product_id=1, quantity=1)
account = parse_account(result.items[0])
access_token = exchange_token(account.client_id, account.refresh_token)
messages = read_inbox(access_token, folder="inbox", limit=10)
for m in messages:
print(m.date, m.from_, m.subject)
folder is one of "inbox", "junk", or "all".
Note: on Message, the sender field is named from_ (with a trailing underscore) because from is a reserved word in Python.
parse_account splits on : and takes the email as the first field and the client ID as the last field; everything in between is rejoined with : as the refresh token, since refresh tokens can themselves contain colons. It raises ValueError if the string doesn't have at least 4 :-separated parts.
Examples
A complete, runnable script covering every method (list_products, balance, transactions, orders, buy, order_items, and the Graph flow) is in examples/quickstart.py. It reads the API key from the EMAILCENTRAL_API_KEY environment variable:
EMAILCENTRAL_API_KEY=your-key python examples/quickstart.py
Error codes
These are the code values you may see on a raised APIError, with the HTTP status they come with.
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized |
API key missing, invalid, or revoked |
| 400 | invalid_body |
Request body failed validation (e.g. bad productId/quantity) |
| 415 | unsupported_media_type |
Request Content-Type was not accepted |
| 413 | payload_too_large |
Request body exceeded the size limit |
| 404 | product_not_found |
No product exists with the given productId |
| 400 | insufficient_balance |
Account balance too low to complete the purchase |
| 400 | insufficient_stock |
Not enough stock left for the requested quantity |
| 400 | purchase_failed |
Purchase could not be completed for another reason |
| 409 | request_in_progress |
The same Idempotency-Key is already being processed |
| 500 | internal_error |
Server-side error |
| 429 | rate_limited |
Too many requests; back off and retry |
unauthorized and rate_limited can be returned by every endpoint (list_products, buy, balance, transactions), not just buy.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file emailcentralpy-1.0.0.tar.gz.
File metadata
- Download URL: emailcentralpy-1.0.0.tar.gz
- Upload date:
- Size: 6.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6af886f855a2d2860dae4cac3492ab14b53cd0e64a8202d25e0ca4de52fca39
|
|
| MD5 |
ed3217b2513bffb6c96c2ff562aec1fa
|
|
| BLAKE2b-256 |
c41885429bf3a794864a2cc1e530ac252e3747376d20831c45ee19542246e9cf
|
File details
Details for the file emailcentralpy-1.0.0-py3-none-any.whl.
File metadata
- Download URL: emailcentralpy-1.0.0-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c323c9898c97aebf1fc288d1e2e6125aa519d3fa758d1f3de5ef906d084876b
|
|
| MD5 |
49aae7138b8e4f0b1356012b99c1f662
|
|
| BLAKE2b-256 |
1b16c4c580cd99e2d1de6914012f2e0c4ff59977b2de56a1127e8cb1d4d8d1af
|