Skip to main content

leadsdb

PyPI version Python 3.10+ License: MIT

Python SDK for the LeadsDB API.

Features:

  • Sync and async clients
  • Pydantic models with validation
  • Fluent filter API
  • Automatic pagination
  • Retry with exponential backoff
  • Full type hints

Installation

pip install leadsdb

Requires Python 3.10+.

Quick Start

from leadsdb import LeadsDB, Lead

client = LeadsDB("your-api-key")

# Create a lead
lead = client.create(Lead(
    name="Acme Corporation",
    source="website",
    city="San Francisco",
    email="contact@acme.com",
    rating=4.5,
    tags=["enterprise", "saas"],
))

print(f"Created: {lead.name} ({lead.id})")

Async Client

import asyncio
from leadsdb import AsyncLeadsDB, Lead

async def main():
    async with AsyncLeadsDB("your-api-key") as client:
        lead = await client.create(Lead(
            name="Acme Corporation",
            source="website",
        ))
        print(f"Created: {lead.name}")

asyncio.run(main())

Client Options

client = LeadsDB(
    api_key,
    base_url="https://custom.api.com",
    timeout=30.0,
    max_retries=5,
)

CRUD Operations

Create

from leadsdb import Lead, text_attr, number_attr, bool_attr, list_attr

lead = client.create(Lead(
    name="Acme Corporation",
    source="website",
    description="Leading provider of innovative solutions",
    address="123 Main Street",
    city="San Francisco",
    state="CA",
    country="USA",
    postal_code="94105",
    latitude=37.7749,
    longitude=-122.4194,
    phone="+1-555-123-4567",
    email="contact@acme.com",
    website="https://acme.com",
    rating=4.5,
    review_count=128,
    category="Technology",
    tags=["enterprise", "saas", "b2b"],
    source_id="acme-001",
    logo_url="https://acme.com/logo.png",
    attributes=[
        text_attr("industry", "Software"),
        number_attr("employees", 500),
        bool_attr("verified", True),
        list_attr("products", ["CRM", "ERP", "Analytics"]),
    ],
))

Get

lead = client.get("lead-id")

Update

from leadsdb import UpdateLeadInput

lead = client.update("lead-id", UpdateLeadInput(
    rating=4.8,
    city="New York",
    tags=["enterprise", "saas", "b2b", "updated"],
))

Delete

client.delete("lead-id")

Listing Leads

Basic List

from leadsdb import city, rating, SortField, SortOrder

result = client.list(
    city().eq("Berlin"),
    rating().gte(4.0),
    sort_by=SortField.NAME,
    sort_order=SortOrder.ASC,
    limit=20,
)

for lead in result.leads:
    print(f"{lead.name} ({lead.city})")

# Pagination
if result.has_more:
    next_result = client.list(
        city().eq("Berlin"),
        cursor=result.next_cursor,
    )

Iterator (Automatic Pagination)

for lead in client.iterate(city().eq("Berlin"), sort_by=SortField.NAME):
    print(lead.name)

Async Iterator

async for lead in client.iterate(city().eq("Berlin")):
    print(lead.name)

Filters

All filters default to AND logic. Use or_() for OR logic.

Text Fields

Available for: name(), city(), country(), state(), category(), source(), email(), phone(), website()

Method Description
eq(value) Equals
neq(value) Not equals
contains(value) Contains substring
not_contains(value) Does not contain substring
is_empty() Field is empty
is_not_empty() Field is not empty
from leadsdb import city, name, email

city().eq("Berlin")
name().contains("Tech")
email().is_not_empty()

Number Fields

Available for: rating(), review_count()

Method Description
eq(value) Equals
neq(value) Not equals
gt(value) Greater than
gte(value) Greater than or equal
lt(value) Less than
lte(value) Less than or equal
from leadsdb import rating, review_count

rating().gte(4.0)
review_count().gt(100)

Array Fields

Available for: tags()

Method Description
contains(value) Array contains value
not_contains(value) Array does not contain value
is_empty() Array is empty
is_not_empty() Array is not empty
from leadsdb import tags

tags().contains("enterprise")
tags().is_not_empty()

Location

Method Description
within_radius(lat, lon, km) Within radius in kilometers
is_set() Coordinates are set
is_not_set() Coordinates are not set
from leadsdb import location

# Find leads within 50km of Berlin
location().within_radius(52.52, 13.405, 50)

Custom Attributes

Use attr(name) for custom attribute filters:

from leadsdb import attr

attr("industry").eq("Software")
attr("employees").gte(100)

OR Logic

from leadsdb import or_, rating

# City is Berlin OR Paris
result = client.list(
    rating().gte(4.0),           # AND
    or_().city().eq("Berlin"),   # OR
    or_().city().eq("Paris"),    # OR
)

Sorting

from leadsdb import SortField, SortOrder, attr_sort_field

# Sort by field
result = client.list(sort_by=SortField.NAME, sort_order=SortOrder.ASC)
result = client.list(sort_by=SortField.RATING, sort_order=SortOrder.DESC)

# Sort by custom attribute
result = client.list(sort_by=attr_sort_field("employees"), sort_order=SortOrder.DESC)

Available sort fields:

  • SortField.NAME, SortField.CITY, SortField.COUNTRY, SortField.STATE
  • SortField.CATEGORY, SortField.SOURCE, SortField.EMAIL, SortField.PHONE, SortField.WEBSITE
  • SortField.RATING, SortField.REVIEW_COUNT
  • SortField.CREATED_AT, SortField.UPDATED_AT

Bulk Operations

Bulk Create (up to 100 leads)

result = client.bulk_create([
    Lead(name="Lead 1", source="import", city="Athens"),
    Lead(name="Lead 2", source="import", city="London"),
    Lead(name="Lead 3", source="import", city="Paris"),
])

print(f"Created: {result.success}, Failed: {result.failed}")
for created in result.created:
    print(f"ID: {created.id} (index {created.index})")

Notes

# Create a note
note = client.create_note("lead-id", "Initial contact made")

# List notes
notes = client.list_notes("lead-id")

# Update a note
note = client.update_note("note-id", "Updated content")

# Delete a note
client.delete_note("note-id")

Export

from leadsdb import ExportFormat

# Export as CSV
data = client.export(ExportFormat.CSV)
with open("leads.csv", "wb") as f:
    f.write(data)

# Export as JSON
data = client.export(ExportFormat.JSON)

Error Handling

from leadsdb import NotFoundError, APIError

try:
    lead = client.get("non-existent-id")
except NotFoundError:
    print("Lead not found")
except APIError as e:
    print(f"Status: {e.status_code}, Message: {e.message}")

Exception types:

  • NotFoundError - Resource not found (404)
  • UnauthorizedError - Invalid API key (401)
  • ForbiddenError - Access denied (403)
  • RateLimitedError - Too many requests (429)
  • BadRequestError - Invalid request (400)
  • ValidationError - Client-side validation error

Using ListOptions

For more complex queries, you can use ListOptions:

from leadsdb import ListOptions, city, rating, SortField, SortOrder

opts = (
    ListOptions()
    .with_limit(50)
    .with_sort(SortField.RATING, SortOrder.DESC)
    .with_filter(city().eq("Berlin"))
    .with_filter(rating().gte(4.0))
)

result = client.list(options=opts)

License

MIT

Metadata

Release files for leadsdb 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for leadsdb 0.9.0
File Size Uploaded
leadsdb-0.9.0.tar.gz 15.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for leadsdb 0.9.0
File Interpreter ABI Platform
leadsdb-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 33.9 kB

Release files / leadsdb-0.9.0.tar.gz

Download URL leadsdb-0.9.0.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
95c10209feae5d670df54f24650b43bce9f0ff11e2a2ac82d52909bcd9d9492d
BLAKE2b-256 checksum
How to use checksums
23f55f97d7c35f61cb6bd721c5eea2b57dbb964c3b796a92b6bb41de99a10b91
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 26, 2025.

Transparency log

Release files / leadsdb-0.9.0-py3-none-any.whl

Download URL leadsdb-0.9.0-py3-none-any.whl
Size 18.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
379e15b2109efb17d93a1de0660f4f8e522563f4f3c6b9f6efa21d84d1be90d0
BLAKE2b-256 checksum
How to use checksums
4d12a2e8248182bd601909785b54f6217e9fe13d75aabf9183ae7ef1a757a2fa
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 26, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page