Current collected state Current
Observed since 20 Oct, 21:13 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Python SDK for AfroMessage API to send SMS and OTP
A complete Python SDK for the AfroMessage SMS and OTP API.
This package makes it easy to send single SMS, bulk SMS, and handle OTP challenges with minimal setup.
Install the package via pip:
pip install afromessage
AFROMESSAGE_TOKEN=your_api_token_here
import os
from dotenv import load_dotenv
from afromessage import AfroMessage
from afromessage.models.sms_models import SendSMSRequest, BulkSMSRequest
from afromessage.models.otp_models import SendOTPRequest, VerifyOTPRequest
# Load environment variables
load_dotenv()
token = os.getenv("AFROMESSAGE_TOKEN")
if not token:
raise ValueError("⚠️ Set AFROMESSAGE_TOKEN in your .env file!")
# Initialize the SDK
sdk = AfroMessage(token=token)
# --- Single SMS ---
sms_request = SendSMSRequest(
to="+2519xxxxxxx",
message="Hello from AfroMessage SDK!",
from_="MySender",
sender="MyBrand"
)
response = sdk.sms.send(sms_request)
print("✅ Single SMS:", response)
# --- Bulk SMS ---
bulk_request = BulkSMSRequest(
to=["+2519xxxxxxx", "+2519yyyyyyy"],
message="Hello, bulk users!",
from_="MySender",
sender="MyBrand",
campaign="MyCampaign"
)
bulk_response = sdk.sms.bulk_send(bulk_request)
print("✅ Bulk SMS:", bulk_response)
#--- Personalized Bulk request ---
personalized_request = BulkSMSRequest(
to=[
BulkRecipient(to="+2519xxxxxxx", message="Hi Yonas!"),
BulkRecipient(to="+2519yyyyyyy", message="Hi Eshetu!")
],
from_="MySender",
sender="MyBrand",
campaign="PersonalizedCampaign"
)
response = sdk.sms.bulk_send(personalized_request)
# --- OTP Challenge ---
otp_request = SendOTPRequest(
to="+2519xxxxxxx",
pr="Your code",
len_=6
)
otp_response = sdk.otp.send(otp_request)
print("✅ OTP Challenge:", otp_response)
# --- Verify OTP ---
verify_request = VerifyOTPRequest(
to="+2519xxxxxxx",
code="123456"
)
verify_response = sdk.otp.verify(verify_request)
print("✅ OTP Verify:", verify_response)
from afromessage.models.sms_models import SendSMSRequest
sms_request = SendSMSRequest(
to="+2519xxxxxxx",
message="Hello from AfroMessage!",
from_="MySender",
sender="MyBrand",
callback="https://myapp.com/callback" # optional
)
response = sdk.sms.send(sms_request)
response = sdk.sms.send_get(sms_request)
from afromessage.models.sms_models import BulkSMSRequest
bulk_request = BulkSMSRequest(
to=["+2519xxxxxxx", "+2519yyyyyyy"],
message="Hello, everyone!",
from_="MySender",
sender="MyBrand",
campaign="MyCampaign"
)
response = sdk.sms.bulk_send(bulk_request)
from afromessage.models.sms_models import BulkRecipient, BulkSMSRequest
personalized_request = BulkSMSRequest(
to=[
BulkRecipient(to="+2519xxxxxxx", message="Hi Yonas!"),
BulkRecipient(to="+2519yyyyyyy", message="Hi Eshetu!")
],
from_="MySender",
sender="MyBrand",
campaign="PersonalizedCampaign"
)
response = sdk.sms.bulk_send(personalized_request)
from afromessage.models.otp_models import SendOTPRequest
otp_request = SendOTPRequest(
to="+2519xxxxxxx",
pr="Your code",
len_=6,
ttl=300 # time-to-live in seconds (optional)
)
response = sdk.otp.send(otp_request)
from afromessage.models.otp_models import VerifyOTPRequest
verify_request = VerifyOTPRequest(
to="+2519xxxxxxx",
code="123456"
)
response = sdk.otp.verify(verify_request)
try:
response = sdk.sms.send(sms_request)
print("✅ Success:", response)
except Exception as e:
print("❌ Error:", str(e))
📤 [POST] Request to: send
Payload: {
"to": "+2519xxxxxxx",
"message": "Hello!"
}
📥 Response from: send
Data: {
"acknowledge": "success",
"response": { "code": "202", "to": "+2519xxxxxxx" }
}
.
python usage/test_real.py
pytest
pypistats · 45 observations shown. Missing days are unknown. Source category: overall: without mirrors.
| Date / source period | Value | Observed at |
|---|---|---|
| 2026-10-16 – 2026-10-16 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-15 – 2026-10-15 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-13 – 2026-10-13 | 7 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-12 – 2026-10-12 | 14 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-11 – 2026-10-11 | 10 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-10 – 2026-10-10 | 26 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-09 – 2026-10-09 | 8 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-08 – 2026-10-08 | 5 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-07 – 2026-10-07 | 5 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-06 – 2026-10-06 | 3 | 2026-10-20T21:28:13.9256312Z |
| 2026-10-02 – 2026-10-02 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-30 – 2026-09-30 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-29 – 2026-09-29 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-28 – 2026-09-28 | 3 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-27 – 2026-09-27 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-26 – 2026-09-26 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-25 – 2026-09-25 | 12 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-24 – 2026-09-24 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-20 – 2026-09-20 | 6 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-18 – 2026-09-18 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-16 – 2026-09-16 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-14 – 2026-09-14 | 6 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-12 – 2026-09-12 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-09 – 2026-09-09 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-07 – 2026-09-07 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-02 – 2026-09-02 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-09-01 – 2026-09-01 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-31 – 2026-08-31 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-28 – 2026-08-28 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-24 – 2026-08-24 | 6 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-23 – 2026-08-23 | 3 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-21 – 2026-08-21 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-20 – 2026-08-20 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-17 – 2026-08-17 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-14 – 2026-08-14 | 4 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-13 – 2026-08-13 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-09 – 2026-08-09 | 3 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-03 – 2026-08-03 | 6 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-02 – 2026-08-02 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-08-01 – 2026-08-01 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-07-30 – 2026-07-30 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-07-27 – 2026-07-27 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-07-24 – 2026-07-24 | 1 | 2026-10-20T21:28:13.9256312Z |
| 2026-07-23 – 2026-07-23 | 2 | 2026-10-20T21:28:13.9256312Z |
| 2026-07-21 – 2026-07-21 | 1 | 2026-10-20T21:28:13.9256312Z |
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.4 | 24 Sept 2025 | 2 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 21:13 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:24b28107210d70b884ba767ee72efa01fc09356dd73ee8faf8e144137f695848