Easy Labs
SDKsPythonResources

Treasury

Treasury — methods, parameters, and examples for easy-sdk (pip).

Treasury is the platform's money-movement layer for the operator's funds — bank-linking, recipients, transfers, withdrawals, payout links, recurring payouts, and approval/security rules. The Python SDK exposes the full surface as flat methods on client.treasury.

Namespace: client.treasury. The method names are deliberately verbose (list_recipient_payment_methods, create_security_rule) so the resource works without nested classes — see the client.treasury source for the canonical list.

Bank accounts

# List linked bank accounts
accounts = client.treasury.list_bank_accounts(limit=50, offset=0)

# Plaid Link token for the dashboard / app
link_token = client.treasury.get_bank_link_token()

# Link a bank account after Plaid Link succeeds
client.treasury.link_bank_account(
    plaid_public_token="public-sandbox-…",
    plaid_account_id="acc_…",
    idempotency_key="bank-link-2026-05-01",
)

# Deactivate
client.treasury.delete_bank_account("ba_123")

Categories

categories = client.treasury.list_categories(limit=50)
custom = client.treasury.create_category(
    name="Marketing",
    color="#0a84ff",
    idempotency_key="cat-marketing",
)
client.treasury.delete_category(custom.id)
usage = client.treasury.get_category_usage(custom.id)

Dashboard & deposits

summary = client.treasury.get_dashboard_summary()
wire    = client.treasury.get_wire_instructions()

# Pull funds from a linked bank (ACH)
client.treasury.bank_pull(
    bank_account_id="ba_123",
    amount=100000,
    idempotency_key="pull-2026-05-01",
)

Recipients

recipients = client.treasury.list_recipients(limit=50)
recipient = client.treasury.retrieve_recipient("rec_123")

new = client.treasury.create_recipient(
    name="Vendor LLC",
    email="vendor@example.com",
    payment_methods=[{
        "type": "BANK_ACCOUNT",
        "routing_number": "...",
        "account_number": "...",
        "account_type": "checking",
    }],
    idempotency_key="recipient-vendor-llc",
)

client.treasury.update_recipient(new.id, notes="Net-30")
client.treasury.delete_recipient(new.id)

# Payment methods (sub-resource)
client.treasury.add_recipient_payment_method(
    new.id, type="BANK_ACCOUNT", routing_number="...", account_number="...",
)

# Self-service flows
client.treasury.invite_recipient(new.id)
client.treasury.request_recipient_w9(new.id)

# Auto-pay schedule
client.treasury.create_recipient_auto_pay(
    new.id, amount=100000, schedule="monthly_first",
)

# Tax info
tax = client.treasury.get_recipient_tax_info(new.id)
client.treasury.set_recipient_tax_info(new.id, tin="...", classification="LLC")

# Invitations
invites = client.treasury.list_recipient_invitations(limit=50)

# Bulk import (CSV)
with open("recipients.csv", "rb") as f:
    client.treasury.import_recipients(file=f, filename="recipients.csv")

# Tax compliance report
report = client.treasury.get_recipient_tax_report()

# Plaid for recipient self-service
token = client.treasury.get_recipient_plaid_link_token(recipient_id=new.id)
client.treasury.exchange_recipient_plaid_token(
    recipient_id=new.id,
    public_token="public-sandbox-…",
)

list_recipient_payment_methods(recipient_id) is exposed for forward compatibility but the API has no dedicated GET endpoint today — payment methods are returned inline on the recipient object.

Transactions

# Cursor-based pagination — pass next_cursor back as cursor=
page = client.treasury.list_transactions(limit=100)
while True:
    for tx in page.get("data", []):
        print(tx["id"], tx["amount"])
    if not page.get("next_cursor"):
        break
    page = client.treasury.list_transactions(limit=100, cursor=page["next_cursor"])

tx = client.treasury.retrieve_transaction("ttx_123")
client.treasury.update_transaction("ttx_123", category_id="cat_marketing")
breakdown = client.treasury.get_transaction_settlement("ttx_123")
csv = client.treasury.export_transactions(start="2026-05-01", end="2026-05-31")

Send / transfer / withdraw

All three are two-step (initiate, then optional 2FA confirm) and accept arbitrary fields via **kwargs. Each returns a raw dict.

# Send money to a recipient
op = client.treasury.send(
    recipient_id="rec_123",
    amount=100000,
    method="ach",
    idempotency_key="send-rec_123-2026-05-01",
)
client.treasury.confirm_send(send_id=op["id"], two_factor_code="123456")
client.treasury.cancel_send(send_id=op["id"])

# Transfer between accounts
client.treasury.transfer(
    from_account="ba_123", to_account="ba_456", amount=50000,
)
client.treasury.confirm_transfer(transfer_id="ttr_123", two_factor_code="123456")

# Withdraw to an external bank
client.treasury.withdraw(
    bank_account_id="ba_123", amount=200000,
    idempotency_key="withdraw-2026-05-01",
)
client.treasury.confirm_withdraw(withdraw_id="tw_123", two_factor_code="123456")
links = client.treasury.list_payout_links(limit=50)
link  = client.treasury.generate_payout_link(amount=50000, currency="USD")

# Public endpoint — no auth needed; suitable for the recipient page
detail = client.treasury.get_payout_link("plk_token")
client.treasury.submit_payout_link(
    "plk_token",
    routing_number="...", account_number="...", account_type="checking",
)

Recurring payments

recurring = client.treasury.list_recurring_payments(limit=50)
rp = client.treasury.retrieve_recurring_payment("trp_123")

new_rp = client.treasury.create_recurring_payment(
    recipient_id="rec_123",
    amount=100000,
    schedule="monthly_first",
    idempotency_key="recurring-vendor-monthly",
)

client.treasury.update_recurring_payment(new_rp.id, status="paused")
client.treasury.delete_recurring_payment(new_rp.id)

Auto-transfer rules

rules = client.treasury.list_auto_transfer_rules(limit=50)

rule = client.treasury.create_auto_transfer_rule(
    threshold=500000,
    target_account_id="ba_savings",
    idempotency_key="atr-overflow-to-savings",
)
client.treasury.update_auto_transfer_rule(rule.id, enabled=False)
client.treasury.delete_auto_transfer_rule(rule.id)

Security rules & approvals

rules = client.treasury.list_security_rules(limit=50)

rule = client.treasury.create_security_rule(
    type="approval_required",
    threshold=1000000,
    approvers=["user_admin"],
    idempotency_key="sec-large-tx-approval",
)
client.treasury.update_security_rule(rule.id, threshold=2000000)
client.treasury.delete_security_rule(rule.id)

# Approvals
req = client.treasury.create_approval_request(
    transaction_id="ttx_pending",
    reason="High-value transfer",
)
client.treasury.resolve_approval_request(
    req.id, decision="approve", notes="OK from CFO",
)

Object shapes

Treasury models live in easylabs.models.treasury:

TreasuryBankAccount, TreasuryCategory, TreasuryRecipient, TreasuryTransaction, TreasuryPayoutLink, TreasuryRecurringPayment, TreasuryAutoTransferRule, TreasurySecurityRule, TreasuryApprovalRequest.

Each is a pydantic model on EasyModel with extra="allow", so the typed fields shown in source surface common attributes (id, status, amount, created_at, ...) and the rest comes through dynamically. The full per-model schema lives in the Easy Labs API reference.

Examples

Walk all transactions for a CSV export

all_rows = []
cursor = None
while True:
    page = client.treasury.list_transactions(limit=200, cursor=cursor)
    all_rows.extend(page.get("data", []))
    cursor = page.get("next_cursor")
    if not cursor:
        break

Categorize uncategorized transactions

page = client.treasury.list_transactions(limit=100)
for tx in page.get("data", []):
    if not tx.get("category_id"):
        client.treasury.update_transaction(tx["id"], category_id="cat_uncategorized")

On this page