Python SDK
Official Python SDK for Snippe — sync and async clients, payouts, and webhook verification
The official Snippe SDK for Python. Ships both a synchronous Snippe client and an AsyncSnippe for asyncio frameworks (FastAPI, aiohttp, etc.).
- Source: github.com/Neurotech-HQ/snippe-python-sdk
- PyPI:
snippe
Install
pip install snippeInitialize the client
from snippe import Snippe, Customer
client = Snippe("snp_your_api_key")from snippe import AsyncSnippe, Customer
async def create_payment():
async with AsyncSnippe("snp_your_api_key") as client:
payment = await client.create_mobile_payment(
amount=1000,
currency="TZS",
phone_number="0788500000",
customer=Customer(firstname="John", lastname="Doe"),
)
return paymentAsyncSnippe is an async context manager — using async with ensures the underlying HTTP session is closed cleanly.
Store the API key in an environment variable, never in source. The SDK accepts
any string but only snp_ prefixed live or test keys are valid.
Create a payment
payment = client.create_mobile_payment(
amount=5000,
currency="TZS",
phone_number="0712345678",
customer=Customer(
firstname="Jane",
lastname="Doe",
email="jane@example.com",
),
webhook_url="https://yourapp.com/webhooks",
metadata={"order_id": "ORD-123"},
)payment = client.create_card_payment(
amount=50000,
currency="TZS",
phone_number="0712345678",
customer=Customer(
firstname="John",
lastname="Doe",
email="john@example.com",
address="123 Main Street",
city="Dar es Salaam",
state="DSM",
postcode="14101",
country="TZ",
),
callback_url="https://yourapp.com/callback",
webhook_url="https://yourapp.com/webhooks",
)
# Redirect the customer to payment.payment_urlSee the Payments API for the full request reference.
Send a payout
payout = client.create_mobile_payout(
amount=5000,
recipient_name="John Doe",
recipient_phone="255781000000",
narration="Salary payment January 2026",
webhook_url="https://yourapp.com/webhooks",
metadata={"employee_id": "EMP-001"},
idempotency_key="emp-001-jan-2026",
)payout = client.create_bank_payout(
amount=50000,
recipient_name="John Doe",
recipient_bank="CRDB",
recipient_account="0211049375",
narration="Invoice payment INV-2026-001",
webhook_url="https://yourapp.com/webhooks",
metadata={"invoice_id": "INV-2026-001"},
)The full bank code list is in the Bank transfer guide.
Verify a webhook
verify_webhook performs HMAC-SHA256 verification, replay-attack rejection, and JSON parsing. Pass the raw request body — parsing and re-serializing the JSON will break the signature.
from snippe import verify_webhook, WebhookVerificationError
@app.post("/webhooks/snippe")
def handle_snippe_webhook(request):
try:
event = verify_webhook(
body=request.body.decode(),
signature=request.headers["X-Webhook-Signature"],
timestamp=request.headers["X-Webhook-Timestamp"],
signing_key=os.environ["SNIPPE_WEBHOOK_SECRET"],
)
except WebhookVerificationError as e:
return Response(status=400, body=f"Invalid webhook: {e}")
if event["type"] == "payment.completed":
handle_payment_completed(event["data"])
return Response(status=200)For the full event catalogue, see the Webhooks guide.
Errors
| Class | When it's raised |
|---|---|
AuthenticationError | 401 — invalid or missing API key |
ValidationError | 400 — request body failed validation |
WebhookVerificationError | Webhook signature or timestamp invalid |
from snippe import ValidationError
try:
client.create_mobile_payment(...)
except ValidationError as e:
# fix the request and retry
...See Error handling for the full error-code list and recovery patterns.
Idempotency
Every mutating method accepts an idempotency_key argument (max 30 characters). Same key + same body returns the cached response; same key + different body returns a 422 error.
client.create_mobile_payout(
amount=5000,
recipient_name="John Doe",
recipient_phone="255781000000",
idempotency_key="payroll-emp-001-jan26",
)