Metadata-Version: 2.4
Name: kynth
Version: 0.5.0
Summary: Official Python SDK for Kynth Core — the AI back-end for your product.
Project-URL: Homepage, https://api.kynth.studio
Project-URL: Documentation, https://api.kynth.studio/docs
Project-URL: Source, https://github.com/kyisaiah47/kynth
Author: Kynth Studios
License: MIT
Keywords: ai,api,chargeback,contract,document-parsing,kynth,llm,ocr,pii
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# kynth

Official Python SDK for **[Kynth Core](https://api.kynth.studio)** — the AI back-end for your product. Parse documents, extract fields, redact PII, analyze contracts, fight chargebacks, and enrich companies.

```bash
pip install kynth
```

## Quickstart

```python
from kynth import Kynth

client = Kynth(api_key="ksk_live_...")

doc = client.parse(file_url="https://.../invoice.pdf")
print(doc["totalAmount"])              # 4820.5
print(doc["usage"]["balanceRemaining"])  # 490
```

Get a key (and 500 free credits) at **[api.kynth.studio](https://api.kynth.studio)**. Zero dependencies — stdlib only, Python 3.8+.

## Methods

Every method returns the endpoint result as a dict, including a `usage` envelope. A non-2xx response raises a typed `KynthError` (and never burns credits).

```python
client.parse(file_url=...)                                  # documents → JSON
client.extract(text=..., fields=["order", "total"])         # pull named fields
client.classify(text=..., labels=["billing", "tech"])       # label text
client.summarize(text=..., length="standard")               # summary + actions
client.redact(text=...)                                      # strip PII/PHI
client.sentiment(text=..., aspects=["product"])             # sentiment + aspects
client.contract(file_url=...)                               # contract → terms + risks
client.chargeback(reason=..., transaction={"amount": 129})  # representment packet
client.enrich(email="sam@stripe.com")                       # company profile
client.account()                                            # balance
```

## Async & webhooks

A hundred-page contract doesn't fit in a request/response cycle. The document endpoints — `parse`, `invoice`, `receipt`, `statement`, `resume`, `tables`, `split`, `compare`, `contract` — take `async_=True` and hand you a job instead of a result. (`async` is a Python keyword, hence the trailing underscore; the wire field is `async`.)

```python
job = client.parse(file_url="https://.../contract.pdf", async_=True)
done = client.wait_for_job(job["jobId"])

if done["status"] == "succeeded":
    print(done["result"]["totalAmount"])
else:
    print(done["error"])          # failed jobs are never charged
```

Use `client.get_job(job_id)` for a single poll if you'd rather drive the loop yourself.

Every job reaches a terminal state. If the instance running yours dies mid-flight, it is marked `failed` with an explanation rather than left `running` forever — and you aren't billed for it. Nothing is silently retried; resubmit and you stay in control of the spend.

### Webhooks

Pass a `callback_url` (public https) and the finished job is POSTed to it, signed with your account's webhook secret from the [API keys page](https://api.kynth.studio/dashboard/keys):

```python
client.parse(file_url=..., async_=True, callback_url="https://you.example/hooks/kynth")
```

```python
import hmac, hashlib

# X-Kynth-Signature: sha256=<hex HMAC-SHA256 of the RAW body>
def verify(raw_body: bytes, header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(header.removeprefix("sha256="), expected)
```

Delivery is best-effort and never retried — **polling is the source of truth**.

## Error handling

```python
from kynth import Kynth, KynthError

client = Kynth(api_key="ksk_live_...")
try:
    client.parse(file_url="https://.../invoice.pdf")
except KynthError as err:
    # err.code: "insufficient_credits" | "rate_limited" | "unauthorized" | ...
    print(err.code, err.status, err.message)
```

MIT © Kynth Studios
