{"id":220,"library":"plivo","title":"Plivo","description":"Python SDK for Plivo communications API — SMS, voice calls, WhatsApp, and Plivo XML generation. Current version is 4.59.6. Legacy version 0.11.3 has a completely different API (plivo.RestAPI vs plivo.RestClient). pip install --upgrade plivo may NOT cleanly upgrade from legacy — manual uninstall required.","status":"active","version":"4.59.6","language":"python","source_language":"en","source_url":"https://github.com/plivo/plivo-python","tags":["sms","voice","telephony","communications","whatsapp","cpaas"],"install":[{"cmd":"pip install plivo","lang":"bash","label":"Standard (current 4.x API)"},{"cmd":"pip uninstall plivo && pip install plivo","lang":"bash","label":"If upgrading from legacy 0.11.3 — upgrade alone may fail"}],"dependencies":[{"reason":"Required. Installed automatically.","package":"requests","optional":false},{"reason":"Required. Installed automatically.","package":"pytz","optional":false},{"reason":"Required for JWT token creation. Installed automatically.","package":"PyJWT","optional":false}],"imports":[{"note":"The legacy API (0.11.3) used plivo.RestAPI and dict-based method calls. The current 4.x API uses plivo.RestClient with attribute-based resource access. These are completely different interfaces — legacy code fails silently or with AttributeError on 4.x.","wrong":"import plivo\n\n# Legacy 0.11.3 API — fails on 4.x\np = plivo.RestAPI(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN')\nparams = {'src': '+12025551234', 'dst': '+14155551234', 'text': 'Hello'}\nresponse = p.send_message(params)","symbol":"RestClient","correct":"import plivo\n\n# Credentials from environment variables (recommended)\nclient = plivo.RestClient()\n\n# Or explicit\nclient = plivo.RestClient(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN')\n\n# Send SMS\nresponse = client.messages.create(\n    src='+12025551234',\n    dst='+14155551234',\n    text='Hello from Plivo!'\n)"},{"note":"Plivo XML generation module is plivoxml in 4.x, not xml. Always import from plivo import plivoxml.","wrong":"# Old XML generation pattern from legacy docs\nfrom plivo import xml\nresponse = xml.PlivoResponse()\n# AttributeError — xml module renamed to plivoxml in 4.x","symbol":"plivoxml","correct":"from plivo import plivoxml\n\nresponse = plivoxml.ResponseElement()\nresponse.add(plivoxml.SpeakElement('Hello, welcome to Plivo!'))\nprint(response.to_string())"}],"quickstart":{"code":"import plivo\nimport os\n\n# Use env vars: PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN\nclient = plivo.RestClient()\n\n# Send SMS\nsms = client.messages.create(\n    src='+12025551234',   # Your Plivo number in E.164 format\n    dst='+14155551234',   # Destination in E.164 format\n    text='Hello from Plivo!'\n)\nprint('SMS sent:', sms)\n\n# Make a call\ncall = client.calls.create(\n    from_='+12025551234',\n    to_='+14155551234',\n    answer_url='https://yourapp.com/answer_url'  # Returns Plivo XML\n)\nprint('Call made:', call)\n\n# Generate Plivo XML (for answer_url endpoint)\nfrom plivo import plivoxml\nxml = plivoxml.ResponseElement()\nxml.add(plivoxml.SpeakElement('Hello! This call is powered by Plivo.'))\nprint(xml.to_string())","lang":"python","description":"Send SMS, make a call, generate Plivo XML. Store credentials in env vars."},"warnings":[{"fix":"Uninstall first: pip uninstall plivo, then pip install plivo. Rewrite all code from plivo.RestAPI pattern to plivo.RestClient pattern — they are not compatible.","message":"Legacy 0.11.3 (plivo.RestAPI) and current 4.x (plivo.RestClient) are completely different APIs. pip install --upgrade plivo from 0.11.3 may fail silently or leave a broken installation. All old code using RestAPI, send_message(), dict-based params will raise AttributeError on 4.x.","severity":"breaking","affected_versions":">= 4.0"},{"fix":"Always use E.164 format: '+' + country_code + local_number. Example: +12025551234 for a US number, +919876543210 for an Indian number.","message":"Phone numbers must be in E.164 format (+country_code + number). Passing numbers without the + prefix causes API errors. Common mistake: passing '12025551234' instead of '+12025551234'.","severity":"breaking","affected_versions":"all"},{"fix":"The answer_url endpoint must return Plivo XML with Content-Type: application/xml. Use plivoxml.ResponseElement() to generate the response.","message":"calls.create() requires an answer_url that returns valid Plivo XML (ResponseElement). Passing an answer_url that returns JSON or empty response causes the call to fail silently after connecting.","severity":"gotcha","affected_versions":"all"},{"fix":"Purchase a Plivo number at console.plivo.com. The src parameter must match a number in your Plivo account.","message":"The src number for SMS must be a Plivo-owned number in your account, not your personal number. Sending from an unverified or unowned number returns a 400 error.","severity":"gotcha","affected_versions":"all"},{"fix":"Use offset parameter: client.messages.list(limit=20, offset=20) for page 2. Or iterate manually while response has results.","message":"client.messages.list() returns max 20 results by default. For pagination, use limit and offset parameters explicitly. There is no automatic pagination built into list().","severity":"gotcha","affected_versions":"all"},{"fix":"Set the PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN environment variables before running your script. Alternatively, pass auth_id and auth_token directly to the Plivo.RestClient() constructor: client = plivo.RestClient(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN').","message":"The Plivo Python SDK requires authentication credentials (PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN) to be set. These are typically read from environment variables or passed directly to the Plivo.RestClient() constructor. Failure to provide them will result in an AuthenticationError.","severity":"breaking","affected_versions":"all"},{"fix":"Ensure PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN environment variables are set before running the application, or initialize the client with `client = plivo.RestClient(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN')`.","message":"The Plivo Python SDK failed to find authentication credentials. It attempts to read PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN from environment variables by default, or they must be passed explicitly to plivo.RestClient(). Failure to provide these results in plivo.exceptions.AuthenticationError and `KeyError: 'PLIVO_AUTH_ID'` or `'PLIVO_AUTH_TOKEN'`.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T11:57:04.906Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Update your code to use `plivo.RestClient`. If you have the legacy version installed, you might need to uninstall it first (`pip uninstall plivo`) and then install the current version (`pip install plivo`).\n\n```python\nimport plivo\n\n# Old (will cause error)\n# client = plivo.RestAPI(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN')\n\n# New (correct)\nclient = plivo.RestClient(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN')\n```","cause":"This error occurs when using code written for the legacy Plivo Python SDK (version 0.11.3) with the current SDK (version 4.x.x or later). The class name changed from `plivo.RestAPI` to `plivo.RestClient`.","error":"AttributeError: module 'plivo' has no attribute 'RestAPI'"},{"fix":"In the current Plivo SDK, message sending is done via the `messages` resource. You should use `client.messages.create()`.\n\n```python\nimport plivo\n\nclient = plivo.RestClient(auth_id='YOUR_AUTH_ID', auth_token='YOUR_AUTH_TOKEN')\n\n# Old (will cause error)\n# response = client.send_message(\n#     src='YOUR_PLIVO_NUMBER',\n#     dst='RECIPIENT_NUMBER',\n#     text='Hello from Plivo!'\n# )\n\n# New (correct)\nresponse = client.messages.create(\n    src='YOUR_PLIVO_NUMBER',\n    dst='RECIPIENT_NUMBER',\n    text='Hello from Plivo!'\n)\n\nprint(response)\n```","cause":"This error indicates that you are trying to call a method like `send_message` directly on the `RestClient` object, which is not how message sending is handled in the current Plivo Python SDK. The API for sending messages changed.","error":"AttributeError: 'Client' object has no attribute 'send_message'"},{"fix":"Ensure the Plivo Python SDK is installed in your active Python environment. If it's already installed but you're still seeing the error, check your environment or ensure there isn't a local file shadowing the `plivo` package.\n\n```bash\npip install plivo\n\n# If you suspect an issue with a legacy installation, try uninstalling first:\npip uninstall plivo\npip install plivo\n```","cause":"This error means that the Python interpreter cannot find the 'plivo' library. This typically happens if the library is not installed, installed in a different Python environment, or if there's a naming conflict (e.g., a local file named `plivo.py`).","error":"ModuleNotFoundError: No module named 'plivo'"},{"fix":"Verify that your `AUTH_ID` and `AUTH_TOKEN` are correct and active. You can find your credentials on your Plivo Console Dashboard. Ensure there are no typos or leading/trailing spaces.\n\n```python\nimport plivo\n\n# Replace with your actual Auth ID and Auth Token from the Plivo Console\nAUTH_ID = 'YOUR_CORRECT_AUTH_ID'\nAUTH_TOKEN = 'YOUR_CORRECT_AUTH_TOKEN'\n\nclient = plivo.RestClient(auth_id=AUTH_ID, auth_token=AUTH_TOKEN)\n\n# Attempt an API call to test credentials\ntry:\n    response = client.messages.create(\n        src='YOUR_PLIVO_NUMBER',\n        dst='RECIPIENT_NUMBER',\n        text='Test message'\n    )\n    print(response)\nexcept plivo.exceptions.PlivoAPIError as e:\n    print(f\"Plivo API Error: {e}\")\n```","cause":"This error occurs when the Plivo API credentials (Auth ID and Auth Token) provided to the `RestClient` are incorrect, expired, or do not have the necessary permissions.","error":"plivo.exceptions.PlivoAPIError: status_code=401, message=Invalid Auth ID or Auth Token"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.77,"mem_mb":13.9,"disk_size":"35.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.56,"mem_mb":13.9,"disk_size":"35M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1,"mem_mb":15.4,"disk_size":"37.0M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.84,"mem_mb":15.4,"disk_size":"37M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.91,"mem_mb":15.1,"disk_size":"28.8M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.86,"mem_mb":15.1,"disk_size":"29M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.87,"mem_mb":16.1,"disk_size":"28.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.87,"mem_mb":16.1,"disk_size":"29M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.72,"mem_mb":13.6,"disk_size":"34.2M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.61,"mem_mb":13.6,"disk_size":"35M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}