Metadata-Version: 2.5
Name: verixo
Version: 0.5.0
Summary: Official Python SDK for the VerifiedCore API: phone verification (Verify), eSIM, call plans, wallet
Project-URL: Homepage, https://verifiedcore.com
Project-URL: Repository, https://github.com/titicodes/verixo
License-Expression: MIT
Keywords: 2fa,esim,otp,phone-verification,sms-verification,verify,verixo
Requires-Python: >=3.8
Requires-Dist: requests>=2.27
Requires-Dist: websocket-client>=1.6
Description-Content-Type: text/markdown

# verixo

Official Python SDK for the [VerifiedCore](https://verifiedcore.com) API.

## Install

```bash
pip install verixo
```

## Verify: send one-time codes to your own users

Send a code to your user's phone at sign-up, login or 2FA, then check what
they typed. VerifiedCore generates, delivers, rate-limits and expires the code.

```python
import os
from verixo import Client, VerixoError

client = Client(os.environ["VC_API_KEY"])

# 1. Send a code
v = client.verify.start("+2348031234567", ip=request_ip)

# 2. Check the code your user typed
r = client.verify.check(user_input, id=v.id)
if r.valid:
    ...  # signed in
else:
    print(f"{r.attempts_remaining} attempts left")
```

With a `vc_test_` key nothing is sent or charged, and the code is always
`123456`, so you can build your flow end-to-end before going live.

Other calls: `client.verify.get(id)`, `client.verify.list(page=, size=)`,
`client.verify.settings()` and `client.verify.update_settings(brand_name=,
allowed_countries=, code_length=, ttl_seconds=)`.

Failures raise a `VerixoError` whose `code` says why, e.g.
`COUNTRY_NOT_ALLOWED`, `INVALID_NUMBER`, `RESEND_TOO_SOON` or `RATE_LIMITED`.

## Numbers

```python
import os
import verixo

client = verixo.Client(os.environ["VC_API_KEY"])

result = client.numbers.search(
    service_slug="whatsapp",
    country_code="NG",
    min_score=80,
    limit=5,
)

session = client.numbers.purchase(
    service_slug="whatsapp",
    country_code="NG",
)

def handle(push):
    print(f"OTP: {push.otp} in {push.latency_ms}ms")

client.subscribe(session.session_token, handle)
```

Note: `purchase()` takes `service_slug` + `country_code`, not a specific
`number_id` -- the server picks the best available number by Health Score at
purchase time, since a candidate returned by `search()` may already be gone
by the time you'd reference it back.

## Polling instead of real-time push

`subscribe()` runs a background thread holding a persistent WebSocket
connection, which isn't always practical (e.g. one-shot scripts, serverless
functions). Use `sessions.wait_for_otp()` instead:

```python
result = client.sessions.wait_for_otp(session.session_token)
if result.status == "DELIVERED":
    print(result.otp_code)
```

## Errors

All non-2xx responses raise `verixo.VerixoError` with `.status`, and usually
`.code`/`.detail` from the API's error body:

```python
from verixo import VerixoError

try:
    client.numbers.purchase(service_slug="whatsapp", country_code="NG")
except VerixoError as err:
    if err.status == 402:
        print("Insufficient wallet balance")
```

## Requirements

Python 3.8+.

## Development

```bash
python -m venv .venv
.venv/Scripts/activate   # or `source .venv/bin/activate` on macOS/Linux
pip install -e .
python examples/quickstart.py   # requires VC_API_KEY env var, see file header
```
