irnoti (Python)
Python SDK for the irnoti API, built on httpx.
pip install irnoti
from irnoti import Irnoti, IrnotiApiError, parse_webhook
irnoti = Irnoti(api_key="irn_live_…") # base_url, timeout, retries, http_client are optional
try:
line = irnoti.lines.list()[0]["id"]
irnoti.sms.quote(line, "Hi", to="09121234567")
irnoti.sms.send(line, "Hi", to=["09121234567"], group_ids=[12], idempotency_key="k1")
irnoti.sms.pattern("k3f9a2", "09121234567", {"code": "4821"})
irnoti.services.create("regional", {"province": "tehran", "count": 5000, "text": "Sale"})
except IrnotiApiError as e:
if e.is_insufficient_balance:
... # top up
else:
raise
# Flask: verify against the raw body
event = parse_webhook(request.get_data(), request.headers["X-Irnoti-Signature"], WEBHOOK_SECRET)
Multi-tenant: irnoti.with_api_key(customer_key) returns an independent client. Optional request fields use the API's camelCase names where they are passed as **options / dicts (e.g. verify.create(to=…, ttlSec=300)).
Quickstart
New here? Follow QUICKSTART.md: install, get a key, send your first (free, sandbox) SMS in 5 minutes.
What can this SDK do? (function reference)
Everything hangs off one client, irnoti = Irnoti(api_key=...). Each group below is a resource (irnoti.<resource>.<function>()), and each links to its section in the API docs at irnoti.com/docs (open the docs panel and look for the section named in the "Docs section" column).
| Resource | Docs section | What it is for | Functions |
|---|---|---|---|
irnoti.sms |
SMS | Send text messages | send (single / bulk / group / scheduled / gradual), quote (exact price, no send), pattern (approved OTP/transactional template), sos (guaranteed delivery with failover) |
irnoti.messages |
SMS → Messages | Look up sent messages | list, get, check (ask operator for final delivery state) |
irnoti.batches |
SMS → Batches | Control scheduled/gradual sends | scheduled, cancel, pause, resume |
irnoti.lines |
SMS → Lines | Your sender numbers (you need a line_id to send) |
list |
irnoti.wallet |
Wallet | Balance and history | balance, transactions |
irnoti.phonebook |
Phonebook | Contact groups and contacts | groups, create_group, delete_group, contacts, add_contacts, import_csv, update_contact, delete_contact |
irnoti.services |
Services | Provider products: regional, targeted, peyamap, smart, messenger, voice, international |
prices, international_rates, list, quote, create, get, refresh, cancel |
irnoti.link_tracker |
Link tracker | SMS with tracked links, A/B variants, holdout | send, holdouts, send_now, campaigns, campaign |
irnoti.number_banks |
Number banks | Send to purchased/filtered number banks | list, facets, quote, send |
irnoti.verify |
Verify | OTP verification sessions (SMS or bot) | info, create, list, get, cancel, stats |
irnoti.bots |
Bot builder | Read bots, send messages/OTP through them (creating bots is panel-only) | info, list, get, stats, subscribers, messages, send, otp, shop_orders, shop_stats |
irnoti.broker |
Telegram broker | Run Telegram bots through a private relay | list, get, create, rename, replace_token, rotate, delete, request, updates, webhook, set_webhook, delete_webhook |
irnoti.voip |
VoIP | Click-to-call | calls, price, call |
Top-level helpers (no network call):
| Function | What it does |
|---|---|
Irnoti(api_key, base_url=, timeout=, retries=, http_client=) |
Create the client |
irnoti.with_api_key(key) |
New independent client for another customer key (multi-tenant) |
verify_webhook(raw_body, signature, secret) |
True/False: is this webhook really from irnoti? |
parse_webhook(raw_body, signature, secret) |
Verify and return the decoded event, raises ValueError if the signature is bad |
IrnotiApiError |
Raised on any non-2xx answer; has .status, .code, .details and helpers like .is_insufficient_balance |
Every function is a thin wrapper over one HTTP endpoint and returns the API's JSON as plain dict/list. Read the docstring in src/irnoti/resources.py for exact arguments, e.g. help(irnoti.sms.send).
Typical flow:
lines.list()(pick a sender) →sms.quote()(see the cost) →sms.send()(with anidempotency_key) →messages.get()/ webhook (delivery result). Use anirn_test_…key andline_id="sandbox"while experimenting: nothing is sent or charged.
Telegram broker
bot = irnoti.broker.create("Shop bot", botfather_token) # scope broker.write (account owner); returns the relay `link`
irnoti.broker.request(bot["id"], "sendMessage", {"chat_id": 123, "text": "Hi"}) # scope broker.request
irnoti.broker.updates(bot["id"], limit=20) # pull mode
irnoti.broker.set_webhook(bot["id"], "https://example.com/tg", secret_token="s3cret") # push mode
Behaviour shared by all irnoti SDKs
- Auth:
Authorization: Bearer irn_live_…. Use anirn_test_…key withlineId: "sandbox"to try sends for free. Keys carry scopes (sms.send,sms.read,wallet.read,phonebook.read|write,bot.send|read,broker.read|write|request,verify.send|read); a missing scope is a403. - Money is integer Rial returned as a string (
"1960") — never parse it into a float. - Idempotency: every send takes an idempotency key; retrying with the same key never sends twice (
replayed: true). Automatic retries apply only toGETs and sends that carry a key. - Errors: one error type carrying
status, the API's machinecode(insufficient_balance,invalid_recipients,no_price, … — empty for plain 401/403/404) anddetails, with helpers such asisInsufficientBalance/isRateLimited/isUnauthenticated. - Limits: send 600 req/min, pattern 1200 req/min per IP (
429when exceeded). - Webhooks: verify the raw body against
X-Irnoti-Signature: t=<unix>,v1=<hex>(HMAC-SHA256 of"<t>.<body>"with yourwhsec_…key); signatures older than 5 minutes are rejected. - Bot-builder creation/configuration and verify settings are panel-only; Telegram broker bots can be managed through the API.
Sibling SDKs: Laravel · Node.js · Python · Go · PHP. API reference: irnoti.com/docs.
MIT licensed.
Metadata
Release files for irnoti 1.2.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 | Provenance | |
|---|---|---|---|---|
| irnoti-1.2.0.tar.gz | 12.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| irnoti-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.2 kB
Release files / irnoti-1.2.0.tar.gz
| Download URL | irnoti-1.2.0.tar.gz |
|---|---|
| Size | 12.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8b62338c117d12bc45a828fd1bd577971b6f87258085267ba6235bf5907f7901
|
|
BLAKE2b-256 checksum How to use checksums |
089f86c19751a114c0a655d8a111c58dd91957d41f73f2b020f7a2b03de6eba4
|
| 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 14, 2026.
Transparency logRelease files / irnoti-1.2.0-py3-none-any.whl
| Download URL | irnoti-1.2.0-py3-none-any.whl |
|---|---|
| Size | 12.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fbd43af43057c860bb579a470d076fbb75905727143b3d01450340fab776a6b8
|
|
BLAKE2b-256 checksum How to use checksums |
b56744d76d34adae1a856eaba2a4e8ad6113981bef6cb20c232499c22e1545f3
|
| 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 14, 2026.
Transparency logSecurity for irnoti 1.2.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for irnoti-1.2.0.tar.gz
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 14, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.