peerberry-sdk is a Python SDK for the Peerberry investor API.
It helps you build scripts and applications for Peerberry account data, loan discovery and purchases, investment tracking, and transaction exports.
Peerberry is a lending-focused investment platform where investors monitor portfolio performance, browse available loans, and manage investment activity.
This SDK gives Python developers programmatic access to those investor workflows via an API client.
The package exposes a single high-level client (peerberry_sdk.PeerberryClient) with typed model outputs, configurable retries, token lifecycle behavior, and structured exceptions suitable for production integrations.
Looking for a Peerberry Python SDK, Peerberry API wrapper, or Peerberry investor API client? This project is designed for that use case.
- Feature Overview
- Requirements
- Installation
- Quick Start
- Documentation
- Common Workflows
- Authentication Modes
- Configuration
- Header Profile Support
- Peerberry API Surface Covered
- Return Types
- Error Handling
- Lifecycle
- Contributing
- Acknowledgements
- Disclaimer
- Authenticated client for Peerberry profile, loans, investments, and transactions
- Typed dataclass models for most read operations
- Token lifecycle handling (login, refresh, optional proactive refresh)
- Configurable retry policy for HTTP and network failures
- Optional observability hooks and structured event emission
- Context-manager and explicit-close lifecycle support
- Python
>=3.8
pip install peerberry-sdkpip install "peerberry-sdk[otp]"[otp] installs pyotp, required only when you use tfa_secret.
pip install -e ".[otp,docs]"from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
profile = api.get_profile()
overview = api.get_overview()
loans = api.get_loans(quantity=10)
print("public_id:", profile.public_id)
print("available money:", overview.data.get("availableMoney"))
print("loans:", len(loans))- Installation Guide
- Quickstart Guide
- Authentication Guide
- Configuration Guide
- Error Handling Guide
- Models Guide
- Client API Reference (Generated)
- Module API Reference (Generated)
Repository docs are in docs/:
docs/getting-started/for onboardingdocs/guides/for deep task-oriented guidesdocs/api/client.mdfor full generated API contract docsdocs/api/reference.mdfor generated module reference
docs/api/reference.md is generated by docs/gen_api.py during docs build.
Documentation configuration lives in zensical.toml.
Build docs locally:
zensical buildUse tests/manual_display_actions.py for a manual account verification pass that only performs display/read operations.
- No investment purchase action is executed
- Intended for local/manual runs, not CI
- Named without
test_so it is not auto-collected bypytest - Reads dotenv from
tests/.envonly
Setup and run:
cp tests/.env.example tests/.env
python3 tests/manual_display_actions.pyExpected credentials in tests/.env:
PEERBERRY_USERNAMEPEERBERRY_PASSWORDPEERBERRY_TFA_SECRET(optional, base32 TOTP secret)
from datetime import date, timedelta
from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
investments = api.get_investments(quantity=50, current=True)
end_date = date.today()
start_date = end_date - timedelta(days=30)
transactions = api.get_transactions(
quantity=100,
start_date=start_date,
end_date=end_date,
transaction_types=["deposit", "interest_payment", "principal_repayment"],
)
print(investments.total)
print(len(transactions))from decimal import Decimal
from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
order = api.purchase_loan(loan_id=123456, amount=Decimal("10.00"))
print(order.order_id)from datetime import date, timedelta
from peerberry_sdk import PeerberryClient
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
inv_bytes = api.get_mass_investments(current=True)
end = date.today()
start = end - timedelta(days=365)
tx_bytes = api.get_mass_transactions(start_date=start, end_date=end)
with open("investments.xlsx", "wb") as f:
f.write(inv_bytes)
with open("transactions.xlsx", "wb") as f:
f.write(tx_bytes)api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD")api = PeerberryClient(
email="YOUR_EMAIL",
password="YOUR_PASSWORD",
tfa_secret="BASE32_TOTP_SECRET",
)api = PeerberryClient(
access_token="ACCESS_TOKEN",
refresh_token="REFRESH_TOKEN",
)api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD", auto_login=False)
api.login()The client is configured through SDKConfig:
TransportConfig: timeout, retries, header profilesAuthConfig: refresh strategy, token-store integrationObservabilityConfig: events/hook/logger/redactionLifecycleConfig: close/logout behavior
import logging
from peerberry_sdk import (
PeerberryClient,
AuthConfig,
InMemoryTokenStore,
LifecycleConfig,
ObservabilityConfig,
RetryConfig,
SDKConfig,
TransportConfig,
)
config = SDKConfig(
transport=TransportConfig(
timeout=20.0,
retry=RetryConfig(
max_retries=3,
backoff_factor=0.5,
max_backoff=8.0,
retry_status_codes=(429, 500, 502, 503, 504),
retry_on_network_errors=True,
),
),
auth=AuthConfig(
auto_refresh_on_auth_error=True,
max_refresh_attempts=1,
proactive_refresh=True,
proactive_refresh_skew_seconds=60,
token_store=InMemoryTokenStore(),
load_tokens_on_init=True,
),
observability=ObservabilityConfig(
event_hook=None,
logger=logging.getLogger("peerberry-sdk"),
verbose_events=False,
redactor=None,
),
lifecycle=LifecycleConfig(
logout_on_close=False,
swallow_logout_errors=True,
),
)
api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD", config=config)The transport layer allows custom static headers via:
request_opts={"header_profile": {...}}request_opts={"header_profile_path": "/path/to/profile.json"}peerberry_sdk_HEADER_PROFILE=/path/to/profile.json
Accepted JSON formats:
{ "x-app-system": "Linux x86_64", "x-app-user-agent": "Chrome 145.0.0.0" }or:
{ "headers": { "x-app-system": "Linux x86_64" } }get_profile()get_overview()get_loyalty_tier()get_profit_overview()get_investment_status()get_investment_originators_overview()
get_loans()get_loans_page()get_loan_details()get_agreement()purchase_loan()
get_investments()get_mass_investments()
get_account_summary()get_transactions()get_mass_transactions()
login()token()logout()close()
get_countries()get_originators()
Core methods return typed models:
Profile,Overview,LoyaltyTier,ProfitPointLoan,LoanPage,LoanDetailsInvestment,InvestmentPageTransaction,AccountSummary,PurchaseOrder
Export-oriented methods return bytes:
get_mass_investments()get_mass_transactions()get_agreement()
All SDK exceptions inherit from PeerberryException.
Common raised types:
AuthenticationError,InvalidCredentials,TokenRefreshErrorRateLimitError,ValidationError,InsufficientFunds,ServerErrorNetworkError- local validation errors such as
InvalidPeriodicity,InvalidSort,InvalidType
Exception instances can include:
status_code,error_code,errors,payloadurl,method,retry_after,is_retryablerequest_id,original_exception
from peerberry_sdk import PeerberryClient, PeerberryException, RateLimitError, TokenRefreshError, ValidationError
try:
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
api.get_loans(quantity=10)
except RateLimitError as exc:
print("retry_after:", exc.retry_after)
except ValidationError as exc:
print("validation:", exc)
except TokenRefreshError:
print("re-authentication required")
except PeerberryException as exc:
print("sdk error:", exc, "request_id:", exc.request_id)Preferred pattern:
with PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD") as api:
...Explicit pattern:
api = PeerberryClient(email="YOUR_EMAIL", password="YOUR_PASSWORD")
try:
...
finally:
api.close(logout=True)Issues and pull requests are welcome. For documentation updates, edit files under docs/ and validate locally with:
zensical build- This SDK builds on ideas from the archived API client project
thicccat688/peerberrypy. - Thanks to
thicccat688for the original groundwork.
- This SDK is unofficial and not maintained by Peerberry
- Peerberry API behavior can change without prior notice