Skip to main content

distyra

Python client for the Distyra Transaction Enrichment API: transaction enrichment and SME cash-flow underwriting for EU lenders.

pip install distyra

Base URL: https://api.distyra.com (the SDK default). The API and CDN stay on .com; only the Distyra website and customer portal use .eu.

Quick start

import os
from distyra import Distyra

client = Distyra(api_key=os.environ["DISTYRA_API_KEY"])

result = client.enrich(
    descriptor="ALBERT HEIJN 1234 AMSTERDAM NL",
    amount=-12.34,
    currency="EUR",
    mcc="5411",
)
# merchant is None for non-merchant transactions (bank fees, transfers), so guard it.
print(result.merchant.name if result.merchant else "(no merchant)")  # "Albert Heijn"
print(result.category.primary)     # "Retail & E-commerce"
print(result.category.source)      # "catalog" (curated) or "llm" (model-proposed)

Batch enrichment

batch = client.enrich_batch([
    {"descriptor": "ALBERT HEIJN 1234 AMSTERDAM NL", "amount": -12.34, "currency": "EUR"},
    {"descriptor": "NS GROEP B.V.", "amount": -4.50, "currency": "EUR"},
    {"descriptor": "NETFLIX.COM", "amount": -13.99, "currency": "EUR"},
])
for item in batch.items:
    print(item)

Up to 100 items per call; a failed item occupies its slot with an error envelope, the batch itself never fails.

Handling unknown merchants (eventual consistency)

The first time a brand-new merchant is enriched, the result may be unresolved (result.resolution.status other than resolved). The system then discovers and confirms that merchant in the background, so the same descriptor resolves shortly after, for every caller, with no model call.

Read result.resolution.retry_after:

  • A number (seconds) means a confirmed answer is likely coming. Retry the same descriptor once after that delay, or just let your next natural re-sync pick it up.
  • None means the result is definitive; no retry will help.
result = client.enrich(descriptor="TIMECHIMP UREN UTRECHT NL", country_hint="NL")
if result.resolution.status != "resolved" and result.resolution.retry_after is not None:
    # retry once after result.resolution.retry_after seconds, or wait for your next sync
    ...

resolution.retryable is a different signal: True only for a transient backend error (timed_out / transient_error), which you retry within seconds. Full guide: https://api.distyra.com/docs.

Underwriting

Statement files in, one consolidated analysis out. Multiple files for the same applicant (the "last 6 months as 6 monthly PDFs" case) consolidate into one analysis over the merged window:

analysis = client.analyze_statement(
    ["jan.pdf", "feb.pdf", "mar.pdf"],
    applicant_id="loan-2026-0142",
    input_mode="statement_pdf",     # one format per analysis
    enrich=True,                    # optional: enrich every transaction
)
print(analysis.id, analysis.features)

JSON mode, when transactions are already on hand:

analysis = client.analyze(
    applicant_id="loan-2026-0142",
    input_mode="raw",
    accounts=[{
        "account_id": "main",
        "currency": "EUR",
        "opening_balance": 1500.0,
        "transactions": [
            {"date": "2026-05-01", "amount": 2500.0, "descriptor_raw": "INVOICE 1001 ACME BV"},
            {"date": "2026-05-15", "amount": -1200.0, "descriptor_raw": "RENT MAY OFFICE"},
        ],
    }],
)

Fetch a stored analysis later with client.get_analysis(analysis_id).

Note: enrichment is self-serve; underwriting endpoints are enabled per organization. Contact sales for access.

Errors

Every non-2xx raises DistyraError with the parsed envelope:

from distyra import Distyra, DistyraError

try:
    client.enrich(descriptor="...")
except DistyraError as e:
    print(e.status_code, e.error, e.detail)

Beyond the wrapper

The full generated client (every endpoint, typed models) ships in the same distribution as distyra_api_client. The wrapper's .raw attribute is a ready-authenticated instance:

from distyra_api_client.api.catalog import get_categories

categories = get_categories.sync(client=client.raw)

Development

This package lives in the Distyra monorepo at packages/saas-sdk-python/. The distyra_api_client package is generated from the committed OpenAPI snapshot — do not edit it by hand:

npm run snapshot -w @brightfield/saas-api   # refresh openapi.json from source
bash scripts/generate-python-sdk.sh         # regenerate distyra_api_client
bash scripts/test-python-sdk.sh             # build wheel + smoke

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

distyra-0.6.0.tar.gz (170.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

distyra-0.6.0-py3-none-any.whl (642.8 kB view details)

Uploaded Python 3

File details

Details for the file distyra-0.6.0.tar.gz.

File metadata

  • Download URL: distyra-0.6.0.tar.gz
  • Upload date:
  • Size: 170.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for distyra-0.6.0.tar.gz
Algorithm Hash digest
SHA256 56461ed708ae2b4494241c6781acea6df6e5efb3fd700d2c098371d54f74a242
MD5 73ceb1e1cb23afb377b4bcdcae6583c3
BLAKE2b-256 31a91445c12dcce975b89aa2336b7b30fd627975c8c0aeeabd91b08ac18514ce

See more details on using hashes here.

File details

Details for the file distyra-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: distyra-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 642.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for distyra-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 91dbc95b57a954690d9deb3264b3bf9f8b2d9c5df9a78ab5100a88a8e1ef5962
MD5 97ab0c89bbe587f97efca25163483aa0
BLAKE2b-256 ef72325d881140501a4266deb5def98877347808e61967a736051776f59dc78e

See more details on using hashes here.

Release history Release notifications | RSS feed

1.4.0

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.1

2 files

This release

0.6.0 This release

2 files

0.5.0

2 files

0.4.0

2 files

0.1.0

2 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