Vonage
Official Python SDK for Vonage APIs (formerly Nexmo) — SMS, Voice, WhatsApp, Verify, Video. v4.0 (2023) is a complete architectural rewrite from v3. Old nexmo package and old vonage v3 patterns are entirely broken in v4. Now a monorepo: top-level vonage package plus separate vonage_sms, vonage_voice, vonage_verify etc. packages installed as dependencies. All responses are Pydantic models.
Warnings
- breaking v4.0 is a complete rewrite. vonage.Client() does not exist in v4. All v3 code (client.send_message(), client.get_balance(), etc.) raises AttributeError. All tutorials and LLM-generated code using v3 patterns are broken.
- breaking nexmo PyPI package reached EOL October 2021, frozen at v7.2.0. 'import nexmo' still installs and runs but receives no updates. All new code must use 'vonage' package.
- gotcha SMS and basic APIs use API key + secret auth. Voice, Video, and Messages APIs require JWT auth (application_id + private_key). Using API key/secret for JWT-only endpoints returns 401.
- gotcha v4 responses are Pydantic models, not dicts. Code accessing response['message-id'] or response.get('messages') fails with TypeError. Use attribute access or .model_dump().
- gotcha API-specific models (SmsMessage, ListCallsFilter, etc.) must be imported from their sub-packages (vonage_sms, vonage_voice), not from vonage directly.
Install
-
pip install vonage
Imports
- Vonage (v4)
from vonage import Vonage, Auth from vonage_sms import SmsMessage auth = Auth(api_key='YOUR_KEY', api_secret='YOUR_SECRET') client = Vonage(auth=auth) message = SmsMessage(to='1234567890', from_='Vonage', text='Hello') response = client.sms.send(message)
- nexmo (old package)
# Install vonage instead pip install vonage
Quickstart
import os
from vonage import Vonage, Auth
from vonage_sms import SmsMessage
auth = Auth(
api_key=os.environ['VONAGE_API_KEY'],
api_secret=os.environ['VONAGE_API_SECRET']
)
client = Vonage(auth=auth)
message = SmsMessage(
to='15551234567',
from_='Vonage',
text='Hello from Vonage!'
)
response = client.sms.send(message)
print(response.model_dump_json(exclude_unset=True))
# For Voice/JWT auth, use:
# auth = Auth(application_id='APP_ID', private_key='path/to/private.key')