Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.111.0"
".": "0.112.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 171
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-9791980619fc7ce8afb01f77dfe3c660a540975327378287cb666136ae4b0a99.yml
openapi_spec_hash: 0752074b2a7b0534329a1e3176c94a62
config_hash: aab05d0cf41f1f6b9f4d5677273c1600
configured_endpoints: 175
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-abe6a4f82f696099fa8ecb1cc44f08979e17d56578ae7ea68b0e9182e21df508.yml
openapi_spec_hash: d2ce51592a9a234c6f34a1168a31f91f
config_hash: f4b1d2f464e80527f970de61cba0c52f
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,47 @@
# Changelog

## 0.112.0 (2025-12-10)

Full Changelog: [v0.111.0...v0.112.0](https://github.com/lithic-com/lithic-python/compare/v0.111.0...v0.112.0)

### Features

* **api:** add bulk card creation APIs ([8bb0722](https://github.com/lithic-com/lithic-python/commit/8bb072220516545e9adbd32ad3aef1f51c029a8b))
* **api:** Add event_streams to auth rules APIs ([ad154eb](https://github.com/lithic-com/lithic-python/commit/ad154eb4737943666314f8a53d63e3bf4d48514e))
* **api:** add Google WPP to SDKs ([75159c4](https://github.com/lithic-com/lithic-python/commit/75159c4e762e68281b00fec859e69052d3a45d3b))
* **api:** add IS_AFTER / IS_BEFORE operators to Auth Rule APIs ([75159c4](https://github.com/lithic-com/lithic-python/commit/75159c4e762e68281b00fec859e69052d3a45d3b))
* **api:** Add new fee types ([ad154eb](https://github.com/lithic-com/lithic-python/commit/ad154eb4737943666314f8a53d63e3bf4d48514e))
* **api:** Add optional ach_hold_period ([ad154eb](https://github.com/lithic-com/lithic-python/commit/ad154eb4737943666314f8a53d63e3bf4d48514e))
* **api:** add WALLET_RECOMMENDATION_REASONS attribute for tokenization rules ([78148ad](https://github.com/lithic-com/lithic-python/commit/78148adea18a42644b9778613c3f459f4003aeec))
* **api:** add webhook schemas to SDKs - add parse and parse_unsafe ([d977e3f](https://github.com/lithic-com/lithic-python/commit/d977e3fc8beb01522aadb98d12df79e823cf128b))
* **api:** provide a unified model for AuthRule ([78148ad](https://github.com/lithic-com/lithic-python/commit/78148adea18a42644b9778613c3f459f4003aeec))
* **api:** support event_streams in auth_rules list endpoint ([befa333](https://github.com/lithic-com/lithic-python/commit/befa3335fabdc8099e8cf7dee8b32ae269c9c890))


### Bug Fixes

* **api:** extract several common types to reduce duplication ([8bb0722](https://github.com/lithic-com/lithic-python/commit/8bb072220516545e9adbd32ad3aef1f51c029a8b))
* **api:** fix examples in spec that were not fully valid ([78148ad](https://github.com/lithic-com/lithic-python/commit/78148adea18a42644b9778613c3f459f4003aeec))
* **api:** fix webhook parsing logic ([fc50832](https://github.com/lithic-com/lithic-python/commit/fc508320a25f3716b2f55880169df2c9c8faa056))
* **api:** make certain payoff fields nullable ([78148ad](https://github.com/lithic-com/lithic-python/commit/78148adea18a42644b9778613c3f459f4003aeec))
* ensure streams are always closed ([7a9e41f](https://github.com/lithic-com/lithic-python/commit/7a9e41ff7a639075315b721842d95c13b624e421))
* **types:** allow pyright to infer TypedDict types within SequenceNotStr ([d290cbb](https://github.com/lithic-com/lithic-python/commit/d290cbb1df6ed2ad2280dc150c106e6b2b3ca441))


### Chores

* add missing docstrings ([d297283](https://github.com/lithic-com/lithic-python/commit/d2972836067fdb76678128af20212c0b9bb4e8a0))
* add Python 3.14 classifier and testing ([95a6172](https://github.com/lithic-com/lithic-python/commit/95a6172000f72b77904fcd0fb21c6ca83319b5ed))
* **deps:** mypy 1.18.1 has a regression, pin to 1.17 ([6b9f3ab](https://github.com/lithic-com/lithic-python/commit/6b9f3abd0737a2db85284a76a9281a340c89b630))
* **docs:** use environment variables for authentication in code snippets ([29ae3a9](https://github.com/lithic-com/lithic-python/commit/29ae3a9b42a67775cb5225887c6bb6a37a327cf4))
* replace custom webhook signature verification with standardwebhooks ([d977e3f](https://github.com/lithic-com/lithic-python/commit/d977e3fc8beb01522aadb98d12df79e823cf128b))
* update lockfile ([a7a6330](https://github.com/lithic-com/lithic-python/commit/a7a63309b13085625edd790131f3ad588a3f472f))


### Documentation

* **api:** clarify error 422 for 3DS challenge response ([75159c4](https://github.com/lithic-com/lithic-python/commit/75159c4e762e68281b00fec859e69052d3a45d3b))

## 0.111.0 (2025-11-20)

Full Changelog: [v0.110.1...v0.111.0](https://github.com/lithic-com/lithic-python/compare/v0.110.1...v0.111.0)
Expand Down
76 changes: 60 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,15 @@ pip install lithic[aiohttp]
Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:

```python
import os
import asyncio
from lithic import DefaultAioHttpClient
from lithic import AsyncLithic


async def main() -> None:
async with AsyncLithic(
api_key="My Lithic API Key",
api_key=os.environ.get("LITHIC_API_KEY"), # This is the default and can be omitted
http_client=DefaultAioHttpClient(),
) as client:
card = await client.cards.create(
Expand Down Expand Up @@ -176,27 +177,70 @@ for card in first_page.data:
# Remove `await` for non-async usage.
```

## Webhook Verification
## Nested params

Nested parameters are dictionaries. The SDK uses TypedDict for type validation, but you can pass regular dictionaries as shown below:

```python
from lithic import Lithic

client = Lithic()

card = client.cards.create(
type="PHYSICAL",
shipping_address={
"address1": "123",
"city": "NEW YORK",
"country": "USA",
"first_name": "Johnny",
"last_name": "Appleseed",
"postal_code": "10001",
"state": "NY",
},
)
```

## Webhooks

Lithic uses webhooks to notify your application when events happen. The library provides signature verification via the optional `standardwebhooks` package.

We provide helper methods for verifying that a webhook request came from Lithic, and not a malicious third party.
### Parsing and verifying webhooks

You can use `lithic.webhooks.verify_signature(body: string, headers, secret?) -> None` or `lithic.webhooks.unwrap(body: string, headers, secret?) -> Payload`,
both of which will raise an error if the signature is invalid.
```py
from lithic.types import CardCreatedWebhookEvent

# Verifies signature and returns typed event
event = client.webhooks.parse(
request.body, # raw request body as string
headers=request.headers,
secret=os.environ["LITHIC_WEBHOOK_SECRET"] # optional, reads from env by default
)

Note that the "body" parameter must be the raw JSON string sent from the server (do not parse it first).
The `.unwrap()` method can parse this JSON for you into a `Payload` object.
# Use isinstance to narrow the type
if isinstance(event, CardCreatedWebhookEvent):
print(f"Card created: {event.card_token}")
```

For example, in [FastAPI](https://fastapi.tiangolo.com/):
### Parsing without verification

```py
@app.post('/my-webhook-handler')
async def handler(request: Request):
body = await request.body()
secret = os.environ['LITHIC_WEBHOOK_SECRET'] # env var used by default; explicit here.
payload = client.webhooks.unwrap(body, request.headers, secret)
print(payload)

return {'ok': True}
# Parse only - skips signature verification (not recommended for production)
event = client.webhooks.parse_unsafe(request.body)
```

### Verifying signatures only

```py
# Verify signature without parsing (raises exception if invalid)
client.webhooks.verify_signature(request.body, headers=request.headers, secret=secret)
```

### Installing standardwebhooks (optional)

To use signature verification, install the webhooks extra:

```sh
pip install lithic[webhooks]
```

## Handling errors
Expand Down
Loading