vellumcharter
Thin, dependency-free (stdlib-only) server-side client for the VellumCharter entitlements + billing API. Server-side only — it holds a secret API key.
Install
pip install vellumcharter
Requires Python 3.11+.
Usage
from vellumcharter import VellumCharterClient
vellum = VellumCharterClient(
api_key="vlm_sam.xxxxx", # keep server-side, never ship to a browser
tenant_id="sam",
# base_url defaults to https://api.vellumcharter.com
)
# Gate a feature (cached with a short TTL):
if vellum.can("unit_1", "imports"):
...
ent = vellum.get_entitlements("unit_1")
ent.has_access() # server-authoritative; for reporting, not gating
ent.has("imports") # gate on THIS
ent.config("trial_days")
ent.found # False if the customer has no record (no exception)
A 404 returns an empty EntitlementSet (no exception), so gating never needs a
null check.
Async
AsyncVellumCharterClient is the awaitable counterpart — same constructor and
methods, each await-ed. Use it from async frameworks (e.g. FastAPI):
from vellumcharter import AsyncVellumCharterClient
vellum = AsyncVellumCharterClient(api_key="vlm_sam.xxxxx", tenant_id="sam")
if await vellum.can("unit_1", "imports"):
...
ent = await vellum.get_entitlements("unit_1")
vellum.invalidate("unit_1") # cache op is synchronous (no await)
What it covers
- Entitlements:
get_entitlements,can, opt-in TTL cache +invalidate. - Checkout / subscriptions:
create_checkout,create_setup_checkout,create_subscription,cancel_subscription,get_subscription. - Provisioning:
create_account,create_customer,set_account_status,set_customer_status. - Billing:
list_payment_methods,set_default_payment_method,remove_payment_method,set_subscription_payment_method,list_invoices,invoice_pdf_url. - Webhook verification:
verify_push_signature(raw_body, header, secret)— validates a push and returns the parsed event (raises on a bad signature).
Billing reads return dicts in the server's camelCase shape:
get_subscription→id(deprecated, removed in 1.0.0),status,cancelAtPeriodEnd,seats,amount(per-seat price, cents),currency,interval(month/year),currentPeriodStart,currentPeriodEnd,trialEnd,canceledAt,defaultPaymentMethod(deprecated, removed in 1.0.0),defaultPaymentMethodRef(an opaque handle, byte-identical to the matching payment method'sref; omitted if it could not be minted — fall back todefaultPaymentMethod; all timestamps ISO 8601).list_payment_methods→ items ofid(deprecated, removed in 1.0.0),ref(opaque, account-bound — send this to the methods below; omitted if it could not be minted, fall back toid),brand,last4,expMonth,expYear,name(cardholder),isDefault.list_invoices→ items ofid(deprecated, removed in 1.0.0),ref(opaque, account-bound — send this toinvoice_pdf_url; omitted if it could not be minted, fall back toid),number,status,amountDue,amountPaid,subtotal,total,tax,paid,currency,created(ISO),hostedInvoiceUrl,invoicePdf(deprecated, removed in 1.0.0 — useinvoice_pdf_url, which redirects to the hosted PDF after an ownership check).
set_default_payment_method, remove_payment_method,
set_subscription_payment_method, and invoice_pdf_url each take a ref
from the calls above; a raw billing-provider id is still accepted in the same
argument but is deprecated and removed in 1.0.0.
payment.* push events additionally carry seats and an invoice block
(id, number, status, amountDue, amountPaid, currency,
hostedInvoiceUrl, invoicePdf) so a dunning notice needs no follow-up read.
invoice.id and invoice.invoicePdf are deprecated the same way as their
pull-API counterparts, but the push payload has no ref to migrate onto yet,
so their removal is tracked separately (D40, TODO.md) rather than tied to the
SDK's 1.0.0.
Errors
VellumCharterAuthError on 401/403; VellumCharterApiError (with .status /
.body) on other non-2xx; VellumCharterSignatureError on a bad push signature.
The API key is sent as x-api-key on every request.
API reference
Full endpoint + webhook contract: https://api.vellumcharter.com/openapi.json
Upgrading to 1.0.0
Breaking. Every raw billing-provider id is gone from the contract; objects that
need a handle carry an opaque, account-bound ref instead.
| Removed | Use instead |
|---|---|
PaymentMethod.id |
PaymentMethod.ref |
Invoice.id |
Invoice.ref |
Invoice.invoicePdf |
invoice_pdf_url(account_id=..., invoice_id=<ref>) — redirects to the hosted PDF after an ownership check |
SubscriptionView.id |
address the subscription by (account_id, customer_id) |
SubscriptionView.defaultPaymentMethod |
defaultPaymentMethodRef |
SubscribeResponse.subscriptionId |
address the subscription by (account_id, customer_id) |
CreateAccountResponse.billingCustomerId |
address the account by account_id |
Entitlements.billingSubscriptionId |
address the subscription by (account_id, customer_id) |
Raw ids are no longer accepted on input. set_default_payment_method,
remove_payment_method, set_subscription_payment_method and
invoice_pdf_url take a ref; anything else returns 404, deliberately — a
403 would confirm the object exists.
set_subscription_payment_method now returns the updated subscription view
rather than {"subscription", "default"}, matching every other subscription
mutation.
ref is always present. Through 0.10.0 it could be omitted if the server failed
to mint one and you fell back to id; with id gone the server fails closed
instead, so a response either has a usable ref or is an error.
Two things did not change: Invoice.hostedInvoiceUrl (a Stripe-hosted
payment page, not an identifier) and the inbound billing_customer_id on
create_account, which adopts a customer that predates Vellum.
Both clients are affected identically — VellumCharterClient and the async
AsyncVellumCharterClient stay in step.
Metadata
Release files for vellumcharter 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vellumcharter-1.1.0.tar.gz | 14.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vellumcharter-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.4 kB
Release files / vellumcharter-1.1.0.tar.gz
| Download URL | vellumcharter-1.1.0.tar.gz |
|---|---|
| Size | 14.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8176a44946e93e523c90dde26650f92e0dcc04db3f242d391c2e63948767c53c
|
|
BLAKE2b-256 checksum How to use checksums |
193383660b0c7ea436fc4931a369b8e483c2c6362bf548f229fed791568e11e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 12, 2026.
Transparency logRelease files / vellumcharter-1.1.0-py3-none-any.whl
| Download URL | vellumcharter-1.1.0-py3-none-any.whl |
|---|---|
| Size | 14.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b7f10b54c2d62b4bc6c8231d9efe5035395b4d54c2992ede8adcff3806f35631
|
|
BLAKE2b-256 checksum How to use checksums |
54ea77a52164e8f3bd01dbb828be9590ef0cd01640009fa1501fad0436a07d64
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 12, 2026.
Transparency log