A previous release had provenance metadata, but this release does not. View details.
Vorlek Python SDK
Python client for the Vorlek API. It exposes the Phase 2 tool surface with
automatic idempotency keys, normalized {data, meta} results, and typed
exceptions for API and network failures.
pip install vorlek
Requires Python 3.10 or newer.
Quickstart (sync)
import os
from vorlek import VorlekClient
with VorlekClient(api_key=os.environ["VORLEK_API_KEY"]) as client:
result = client.contact.upsert(
provider="sendgrid",
email="jamie@example.com",
first_name="Jamie",
properties={"plan": "free"},
)
print(result.data["contact_id"])
print(result.meta.request_id)
catalog = client.catalog.get()
print([tool["name"] for tool in catalog.data["tools"]])
operation = client.operations.get(result.meta.request_id)
print(operation.data["status"])
minimal = client.contact.upsert(
provider="sendgrid",
email="minimal@example.com",
detail="minimal",
)
print(minimal.meta.detail)
Quickstart (async)
import asyncio
import os
from vorlek import AsyncVorlekClient
async def main() -> None:
async with AsyncVorlekClient(api_key=os.environ["VORLEK_API_KEY"]) as client:
result = await client.connection.status(provider="sendgrid")
print(result.data["status"])
print(result.meta.request_id)
asyncio.run(main())
Methods
All tool calls are keyword-only and return VorlekResult[T], where
result.data is the normalized tool payload and result.meta includes the
request id, quota state, rate-limit state, and idempotency replay state when
present.
result.data is parsed JSON: at runtime it is dict[str, object], even
though the per-tool aliases (UpsertContactResult, SendTransactionalResult,
etc.) point at the generated dataclasses for type-checker convenience. Use
subscript syntax — result.data["contact_id"], not result.data.contact_id.
| Namespace | Method | Endpoint |
|---|---|---|
client.contact |
upsert(...) |
POST /v1/tools/upsert_contact |
client.connection |
status(...) |
POST /v1/tools/get_connection_status |
client.send |
transactional(...) |
POST /v1/tools/send_transactional |
client.campaign |
stats(...) |
POST /v1/tools/get_campaign_stats |
client.campaign |
list(...) |
POST /v1/tools/list_campaigns |
client.template |
list(...) |
POST /v1/tools/list_templates |
client.catalog |
get() |
GET /v1/catalog |
client.operations |
get(request_id) |
GET /v1/operations/{request_id} |
Supported providers are sendgrid, mailchimp, and klaviyo. Argument
types are generated from the live OpenAPI schema and are also documented at
https://vorlek.dev/openapi.json.
Tool methods accept detail="minimal", detail="standard", or
detail="full". minimal trims envelope metadata, standard is the default,
and full adds operation lookup metadata.
client.template.list(query="welcome") filters the returned template page
across id, name, and subject. When the page has no match, inspect
result.data["search"]["no_match"] for the suggested next action.
client.contact.get(provider="sendgrid", email="test@example.com") reads one
contact by email for same-surface read-after-write verification after an
upsert.
Error handling
Vorlek raises subclasses of VorlekError. Caller mistakes are grouped under
VorlekClientError, while more specific classes let applications handle common
cases directly.
from vorlek import (
VorlekClient,
VorlekClientError,
VorlekError,
VorlekRateLimitedError,
is_retryable_error,
)
client = VorlekClient(api_key="vk_live_...")
try:
result = client.contact.upsert(provider="sendgrid", email="jamie@example.com")
except VorlekRateLimitedError as err:
print(f"rate limited, retry after {err.retry_after} seconds")
except VorlekClientError as err:
print(f"fix the request before retrying: {err.code} {err.message}")
except VorlekError as err:
if is_retryable_error(err):
print(f"retry with backoff: {err.code}")
else:
print(f"not retry-safe: {err.code}")
else:
print(result.data)
finally:
client.close()
Every error exposes code, category, retry_safe, http_status,
request_id, provider, retry_after, and detail.
Idempotency
Every tool call sends an Idempotency-Key header. By default the SDK generates
a fresh ULID per request.
Pass idempotency_key to retry one logical operation with the same key:
result = client.contact.upsert(
provider="mailchimp",
email="jamie@example.com",
idempotency_key="01HV0011V0110011V011001100",
)
print(result.meta.idempotency.replay if result.meta.idempotency else False)
Calling the same key twice with the same request body is safe. Reusing the same
key with a different body raises VorlekIdempotencyConflictError.
from_ on transactional sends
Python reserves from as a keyword, so the SDK accepts from_ and sends it to
the API as from.
client.send.transactional(
provider="sendgrid",
to="jamie@example.com",
from_="updates@example.com",
subject="Welcome",
text="Thanks for trying Vorlek.",
)
Test mode
vk_test_* keys pass through the SDK today. Full test-mode behavior, including
provider-free deterministic tool responses, is planned for Phase 3.6 and will
be documented at https://vorlek.dev/docs/test-mode when it ships.
Examples
The examples/ directory contains small scripts that run from a virtual
environment:
export VORLEK_API_KEY=vk_live_...
python examples/upsert.py
python examples/send_transactional.py
python examples/cross_provider_round_trip.py
Each script exits successfully with a skip message when required environment variables are missing.
Cross-SDK parity
The TypeScript SDK is published as @vorlek/sdk. Both SDKs surface the same
{data, meta} success contract and the same six tool namespaces. Python v1
ships the full 18-class error hierarchy; the TypeScript retrofit is tracked at
https://github.com/vorlek/vorlek-sdk-ts/issues/2.
Local development
python -m venv .venv
. .venv/bin/activate
pip install -e ".[dev]"
ruff check .
ruff format --check .
mypy src/vorlek
pytest -q
python scripts/generate_types.py && git diff --exit-code src/vorlek/_generated/
Metadata
Release files for vorlek 1.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Loss of provenance
These files do not have provenance metadata, despite files in a prior release including this data.
We recommend further investigation before installing these files. View details.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| vorlek-1.2.3.tar.gz | 54.0 kB | Without provenance | Details for vorlek-1.2.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| vorlek-1.2.3-py3-none-any.whl | Python 3 | none | any | Details for vorlek-1.2.3-py3-none-any.whl |
Total release size: 180.4 kB
Release files / vorlek-1.2.3.tar.gz
Loss of provenance
This file belongs to a release without provenance metadata, despite a prior release including this data.
We recommend further investigation before installing this file. View details.
| Download URL | vorlek-1.2.3.tar.gz |
|---|---|
| Size | 54.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a47c917cccc253743ecdb6dea97655a6ce44d2945b980f801a1a5ef4e3a69a51
|
|
BLAKE2b-256 checksum How to use checksums |
1c14b724666c5d6219bad70bff4559cfa7989849b230846931a743c8ed66ecbe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / vorlek-1.2.3-py3-none-any.whl
Loss of provenance
This file belongs to a release without provenance metadata, despite a prior release including this data.
We recommend further investigation before installing this file. View details.
| Download URL | vorlek-1.2.3-py3-none-any.whl |
|---|---|
| Size | 126.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4ce6bab4998a4891169a67a381534615dd20212d97a92c07e419018138cfd130
|
|
BLAKE2b-256 checksum How to use checksums |
1fc01ac70d87b410d1b653fce1673899df5be4e05bc2f8f294d36780dd9e65c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Security for vorlek 1.2.3
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.
Loss of provenance
A previous release of these files had provenance metadata, but this release does not.
While this could reflect a routine change by the project maintainers, it may also indicate that the release files have been compromised.
Release comparison
- Removed 1.2.2 2 files With provenance
- Added 1.2.3 2 files Without provenance
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.