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.
- Repo: github.com/vereid/sdk (
packages/python) - License: MIT
- Python: 3.9, 3.10, 3.11, 3.12, 3.13
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.verificationfield looks like. - Webhooks — wire format and replay window.
- Rate limits — the SDK automatically respects
retry-after.