Skip to main content

Python client for the Kajabi API

Project description

kajabi-py

Python client for the Kajabi API. Provides both sync and async interfaces with full type hints, Pydantic models, and automatic OAuth2 token management.

Installation

pip install kajabi-py

Requires Python 3.11+.

Quick start

from kajabi import Client

client = Client(client_id="your_id", client_secret="your_secret")

# List resources — returns a lazy collection, no request until accessed
contacts = client.contacts.list()
print(contacts.count)        # total across all pages (triggers first page fetch)
print(contacts[0].name)      # indexed access (fetches page if not cached)
for contact in contacts:     # iterates all pages lazily
    print(contact.name, contact.email)

# Get a single resource
post = client.blog_posts.get("42")

# Create, update, delete
contact = client.contacts.create(
    name="Jane Doe",
    email="jane@example.com",
    site_id="your_site_id",
)
contact = contact.update(name="Jane Smith")
contact.delete()

Async

from kajabi import AsyncClient

async with AsyncClient(client_id="your_id", client_secret="your_secret") as client:
    contacts = client.contacts.list()          # no await — returns collection immediately
    count = await contacts.acount()            # total across all pages
    first = await contacts.aget(0)             # indexed access
    async for contact in contacts:             # iterates all pages lazily
        print(contact.name)
    contact = await client.contacts.get("42")
    contact = await contact.aupdate(name="Updated Name")
    await contact.adelete()

Authentication

Pass client_id/client_secret or username/password. Authentication is lazy -- the first API call triggers the token exchange. Tokens are refreshed automatically.

# OAuth2 client credentials
client = Client(client_id="...", client_secret="...")

# Resource owner password
client = Client(username="user@example.com", password="...")

Resources

All resources are Pydantic models returned from manager methods on the client. Read-only resources support get() and list(). Writable resources also support create(), update()/aupdate(), and delete()/adelete().

Manager Model Writable
blog_posts BlogPost No
contacts Contact Yes
contact_notes ContactNote Yes
contact_tags ContactTag No
courses Course No
custom_fields CustomField No
customers Customer No
forms Form No
form_submissions FormSubmission No
landing_pages LandingPage No
offers Offer No
orders Order No
order_items OrderItem No
payouts Payout No
podcasts Podcast No
products Product No
purchases Purchase No
sites Site No
site_pages SitePage No
transactions Transaction No
webhooks Webhook Yes (create/delete)

Filtering, sorting, and sparse fields

contacts = client.contacts.list(
    filters={"site_id": "123"},
    sort="-created_at",
    fields=["name", "email"],
)

The default page size is 20. Pass page_size when constructing the client to change it globally:

client = Client(client_id="...", client_secret="...", page_size=50)

Lazy-loading related resources

Relationship ID fields (e.g., site_id, product_ids) have corresponding properties that lazily load the full resource on first access. Results are cached for the lifetime of the instance.

customer = client.customers.get("123")

# Single relation: customer.site_id -> customer.site
site = customer.site  # fetches Site on first access, cached thereafter

# Plural relation: customer.product_ids -> customer.products
products = customer.products  # fetches each Product, cached thereafter

Returns None for single relations when the ID is None, and an empty list for plural relations with no IDs. Accessing a relation descriptor on an async client raises KajabiError -- use explicit async calls instead.

Relationships

Some resources expose relationship operations:

# Contact tags
contact.list_tags()
contact.add_tags(["tag-id-1", "tag-id-2"])
contact.remove_tags(["tag-id-1"])

# Contact/Customer offers
contact.grant_offers(["offer-id-1"])
contact.revoke_offers(["offer-id-1"])

# Form submissions
form.submit(email="user@example.com", name="User")

# Purchase actions
purchase.reactivate()
purchase.deactivate()
purchase.cancel_subscription()

Convenience endpoints

me = client.me()        # current user profile
ver = client.version()  # API version info

Error handling

All errors inherit from KajabiError. HTTP errors are mapped to specific exception types:

Status Exception
400 BadRequestError
401 AuthenticationError
403 AuthorizationError
404 NotFoundError
405 MethodNotAllowed
422 ValidationError
429 RateLimitError
5xx ServerError
from kajabi import Client, NotFoundError

try:
    client.contacts.get("nonexistent")
except NotFoundError as e:
    print(e)

Development

uv sync
uv run pytest
uv run ruff check .
uv run ty check

Pre-commit hooks are managed with prek:

uv run prek install
uv run prek run --all-files

License

Apache 2.0

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

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

Source Distribution

kajabi_py-0.1.tar.gz (114.5 kB view details)

Uploaded Source

Built Distribution

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

kajabi_py-0.1-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file kajabi_py-0.1.tar.gz.

File metadata

  • Download URL: kajabi_py-0.1.tar.gz
  • Upload date:
  • Size: 114.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for kajabi_py-0.1.tar.gz
Algorithm Hash digest
SHA256 09648b145ab1dfa943a407bc00e36e1fca50fe0ad74c0f56ba653c34ab92695f
MD5 540ef437c484d34e3a9932e8bb3829c5
BLAKE2b-256 420e72087ec88c592573e67111761860803817f6f429472603a144e346540642

See more details on using hashes here.

File details

Details for the file kajabi_py-0.1-py3-none-any.whl.

File metadata

  • Download URL: kajabi_py-0.1-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for kajabi_py-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3c2b4678313fd6bb939922ed51ba64247ad01dea1921d49ef1af30d6adafc41b
MD5 ad9351c2698b2b9884fec837168f63ee
BLAKE2b-256 53cee5953731974b905f8552f9d40a28019136adf0514fbd2b76723c9338ac1a

See more details on using hashes here.

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