description: dlt source for affinity.co keywords: [Affinity API, affinity.co, CRM]
dlt-source-affinity
If you don't know DLT but stumbled across this when trying to search if you can get your data out of Affinity somehow: this will do it - it basically allows you to pull mostly any (except some enriched) data out of your Affinity instance and into a different target system (Snowflake, Postgres, etc.) that is supported by DLT.
Usage
Create a .dlt/secrets.toml with your API key:
affinity_api_key="<YOUR_API_KEY>"
and then run the default source with optional list references:
from dlt_source_affinity import ListReference, source as affinity_source
pipeline = dlt.pipeline(
pipeline_name="affinity_pipeline",
destination="duckdb",
dev_mode=True,
)
affinity_data = affinity_source(
# By default the data source loads:
# - organizations
# - persons
# - lists
# - opportunities
# - notes
# And then we can optionally pass an arbitrary number of lists and list views:
list_refs=[
# Loads a list with ID 123,
# e.g. https://<your-subdomain>.affinity.co/lists/123/
ListReference(123),
# Loads a view with ID 456 in list 123,
# e.g. https://<your-subdomain>.affinity.co/lists/123/views/456-all-organizations
ListReference(123, 456),
]
)
pipeline.run(affinity_data)
Resources
Resources that can be loaded using this verified source are:
| Name | Description | API version | Permissions needed |
|---|---|---|---|
| companies | The stored companies | V2 | Requires the "Export All Organizations directory" permission. |
| persons | The stored persons | V2 | Requires the "Export All People directory" permission. |
| opportunities | The stored opportunities | V2 | Requires the "Export data from Lists" permission. |
| lists | A given list and/or a saved view of a list | V2 | Requires the "Export data from Lists" permission. |
| notes | Notes attached to companies, persons, opportunities | Legacy | n/a |
V1 vs V2
There are two versions of the Affinity API:
- Legacy which is available for all plans.
- V2 which is only available for customers with an enterprise plan.
This verified source makes use of both API endpoints. The authentication credentials for both APIs are the same, however, they differ in their authentication behavior.
Initialize the pipeline
dlt init affinity duckdb
Here, we chose duckdb as the destination. Alternatively, you can also choose redshift, bigquery, or any of the other destinations.
Add credentials
- You'll need to obtain your API key and configure the pipeline with it.
Development
This project is using devenv.
Run the sample
AFFINITY_API_KEY=[...] python affinity_pipeline.py
Regenerate V2 model
Run
generate-model
🚀 Development Workflow
- Make changes to your code
- Format code with
formatbefore committing - Commit changes - pre-commit hooks will run automatically
- Push to GitHub - CI will run tests on multiple platforms
- Create release by pushing a tag (format:
vX.X.X)
📦 Publishing
Publishing to PyPI is fully automated:
- Create a new tag:
git tag v1.0.0 - Push the tag:
git push origin v1.0.0 - GitHub Actions will automatically build and publish to PyPI
The project uses trusted publishing, so no API keys are required.
Metadata
Release files for dlt-source-affinity 0.1.20
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dlt_source_affinity-0.1.20.tar.gz | 20.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dlt_source_affinity-0.1.20-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.9 kB
Release files / dlt_source_affinity-0.1.20.tar.gz
| Download URL | dlt_source_affinity-0.1.20.tar.gz |
|---|---|
| Size | 20.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b3045f58c9f418a55b302928c65392b4f2e3bc9dddd41b60bd1fddde832ca4a2
|
|
BLAKE2b-256 checksum How to use checksums |
222378e37c6c6245c5d5bf22d73177cc99c983fad424a0e40bd0bb04dd4003df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Dec 9, 2025.
Transparency logRelease files / dlt_source_affinity-0.1.20-py3-none-any.whl
| Download URL | dlt_source_affinity-0.1.20-py3-none-any.whl |
|---|---|
| Size | 23.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
10afb7b9a3ebf769c672a1b9bcda173053b3f6c1c4bcf5a4a4dd2194081e53a6
|
|
BLAKE2b-256 checksum How to use checksums |
1ae50f85fc036b0047706ddb97163f5d51a4df05bfa08bc1b91cf24077eb53e3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Dec 9, 2025.
Transparency log