OTP
Primary flow: POST /v1/otp/send → user enters code → POST /v1/otp/verify. Default delivery_mode=auto tries WhatsApp then SMS.
Send (SEED generates the code)
# SEED generates a 6-digit code, tries WhatsApp then SMS
otp = client.otp.send(
to="+22890000000",
reference="login-1",
delivery_mode="auto", # auto | whatsapp | sms
request_messaging_consent=False,
)
print(otp.challenge_id, otp.channel, otp.expires_at, otp.fallback_used)
# Store challenge_id server-side until the user submits the code
Send (you supply the code)
# You own the code (must be 4-8 digits)
otp = client.otp.send(
to="+22890000000",
code="482917",
reference="checkout-42",
delivery_mode="auto",
request_messaging_consent=False,
)
Verify
result = client.otp.verify(
challenge_id=otp.challenge_id,
code="482917",
)
print(result.verified, result.status) # True, "verified"
Poll challenge status
status = client.otp.get(otp.challenge_id)
print(status.status, status.attempts, status.channel, status.expires_at)
WhatsApp only (no SMS fallback)
Requires a client-supplied code. Prefer otp.send with delivery_mode=auto for production.
# No SMS fallback - code is required
wa = client.whatsapp.otp.send(
to="+22890000000",
code="482917",
reference="login-wa-only",
)
print(wa.challenge_id, wa.wamid)
Email
Send from a verified domain (or SEED shared domains). Maps to POST /v1/emails. At least text or html is required.
Send plain text
email = client.email.send(
to=["[email protected]"],
from_email="[email protected]",
subject="Welcome to SEED",
text="Thanks for joining us.",
reference="welcome-1",
)
print(email.id, email.status)
Send with HTML
Bulk send
bulk = client.email.send_bulk(messages=[
{
"to": ["[email protected]"],
"from_email": "[email protected]",
"subject": "Hello A",
"text": "Message A",
},
{
"to": ["[email protected]"],
"from_email": "[email protected]",
"subject": "Hello B",
"text": "Message B",
},
])
for item in bulk.results:
print(item.id, item.status)