Skip to main content

Python SDK for the Vorlek email-marketing aggregation API

Project description

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/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vorlek-1.2.0.tar.gz (52.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vorlek-1.2.0-py3-none-any.whl (123.1 kB view details)

Uploaded Python 3

File details

Details for the file vorlek-1.2.0.tar.gz.

File metadata

  • Download URL: vorlek-1.2.0.tar.gz
  • Upload date:
  • Size: 52.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vorlek-1.2.0.tar.gz
Algorithm Hash digest
SHA256 a5268a4fca5aebcf3d438dbfb4e08e9a83bab2da54114a8d7b4f4b02d70befc7
MD5 b678da09a51ac3b1d6ae3854915c964e
BLAKE2b-256 cf8c0a9a258a0a748b7446878199a521d74e04aca3c162ef9058ca9b7a55c4ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for vorlek-1.2.0.tar.gz:

Publisher: publish.yml on vorlek/vorlek-sdk-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vorlek-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: vorlek-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 123.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vorlek-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a098491b2a31c97ec5cd60b272468275775341273159d98c7d5ce9c3b506a323
MD5 170ab2999556a9d970ce904767c6bf7c
BLAKE2b-256 6f221a6258d136920ec197a4bcd57fb2602fd79a465c50a8afc0d0deba4ccf7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for vorlek-1.2.0-py3-none-any.whl:

Publisher: publish.yml on vorlek/vorlek-sdk-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page