:::note[Fail-open by default]
Every example returns `None` when the API is unreachable. Always let the user through when Syvel is unavailable — never block a registration because of a third-party service.
:::

## Installation

```bash
pip install syvel
```

Requires Python 3.10+. No runtime dependencies beyond `httpx`.

## Quick start

```python
import os
from syvel import Syvel

client = Syvel(api_key=os.environ["SYVEL_API_KEY"])

result = client.check_email("user@example.com")

if result and result.is_risky:
    raise ValueError("Please use a professional email address.")
# result is None → Syvel unavailable, let the user through
```

## Async usage

```python
import os
from syvel import AsyncSyvel

async def validate_email(email: str) -> bool:
    async with AsyncSyvel(api_key=os.environ["SYVEL_API_KEY"]) as client:
        result = await client.check_email(email)
        return result is None or not result.is_risky
```

## Django REST Framework

```python
from rest_framework import serializers
import os
from syvel import Syvel

client = Syvel(api_key=os.environ["SYVEL_API_KEY"], silent=True)


class RegisterSerializer(serializers.Serializer):
    email = serializers.EmailField()

    def validate_email(self, value):
        result = client.check_email(value)
        if result and result.is_risky:
            raise serializers.ValidationError(
                "Please use a professional email address."
            )
        return value
```

## FastAPI (async)

```python
from fastapi import FastAPI, HTTPException
import os
from syvel import AsyncSyvel

app = FastAPI()


@app.post("/register")
async def register(email: str):
    async with AsyncSyvel(api_key=os.environ["SYVEL_API_KEY"]) as client:
        result = await client.check_email(email)
    if result and result.is_risky:
        raise HTTPException(
            status_code=422,
            detail="Please use a professional email address.",
        )
    # continue with registration…
```

## Flask

```python
from flask import Flask, request, jsonify
import os
from syvel import Syvel

app = Flask(__name__)
client = Syvel(api_key=os.environ["SYVEL_API_KEY"], silent=True)


@app.route("/register", methods=["POST"])
def register():
    email = request.json.get("email")
    result = client.check_email(email)
    if result and result.is_risky:
        return jsonify({"error": "Please use a professional email address."}), 422
    # continue with registration…
```

## Response fields

| Field | Type | Description |
|---|---|---|
| `is_risky` | `bool` | `True` if the email is considered risky |
| `risk_score` | `int` | Risk score (0–100) |
| `reason` | `str` | `"safe"` \| `"disposable"` \| `"undeliverable"` \| `"role_account"` |
| `deliverability_score` | `int` | Likelihood of delivery (0–100) |
| `did_you_mean` | `str \| None` | Typo correction suggestion |
| `is_free_provider` | `bool` | Gmail, Yahoo, etc. |
| `is_corporate_email` | `bool` | Business domain detected |
| `is_alias_email` | `bool` | Privacy relay service (e.g. iCloud Hide My Email) |

## Error handling

By default, the SDK raises exceptions on errors. Pass `silent=True` to return `None` instead.

```python
from syvel import Syvel, SyvelAuthError, SyvelRateLimitError, SyvelError

client = Syvel(api_key=os.environ["SYVEL_API_KEY"])

try:
    result = client.check_email("user@example.com")
except SyvelAuthError:
    pass  # invalid API key
except SyvelRateLimitError:
    pass  # quota exceeded
except SyvelError:
    pass  # any other Syvel error → fail open
```

## Configuration

| Parameter | Default | Description |
|---|---|---|
| `api_key` | — | Your API key (from syvel.io/dashboard) |
| `base_url` | `https://api.syvel.io` | API base URL |
| `timeout` | `3.0` | Timeout in seconds |
| `silent` | `False` | Return `None` instead of raising exceptions |

## Resources

- [PyPI — syvel](https://pypi.org/project/syvel/)
- [GitHub — syvel-python](https://github.com/Syvel-io/syvel-python)
- [Python (httpx / requests) — no SDK dependency](/docs/integrations/python-httpx)
- [API reference — Domain check](/docs/api/check)
- [Authentication](/docs/guides/authentication)
- [Error codes](/docs/guides/errors)