Skip to main content

Paravane

Paravane Python Library

The Paravane Python library provides convenient access to the Paravane API from applications written in Python.

The first supported product API is smtpRS, Paravane's email risk intelligence API. smtpRS helps score email addresses for onboarding, trust, review, abuse-prevention, and operations workflows.

This SDK is intentionally small at the start. It provides a stable client entrypoint, request serialization, response helpers, structured errors, examples, tests, and packaging conventions that can grow as Paravane adds more APIs.

PyPI Python

Documentation · Installation · Quickstart · Examples · Development

Contents

Documentation

This README is the canonical SDK reference. The hosted Paravane documentation portal may temporarily show an access-status page during capacity pauses.

Installation

Install the latest release from PyPI:

python -m pip install --upgrade paravane

To install the current development version directly from GitHub:

python -m pip install "git+https://github.com/paravaneai/paravane-python.git"

For local development:

git clone git@github.com:paravaneai/paravane-python.git
cd paravane-python
python -m pip install -e ".[dev]"

Requirements

Python 3.10 or newer.

Runtime dependency:

  • requests>=2.33.0

Development dependencies are installed with:

python -m pip install -e ".[dev]"

Quickstart

Create an API key from the Paravane API keys page, copy it when it is shown, and store it in your server-side environment. The production client already defaults to https://api.paravane.io; do not append /v1 to the base URL.

Set your API key:

export PARAVANE_API_KEY="pvn_live_..."

On Windows PowerShell:

$env:PARAVANE_API_KEY = "pvn_live_..."

Call smtpRS:

from paravane import ParavaneClient

client = ParavaneClient()

result = client.smtprs.analyze("alice@example.com")

print(result.decision)
print(result.overall_risk)
print(result.credits_charged)

The SDK method is named analyze(...) for Python readability. The HTTP API endpoint remains:

POST /v1/analyse

Usage

Create a client with an API key:

from paravane import ParavaneClient

client = ParavaneClient(api_key="pvn_live_...")

Or use PARAVANE_API_KEY:

from paravane import ParavaneClient

client = ParavaneClient()

Run an email risk analysis:

result = client.smtprs.analyze("person@example.com")

if result.decision == "allow":
    print("Continue")
else:
    print("Review or block")

Inspect the normalized response:

print(result.email)
print(result.decision)
print(result.overall_risk)
print(result.analysis_profile)
print(result.credit_cost)
print(result.usage)

Access the original API response:

raw = result.to_dict()
print(raw)

smtpRS

smtpRS is available through:

client.smtprs

Analysis profiles

smtpRS provides named profiles so applications can choose the appropriate balance of coverage, latency, and credit usage without configuring individual checks.

Profile Credits Availability Intended use
quick 1 All plans Lightweight screening; this is the default.
standard 3 Basic and above Broader passive analysis.
adaptive 5 Pro and above Adds checks when the initial result needs more context.
deep 5 Pro and above Comprehensive analysis without catch-all probing.
catch_all 20 Enterprise or entitled accounts Deep analysis with catch-all probing.

Use the default quick profile:

result = client.smtprs.analyze("person@example.com")

Or request another profile available to your account:

result = client.smtprs.analyze(
    "person@example.com",
    profile="standard",
)

Profile availability is enforced by the API. Requesting a profile that is not included with the current plan raises PermissionDeniedError.

Legacy mode flags

The older disposable_only, strict_disposable, guess, and run_catch_all arguments remain available for compatibility. New integrations should use profile instead. Do not combine profile with an enabled legacy mode flag.

For example, replace:

result = client.smtprs.analyze(
    "person@example.com",
    strict_disposable=True,
)

with:

result = client.smtprs.analyze(
    "person@example.com",
    profile="deep",
)

Low-latency posture

Use the fast flag when your workflow favors lower latency:

result = client.smtprs.analyze(
    "person@example.com",
    fast=True,
)

Company Validity Beta

Paid smtpRS callers can explicitly request the optional Company Validity Beta:

result = client.smtprs.analyze(
    "person@example.com",
    profile="standard",
    company_validity_beta=True,
)

beta = result.company_validity_beta
if beta is not None:
    print(beta.status)  # "beta"
    print(beta.requested)  # True
    print(beta.enabled)  # True when the feature was active for this request
    print(beta.notes)

signal = result.domain_signal
if signal is not None:
    print(signal.domain_status)
    print(signal.mail_status)
    print(signal.company_valid)

The option is omitted by default, so existing calls retain their current behavior. It is available only to paid smtpRS plans and provides additive company-domain context rather than an allowlist. It currently adds no credits beyond the selected profile. Free-plan requests that explicitly enable it receive PermissionDeniedError. Because the response contract is beta, applications can use result.to_dict() to retain access to newly added fields.

Configuration

from paravane import ParavaneClient

client = ParavaneClient(
    api_key="pvn_live_...",
    base_url="https://api.paravane.io",
    timeout=20.0,
    max_network_retries=1,
)

Environment variables:

Name Purpose Default
PARAVANE_API_KEY API key used for requests. None
PARAVANE_BASE_URL API base URL. https://api.paravane.io

Most applications should leave PARAVANE_BASE_URL unset. If an approved alternate endpoint is required, provide only its scheme and host; the SDK adds /v1/analyse itself.

Per-request options

You can set a timeout for one request:

result = client.smtprs.analyze(
    "person@example.com",
    timeout=5.0,
)

You can pass an idempotency key:

result = client.smtprs.analyze(
    "person@example.com",
    idempotency_key="signup-check-123",
)

You can pass future or preview query parameters without waiting for a new SDK release:

result = client.smtprs.analyze(
    "person@example.com",
    extra_params={"preview_flag": "enabled"},
)

Custom HTTP sessions

The SDK uses requests by default. If your environment needs custom connection pooling, proxies, certificates, or adapters, pass a configured requests.Session:

import requests
from paravane import ParavaneClient

session = requests.Session()
session.proxies.update(
    {
        "https": "https://proxy.example.com:8443",
    }
)

client = ParavaneClient(
    api_key="pvn_live_...",
    session=session,
)

Retries

By default, the SDK does not retry network calls:

client = ParavaneClient(max_network_retries=0)

Enable limited retries for transient network failures, 429 rate limits, and 5xx API responses:

client = ParavaneClient(max_network_retries=2)

Billable POST requests are retried only when you supply an idempotency key. Without one, analyze makes one attempt even when max_network_retries is greater than zero:

result = client.smtprs.analyze(
    "person@example.com",
    idempotency_key="customer-signup-456",
)

Idempotency

The SDK accepts an idempotency_key and sends it as:

Idempotency-Key: your-key

Use stable keys for requests that your application may retry after timeouts or transient failures.

Errors

Unsuccessful requests raise structured exceptions from paravane.errors.

from paravane import (
    AuthenticationError,
    ParavaneClient,
    QuotaExceededError,
    RateLimitError,
    ValidationError,
)

client = ParavaneClient()

try:
    result = client.smtprs.analyze("person@example.com")
except AuthenticationError:
    print("Check your API key.")
except QuotaExceededError:
    print("The workspace has exhausted its available credits.")
except RateLimitError:
    print("Slow down and retry later.")
except ValidationError as exc:
    print("Request was invalid:", exc)

Exception classes:

Class Typical cause
ConfigurationError Missing API key or invalid client setup.
APIConnectionError Network failure, timeout, DNS failure, or connection error.
APIError Generic non-success API response.
AuthenticationError Missing, invalid, or revoked API key.
PermissionDeniedError API key lacks access to the requested resource.
ValidationError Invalid request payload or parameters.
QuotaExceededError Plan or credit quota has been exhausted.
RateLimitError Too many requests.

API errors include useful details when available:

try:
    client.smtprs.analyze("not-an-email")
except ValidationError as exc:
    print(exc.status_code)
    print(exc.code)
    print(exc.request_id)
    print(exc.response)

Responses and raw data

The SDK returns SmtpRsAnalysis for smtpRS analysis requests.

result = client.smtprs.analyze("person@example.com")

Common fields:

Field Description
email Email address represented by the response, when returned by the API.
decision Customer-facing decision or recommendation, when returned by the API.
overall_risk Overall risk score, when returned by the API.
tier Workspace/API-key tier reflected by the response.
analysis_profile Analysis path used by the API.
response_profile Response shape, such as summary/full.
credit_cost Planned credit cost for the selected profile.
credits_charged Credits recorded for the request, when returned.
company_validity_beta Typed beta status, opt-in state, availability, credit cost, and API notes.
domain_signal Typed domain, mail, and company-context facts when returned.
reasons Human-readable reason strings, when returned.
usage Usage/quota snapshot, when returned.
raw Original API payload.

To avoid losing fields added by the API before the SDK is updated, the full payload is always preserved:

raw = result.to_dict()
print(raw["usage"])

Types

This package includes inline type hints and ships a py.typed marker.

The response helper is a dataclass:

from paravane import SmtpRsAnalysis


def handle_result(result: SmtpRsAnalysis) -> None:
    print(result.decision)
    signal = result.domain_signal
    if signal is not None:
        print(signal.mail_capable)

Type hints are intended to describe stable SDK behavior. The raw API response may include additional fields that are not represented as first-class dataclass attributes yet.

Logging

The SDK does not install or configure logging handlers. Applications should configure logging at the application boundary.

For now, request failures are surfaced through exceptions. If you need detailed HTTP logging during development, configure your own requests.Session or enable logging in your HTTP stack.

Examples

This repository includes small examples:

examples/basic_analyze.py
examples/strict_analyze.py
examples/batch_csv.py

Run one with:

PARAVANE_API_KEY="pvn_live_..." python examples/basic_analyze.py

Windows PowerShell:

$env:PARAVANE_API_KEY = "pvn_live_..."
python examples/basic_analyze.py

Development

Create an environment:

python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"

Windows PowerShell:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"

Run tests:

pytest

Run lint:

ruff check .

Build the package:

python -m build

Recommended pre-commit check:

pytest && ruff check . && python -m build

Repository layout

paravane-python/
  .github/workflows/   GitHub Actions checks
  examples/            Small runnable examples
  src/paravane/        SDK package source
  tests/               Unit tests
  pyproject.toml       Packaging metadata and tool config
  RELEASING.md         Maintainer release process

Versioning

Current package version:

1.0.2

Security

Do not put API keys in source code, client-side apps, mobile apps, screenshots, or public repositories.

Recommended handling:

  • load API keys from environment variables or a secret manager
  • rotate keys if they are exposed
  • create separate keys for development, staging, and production
  • revoke keys that are no longer needed

Report suspected vulnerabilities privately:

security@paravane.io

Support

For product or account support:

contact@paravane.io

For security reports:

security@paravane.io

Release files for paravane 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for paravane 1.0.2
File Size Uploaded
paravane-1.0.2.tar.gz 22.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for paravane 1.0.2
File Interpreter ABI Platform
paravane-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 38.7 kB

Release files / paravane-1.0.2.tar.gz

Download URL paravane-1.0.2.tar.gz
Size 22.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b09428ee72dc066a1e1f77d6917cf09c9e922aedff69408a328a3d33acec2110
BLAKE2b-256 checksum
How to use checksums
08bff3b788322bb9c0513ca50e5455b76eb93e2a0c57c77aa4ef959126dfb8a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release files / paravane-1.0.2-py3-none-any.whl

Download URL paravane-1.0.2-py3-none-any.whl
Size 16.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5601c1de1d467c721e6cf7fd9ad1a0f6ffa38e0b5fcc6e76233820e64e0cd988
BLAKE2b-256 checksum
How to use checksums
19b14b37790e259e7c8c3c87611dcd33853f82f9dd2e7a8ca7c38ebfb006e507
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.3

2 release files

This release

1.0.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page