Skip to content

Getting started

Requires Python 3.10+.

Provide your API key

Set AFFINITY_API_KEY:

export AFFINITY_API_KEY="your-api-key"

Then create a client from the environment:

from affinity import Affinity

client = Affinity.from_env()

To load a local .env file, install the optional extra and set load_dotenv=True:

pip install "affinity-sdk[dotenv]"
from affinity import Affinity

client = Affinity.from_env(load_dotenv=True)

Disable writes (policy)

If you want the SDK to guarantee it does not perform write operations (POST/PUT/PATCH/DELETE), disable writes via policy:

from affinity import Affinity
from affinity.policies import Policies, WritePolicy

client = Affinity.from_env(policies=Policies(write=WritePolicy.DENY))

Create a client

from affinity import Affinity

client = Affinity(api_key="your-api-key")

Prefer the context manager to ensure resources are closed:

from affinity import Affinity

with Affinity(api_key="your-api-key") as client:
    ...

Make your first request

This snippet covers authentication, a first request, and common failures:

from affinity import Affinity
from affinity.exceptions import AuthenticationError, RateLimitError

try:
    with Affinity.from_env() as client:
        me = client.whoami()
        print(f"Authenticated as: {me.user.email}")
except AuthenticationError:
    print("Check AFFINITY_API_KEY is set correctly")
except RateLimitError as e:
    print(f"Rate limited. Retry after: {e.retry_after}")

Resolve a list by name

If you have a list name from configuration (and not a ListId), you can resolve it:

from affinity import Affinity
from affinity.types import ListType

with Affinity.from_env() as client:
    pipeline = client.lists.resolve(name="Deal Pipeline", list_type=ListType.OPPORTUNITY)
    if pipeline is None:
        raise ValueError("List not found")
    for entry in client.lists.entries(pipeline.id).all():
        ...

SDK-specific gotchas

  • Use typed IDs (e.g., CompanyId(123)) instead of raw integers.
  • Entity fields are only present when requested; check entity.fields.requested.
  • Some write operations still route to V1; see the V1 vs V2 routing guide.

Sync vs async

  • Use Affinity for synchronous code.
  • Use AsyncAffinity for async/await code.

See Sync vs async.

Next steps