Metadata-Version: 2.4
Name: authsms
Version: 1.0.0
Summary: Official Python client for the AuthSMS API: virtual numbers, SMS verification codes, rentals and webhooks.
Author: AuthSMS
License: MIT
Project-URL: Homepage, https://authsms.net
Project-URL: Documentation, https://authsms.net/api-docs
Project-URL: Source, https://github.com/AuthSMS/authsms-sdk
Project-URL: Issues, https://github.com/AuthSMS/authsms-sdk/issues
Keywords: sms,sms-verification,otp,virtual-number,temporary-phone-number,verification-code,api-client,authsms
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Communications
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# authsms

Official Python client for the [AuthSMS API](https://authsms.net/api-docs): buy virtual numbers, receive SMS verification codes, rent numbers and handle webhooks. Standard library only, Python 3.8+.

```bash
pip install authsms
```

Create an API key on <https://authsms.net/api-docs> (sign in first).

## Quick start

```python
import os
from authsms import AuthSMS

api = AuthSMS(os.environ["AUTHSMS_API_KEY"])

number = api.buy_number(service="wa", country="62")
print("Use this number:", number["phone"])

done = api.wait_for_code(number["id"])   # polls until the SMS arrives
print("Code:", done["code"])
```

`service` and `country` are ids from `api.services()` and `api.countries()`. Prices and stock: `api.prices(service="wa")`. If no SMS arrives the number is cancelled and refunded automatically.

## Webhooks instead of polling

```python
from flask import Flask, request
from authsms import verify_webhook

app = Flask(__name__)

@app.post("/authsms")
def hook():
    try:
        event = verify_webhook(request.get_data(), request.headers, os.environ["AUTHSMS_WEBHOOK_SECRET"])
    except ValueError:
        return "", 400
    if event["type"] == "sms.received":
        print("Code", event["data"]["code"])
    return "", 200
```

Register the URL once with `api.set_webhook("https://example.com/authsms")` (the response contains your signing secret) and check it with `api.test_webhook()`. Pass the **raw** body to `verify_webhook`.

## Errors

Failed calls raise `AuthSMSError` with `status`, `code` (for example `INSUFFICIENT_BALANCE`, `NO_NUMBERS`, `RATE_LIMITED`) and the message.

```python
from authsms import AuthSMSError

try:
    api.buy_number(service="wa", country="62")
except AuthSMSError as e:
    if e.code == "NO_NUMBERS":
        ...  # try another country
```

GET requests are retried on 429, 5xx and network errors (`max_retries`, default 2). Purchases are never retried automatically, so you cannot buy twice by accident.

## Rentals

```python
offers = api.rental_offers("wa", hours=24)
rental = api.rent("wa", "62", hours=24)["rental"]
api.cancel_rental(rental["id"])   # refund, only in the first 20 minutes and before any SMS
```

Full reference: <https://authsms.net/api-docs> · OpenAPI: <https://authsms.net/openapi.json> · MIT licensed.
