VVEREID Docs
sdks

SDK — Python

vereid-py — the official Python SDK with sync and async APIs, full type hints, and a built-in FastAPI middleware.

Last updated 2026-05-20

vereid-py is the official Python SDK. It uses httpx under the hood and offers both blocking and asyncio-native clients. Type hints are exhaustive and tested under mypy --strict.

Install

pip install vereid
# with FastAPI middleware
pip install "vereid[fastapi]"
# with Django middleware
pip install "vereid[django]"

Quickstart

from vereid import Vereid
 
vereid = Vereid(api_key=os.environ["VEREID_API_KEY"])
 
profile = vereid.social.profiles.get("@mina")
print(profile.display_name, profile.verification.tier)
 
session = vereid.verify.sessions.create(
    tiers=["T1", "T2"],
    reference="user_42",
)

Async

import asyncio
from vereid import AsyncVereid
 
async def main():
    async with AsyncVereid(api_key=...) as vereid:
        session = await vereid.verify.sessions.create(
            tiers=["T1", "T2"], reference="user_42"
        )
        async for post in vereid.social.timeline.iterate("@mina"):
            print(post.body)
 
asyncio.run(main())

Both clients share the same surface; only the call site differs. The async client uses httpx.AsyncClient and supports trio via httpx's anyio backend.

Webhook verification

from vereid.webhooks import verify
 
@app.post("/webhooks/vereid")
async def webhook(request: Request):
    raw = await request.body()
    if not verify(raw, request.headers.get("vereid-signature"), SECRET):
        raise HTTPException(400)
    event = json.loads(raw)
    ...

FastAPI middleware

The [fastapi] extra ships a dependency that authenticates incoming requests against VEREID Auth (bearer token), validates the id_token, and exposes the typed user + verification claim.

from fastapi import Depends, FastAPI
from vereid.fastapi import vereid_user, VereidUser
 
app = FastAPI()
 
@app.get("/me")
def me(user: VereidUser = Depends(vereid_user(scopes=["openid"]))):
    return {"sub": user.sub, "tier": user.verification.tier}
 
@app.post("/sensitive")
def sensitive(
    user: VereidUser = Depends(
        vereid_user(require_badge="liveness")
    ),
):
    ...

The require_badge parameter raises 403 verification_required (with a hint URL) when the user does not hold the badge — your client SDK then redirects them through the hosted verify flow.

Django middleware

# settings.py
MIDDLEWARE = [
    ...,
    "vereid.django.VereidAuthMiddleware",
]
VEREID = {
    "CLIENT_ID": os.environ["VEREID_CLIENT_ID"],
    "ISSUER": "https://auth.vereid.com",
}
# views.py
def me(request):
    return JsonResponse({
        "sub": request.vereid_user.sub,
        "tier": request.vereid_user.verification.tier,
    })

Error handling

from vereid import VereidError, RateLimitError, ValidationError
 
try:
    vereid.verify.sessions.create(tiers=["T7"])
except ValidationError as e:
    log.error("bad request", extra={"detail": e.detail, "request_id": e.request_id})
except RateLimitError as e:
    time.sleep(e.retry_after)

The base VereidError always carries .problem (RFC 9457), .request_id, .status_code, and .response for forensic logging.

Pagination

# Manual paging
page = vereid.social.timeline.list("@mina", limit=20)
print(page.data, page.next_cursor)
next_page = vereid.social.timeline.list("@mina", cursor=page.next_cursor)
 
# Iterator (handles cursor for you)
for post in vereid.social.timeline.iterate("@mina"):
    ...

Mocking in tests

from vereid.testing import MockVereid
 
vereid = MockVereid()
vereid.verify.sessions.create.return_value = {
    "id": "vs_test",
    "status": "pending",
    "hosted_url": "https://id.vereid.com/s/test",
}

Type stubs

The wheel ships a py.typed marker. Every model is a dataclass (or pydantic.BaseModel if you install the [pydantic] extra). mypy --strict and pyright both pass cleanly with no third-party stubs needed.

Where to next

  • OIDC claims — what the VereidUser.verification field looks like.
  • Webhooks — wire format and replay window.
  • Rate limits — the SDK automatically respects retry-after.