Skip to main content

Python SDK for the VirtualSMS Consumer API — SMS verification, phone number rental, and activation management.

Project description

VirtualSMS Python SDK

Python SDK for the VirtualSMS Consumer API — SMS verification, phone number rental, and activation management.

PyPI License Python

Requirements

  • Python 3.9 or higher
  • No external dependencies (uses standard library only)

Installation

pip install virtualsmslabs-python-sdk

Quick Start

from virtualsms import VirtualSMSClient, ActivationStatus

client = VirtualSMSClient("YOUR_API_KEY", "https://api.virtualsms.de")

# Check balance
balance = client.get_balance()
print(f"Balance: ${balance.balance:.2f}")

# Order a WhatsApp number in Brazil
number = client.get_number("wa", 73, max_price=2.00)
print(f"Number: {number.phone_number} (ID: {number.activation_id})")

# Set status to ready (SMS sent)
client.set_status(number.activation_id, ActivationStatus.READY)

# Poll for SMS code
status = client.get_status(number.activation_id)
if status.code is not None:
    print(f"SMS code: {status.code}")
    # Complete the activation
    client.set_status(number.activation_id, ActivationStatus.COMPLETE)

API Reference

Client Constructor

client = VirtualSMSClient(
    api_key="YOUR_API_KEY",           # Your API key (required)
    base_url="https://api.virtualsms.de",  # API base URL (optional)
    transport=None,                    # Optional custom transport
)

Methods

Account

get_balance() -> BalanceResponse

Returns the current account balance.

balance = client.get_balance()
print(balance.balance)  # 10.50

Information & Pricing

get_countries(pool_provider=None) -> dict

Returns all available countries.

get_services_list(country=None, lang=None) -> dict

Returns available services for a country.

get_operators(country, pool_provider=None) -> list

Returns available mobile operators for a country.

get_prices(service=None, country=None, pool_provider=None) -> dict

Returns pricing data organized by country and service.

get_prices_extended(service=None, country=None, free_price=None, pool_provider=None) -> dict

Returns extended pricing with price tiers.

get_prices_verification(service=None, pool_provider=None) -> dict

Returns pricing in inverted format (service → country).

get_numbers_status(country, operator=None, pool_provider=None) -> dict

Returns available phone quantity per service.

get_top_countries_by_service(service) -> list

Returns top 10 countries for a service, ranked by purchase share and success rate.

Ordering Numbers

get_number(service, country, **options) -> NumberResponse

Orders a phone number. Returns text format response.

number = client.get_number(
    service="wa",
    country=73,
    max_price=2.00,
    operator="claro",
    forward=True,
)
print(number.activation_id)   # 123
print(number.phone_number)    # 447777777777

Options:

Parameter Type Description
max_price float Maximum price willing to pay
operator str Mobile operator filter
phone_exception str Phone prefixes to exclude (comma-separated)
forward bool Enable call forwarding
activation_type int Activation type: 0=SMS, 1=number, 2=voice
language str Language for voice activation
use_cashback bool Use cashback balance first
user_id str End-user ID for tracking
ref str Referral ID
pool_provider str Pool provider: alpha, prime, gamma, zeta
get_number_v2(service, country, **options) -> dict

Same as get_number but returns JSON with additional fields. Supports order_id for idempotency.

Activation Management

set_status(id, status) -> str

Changes activation status.

from virtualsms import ActivationStatus

client.set_status(activation_id, ActivationStatus.READY)     # 1 - SMS sent
client.set_status(activation_id, ActivationStatus.RETRY)     # 3 - Request another SMS
client.set_status(activation_id, ActivationStatus.COMPLETE)  # 6 - Finish
client.set_status(activation_id, ActivationStatus.CANCEL)    # 8 - Cancel
get_status(id) -> StatusResponse

Returns activation status in text format.

status = client.get_status(activation_id)
print(status.status)   # STATUS_OK, STATUS_WAIT_CODE, STATUS_CANCEL
print(status.code)     # 123456 (None if not yet received)
get_status_v2(id) -> dict

Returns activation status in JSON format with SMS/call details.

get_active_activations() -> list

Returns all currently active activations.

check_extra_activation(id) -> dict

Checks if a number is available for reactivation.

get_extra_activation(id) -> NumberResponse

Creates an extra activation on a previously used number.

Notifications

get_notifications() -> dict

Returns user notifications including penalties, low balance alerts, and admin messages.

Constants

ActivationStatus

ActivationStatus.READY     # 1 - SMS has been sent to the number
ActivationStatus.RETRY     # 3 - Request another SMS code
ActivationStatus.COMPLETE  # 6 - Finish activation
ActivationStatus.CANCEL    # 8 - Cancel activation

PoolProvider

PoolProvider.ALPHA  # 'alpha'
PoolProvider.PRIME  # 'prime'
PoolProvider.GAMMA  # 'gamma'
PoolProvider.ZETA   # 'zeta'

Error Handling

The SDK raises typed exceptions for all API errors. Each error code maps to a specific exception class:

from virtualsms import (
    VirtualSMSClient,
    VirtualSMSException,
    AuthenticationException,
    InsufficientBalanceException,
    NoNumbersException,
    ValidationException,
    ActivationException,
    RateLimitException,
    ServerException,
)

try:
    number = client.get_number("wa", 73)
except AuthenticationException:
    # BAD_KEY, BANNED, PURCHASE_RESTRICTED, SERVICE_RESTRICTED
    pass
except InsufficientBalanceException:
    # NO_BALANCE
    pass
except NoNumbersException:
    # NO_NUMBERS
    pass
except ValidationException:
    # WRONG_SERVICE, WRONG_COUNTRY, BAD_ACTION, BAD_STATUS, NO_PRICES, INVALID_PROVIDER
    pass
except ActivationException:
    # NO_ACTIVATION, WRONG_ACTIVATION_ID, EARLY_CANCEL_DENIED, RENEW_ACTIVATION_NOT_AVAILABLE
    pass
except RateLimitException as e:
    # CONCURRENT_LIMIT — check e.retry_after
    pass
except ServerException:
    # ERROR_SQL, unknown errors
    pass

Error Code Reference

Error Code Exception Description
BAD_KEY AuthenticationException Invalid API key
BANNED AuthenticationException Account banned or IP blocked
PURCHASE_RESTRICTED AuthenticationException User restricted from purchasing
SERVICE_RESTRICTED AuthenticationException Service restricted for account
NO_BALANCE InsufficientBalanceException Insufficient balance
NO_NUMBERS NoNumbersException No numbers available
WRONG_SERVICE ValidationException Invalid service code
WRONG_COUNTRY ValidationException Invalid country ID
BAD_ACTION ValidationException Invalid action
BAD_STATUS ValidationException Invalid status code
NO_PRICES ValidationException No pricing data available
INVALID_PROVIDER ValidationException Invalid pool provider
NO_ACTIVATION ActivationException Activation not found
WRONG_ACTIVATION_ID ActivationException Invalid activation ID
EARLY_CANCEL_DENIED ActivationException Cannot cancel within 5 minutes
RENEW_ACTIVATION_NOT_AVAILABLE ActivationException Number not available for reactivation
CONCURRENT_LIMIT RateLimitException Too many concurrent activations
ERROR_SQL ServerException Internal server error

Tracking Headers

The SDK sends anonymous tracking headers with every request for analytics and debugging:

Header Value Privacy
X-SDK-Version 1.0.0 SDK version string
X-SDK-Language python SDK language
X-SDK-Machine-Id SHA-256 hash of platform.platform() + sys.implementation.name (truncated to 32 chars) Irreversible hash — no hostname or IP exposed
X-SDK-Timestamp ISO 8601 UTC timestamp Request time

No personally identifiable information is transmitted. The machine ID is a one-way hash and cannot be reversed to identify the source machine.

Custom Transport

By default, the SDK uses urllib.request for HTTP requests. You can provide your own transport implementation:

from virtualsms import VirtualSMSClient, Transport, Response

class MyTransport(Transport):
    def send(self, url: str, headers: dict) -> Response:
        # Your HTTP implementation
        return Response(status_code=200, body="ACCESS_BALANCE:10.50")

client = VirtualSMSClient("API_KEY", "https://api.example.com", transport=MyTransport())

Examples

See the examples/ directory:

Testing

pip install pytest
pytest

License

MIT — see LICENSE.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

virtualsmslabs_python_sdk-1.0.0.tar.gz (13.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

virtualsmslabs_python_sdk-1.0.0-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file virtualsmslabs_python_sdk-1.0.0.tar.gz.

File metadata

File hashes

Hashes for virtualsmslabs_python_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 23470835eeadd1ee6073c18fa0d7bcb76fc4f17cb9c7c903406e2195c4263139
MD5 a3453239edb3c54c7a56d849f41caa6b
BLAKE2b-256 b2df08bc346861b01cb40e64d922e11f1101c1be789298d518c17338a84fc32c

See more details on using hashes here.

File details

Details for the file virtualsmslabs_python_sdk-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for virtualsmslabs_python_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 856d5cf5334d66443385c5211160bedfbbf47606e6d9804faf71d50d6bfeb567
MD5 51af3505dbc49bc759a246f49ca08dd4
BLAKE2b-256 b6d35adced1576c9945b9f26250eb12ee458b74d03dd9b1b8e4c7596b489d953

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page