Lessons
Practical patterns to apply on day one.
1. Fail fast on invalid input
try:
client.sms.send(to="not-a-number", message="hi")
except SendAfricaError as e:
print("fixed before it cost anything", e.status_code)Invalid phone numbers raise InvalidPhoneError locally — before any network call — so typos never burn credits.
2. Double-check emoji pricing
a = client.sms.analyze("Thanks 🙏")
b = client.sms.analyze("Thanks a lot!")
print(a.encoding, a.credits) # UCS-2 renders as more credits than GSM-7A single emoji can push a message into Unicode and increase credits_used. Analyze before you send.
3. Prefer bulk for blast-style messaging
Same message, many recipients → sms.bulk(). Different messages → sms.send_many(..., rate_limit_per_sec=10).
4. React to delivery, not to send
Update your order state on the sms.delivered webhook, not on the send response. See Webhooks.
5. Centralize the client
Create the client once (module level or dependency-injected) and share it. For FastAPI, construct AsyncSendAfrica in a startup hook and reuse it per-request — remember to aclose() on shutdown.
Last updated on