From 54766ec079921166182a3bf8cb01e575591379bf Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:35:31 +0000
Subject: [PATCH 1/6] chore: internal codegen changes
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index d199040a..ffe4aca9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 155
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-fe97f820471b725722897539252e7444af7490c5a444a2e9304f5e6eec5513f3.yml
openapi_spec_hash: 7e6a5737901cef39499bf749a17d9939
-config_hash: 3d06d32938417ca039b0caa91d2dc8b6
+config_hash: 64c1503c2a0589f02979f69237d98582
From 30d680f54263574ca236ad1095ab1775196beae1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:46:23 +0000
Subject: [PATCH 2/6] chore: internal codegen changes
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index ffe4aca9..931724a5 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 155
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-fe97f820471b725722897539252e7444af7490c5a444a2e9304f5e6eec5513f3.yml
openapi_spec_hash: 7e6a5737901cef39499bf749a17d9939
-config_hash: 64c1503c2a0589f02979f69237d98582
+config_hash: 4ad881d1e70144d965fd188c40350add
From b2f78a54322e3758fea084c1f2cc893c40d44b59 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 3 Apr 2025 15:54:09 +0000
Subject: [PATCH 3/6] chore(internal): remove trailing character (#727)
---
tests/test_client.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_client.py b/tests/test_client.py
index 6fa9f9b3..db2c23c4 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -1675,7 +1675,7 @@ def test_get_platform(self) -> None:
import threading
from lithic._utils import asyncify
- from lithic._base_client import get_platform
+ from lithic._base_client import get_platform
async def test_main() -> None:
result = await asyncify(get_platform)()
From 4789b7322178e77e925c66d95c911dd09e6f6e84 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Apr 2025 14:51:51 +0000
Subject: [PATCH 4/6] chore(internal): only run examples workflow in main repo
(#728)
---
.github/workflows/ci.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index bbbef9f9..c1eb2a61 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -54,6 +54,7 @@ jobs:
examples:
name: examples
runs-on: ubuntu-latest
+ if: github.repository == 'lithic-com/lithic-python'
steps:
- uses: actions/checkout@v4
From 8d5e6343610762cb6362c15d52f53635d440dfa4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Apr 2025 16:54:17 +0000
Subject: [PATCH 5/6] feat(api): new resend endpoint for Event Subscriptions
(#729)
- Add new endpoint for resending events to event subscriptions
- Refactor shipping method into reusable schema component (CardShippingMethod)
- Deprecate `BeneficialOwnerEntities` in favor of BeneficialOwnerIndividuals`
- Enhance card renewal documentation with details on PHYSICAL vs VIRTUAL card behavior
- Rename `FinancialAccount.status_change_reason` to `substatus`
---
.stats.yml | 8 +-
api.md | 6 +
src/lithic/resources/account_holders.py | 56 +++---
src/lithic/resources/cards/cards.py | 72 ++++----
src/lithic/resources/events/__init__.py | 14 ++
.../resources/events/event_subscriptions.py | 168 ++++++++++++++++++
src/lithic/resources/events/events.py | 32 ++++
.../financial_accounts/financial_accounts.py | 16 +-
src/lithic/types/account_holder.py | 5 +-
.../types/account_holder_create_params.py | 90 +++++-----
.../types/card_convert_physical_params.py | 5 +-
src/lithic/types/card_reissue_params.py | 5 +-
src/lithic/types/card_renew_params.py | 5 +-
src/lithic/types/financial_account.py | 4 +-
.../financial_account_update_status_params.py | 4 +-
.../types/financial_accounts/loan_tape.py | 4 +-
.../types/financial_accounts/statement.py | 4 +-
src/lithic/types/kyb_param.py | 86 ++++-----
.../events/test_event_subscriptions.py | 120 +++++++++++++
tests/api_resources/test_account_holders.py | 132 +++-----------
tests/api_resources/test_cards.py | 12 +-
.../api_resources/test_financial_accounts.py | 16 +-
22 files changed, 544 insertions(+), 320 deletions(-)
create mode 100644 src/lithic/resources/events/event_subscriptions.py
create mode 100644 tests/api_resources/events/test_event_subscriptions.py
diff --git a/.stats.yml b/.stats.yml
index 931724a5..1d9cb822 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 155
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-fe97f820471b725722897539252e7444af7490c5a444a2e9304f5e6eec5513f3.yml
-openapi_spec_hash: 7e6a5737901cef39499bf749a17d9939
-config_hash: 4ad881d1e70144d965fd188c40350add
+configured_endpoints: 156
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-179992b114ffada2cdd2d9d56a8a25e0683bec2297606d32d0f0006b9eb9f21d.yml
+openapi_spec_hash: a111418d378ea248892306c81b00f8c8
+config_hash: 6729d695e399d14fff4891b6b82ec86c
diff --git a/api.md b/api.md
index 786f11ad..a0bc4be9 100644
--- a/api.md
+++ b/api.md
@@ -315,6 +315,12 @@ Methods:
- client.events.subscriptions.rotate_secret(event_subscription_token) -> None
- client.events.subscriptions.send_simulated_example(event_subscription_token, \*\*params) -> None
+## EventSubscriptions
+
+Methods:
+
+- client.events.event_subscriptions.resend(event_subscription_token, \*, event_token) -> None
+
# FinancialAccounts
Types:
diff --git a/src/lithic/resources/account_holders.py b/src/lithic/resources/account_holders.py
index 54a99fc8..bee201ca 100644
--- a/src/lithic/resources/account_holders.py
+++ b/src/lithic/resources/account_holders.py
@@ -66,13 +66,14 @@ def with_streaming_response(self) -> AccountHoldersWithStreamingResponse:
def create(
self,
*,
- beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity],
beneficial_owner_individuals: Iterable[account_holder_create_params.KYBBeneficialOwnerIndividual],
business_entity: account_holder_create_params.KYBBusinessEntity,
control_person: account_holder_create_params.KYBControlPerson,
nature_of_business: str,
tos_timestamp: str,
workflow: Literal["KYB_BASIC", "KYB_BYO"],
+ beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity]
+ | NotGiven = NOT_GIVEN,
external_id: str | NotGiven = NOT_GIVEN,
kyb_passed_timestamp: str | NotGiven = NOT_GIVEN,
website_url: str | NotGiven = NOT_GIVEN,
@@ -93,21 +94,11 @@ def create(
accounts that are part of the program that the calling API key manages.
Args:
- beneficial_owner_entities: List of all entities with >25% ownership in the company. If no entity or
- individual owns >25% of the company, and the largest shareholder is an entity,
- please identify them in this field. See
- [FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background. If no business owner is an entity, pass in an
- empty list. However, either this parameter or `beneficial_owner_individuals`
- must be populated. on entities that should be included.
-
beneficial_owner_individuals: List of all direct and indirect individuals with >25% ownership in the company.
- If no entity or individual owns >25% of the company, and the largest shareholder
- is an individual, please identify them in this field. See
+ If no individual owns >25% of the company, please identify the largest
+ shareholder in this field. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background on individuals that should be included. If no
- individual is an entity, pass in an empty list. However, either this parameter
- or `beneficial_owner_entities` must be populated.
+ (Section I) for more background on individuals that should be included.
business_entity: Information for business for which the account is being opened and KYB is being
run.
@@ -130,6 +121,8 @@ def create(
workflow: Specifies the type of KYB workflow to run.
+ beneficial_owner_entities: Deprecated.
+
external_id: A user provided id that can be used to link an account holder with an external
system
@@ -267,7 +260,6 @@ def create(
@required_args(
[
- "beneficial_owner_entities",
"beneficial_owner_individuals",
"business_entity",
"control_person",
@@ -281,8 +273,6 @@ def create(
def create(
self,
*,
- beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity]
- | NotGiven = NOT_GIVEN,
beneficial_owner_individuals: Iterable[account_holder_create_params.KYBBeneficialOwnerIndividual]
| NotGiven = NOT_GIVEN,
business_entity: account_holder_create_params.KYBBusinessEntity | NotGiven = NOT_GIVEN,
@@ -290,6 +280,8 @@ def create(
nature_of_business: str | NotGiven = NOT_GIVEN,
tos_timestamp: str | NotGiven = NOT_GIVEN,
workflow: Literal["KYB_BASIC", "KYB_BYO"] | Literal["KYC_BASIC", "KYC_BYO"] | Literal["KYC_EXEMPT"],
+ beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity]
+ | NotGiven = NOT_GIVEN,
external_id: str | NotGiven = NOT_GIVEN,
kyb_passed_timestamp: str | NotGiven = NOT_GIVEN,
website_url: str | NotGiven = NOT_GIVEN,
@@ -315,13 +307,13 @@ def create(
"/v1/account_holders",
body=maybe_transform(
{
- "beneficial_owner_entities": beneficial_owner_entities,
"beneficial_owner_individuals": beneficial_owner_individuals,
"business_entity": business_entity,
"control_person": control_person,
"nature_of_business": nature_of_business,
"tos_timestamp": tos_timestamp,
"workflow": workflow,
+ "beneficial_owner_entities": beneficial_owner_entities,
"external_id": external_id,
"kyb_passed_timestamp": kyb_passed_timestamp,
"website_url": website_url,
@@ -1063,13 +1055,14 @@ def with_streaming_response(self) -> AsyncAccountHoldersWithStreamingResponse:
async def create(
self,
*,
- beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity],
beneficial_owner_individuals: Iterable[account_holder_create_params.KYBBeneficialOwnerIndividual],
business_entity: account_holder_create_params.KYBBusinessEntity,
control_person: account_holder_create_params.KYBControlPerson,
nature_of_business: str,
tos_timestamp: str,
workflow: Literal["KYB_BASIC", "KYB_BYO"],
+ beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity]
+ | NotGiven = NOT_GIVEN,
external_id: str | NotGiven = NOT_GIVEN,
kyb_passed_timestamp: str | NotGiven = NOT_GIVEN,
website_url: str | NotGiven = NOT_GIVEN,
@@ -1090,21 +1083,11 @@ async def create(
accounts that are part of the program that the calling API key manages.
Args:
- beneficial_owner_entities: List of all entities with >25% ownership in the company. If no entity or
- individual owns >25% of the company, and the largest shareholder is an entity,
- please identify them in this field. See
- [FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background. If no business owner is an entity, pass in an
- empty list. However, either this parameter or `beneficial_owner_individuals`
- must be populated. on entities that should be included.
-
beneficial_owner_individuals: List of all direct and indirect individuals with >25% ownership in the company.
- If no entity or individual owns >25% of the company, and the largest shareholder
- is an individual, please identify them in this field. See
+ If no individual owns >25% of the company, please identify the largest
+ shareholder in this field. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background on individuals that should be included. If no
- individual is an entity, pass in an empty list. However, either this parameter
- or `beneficial_owner_entities` must be populated.
+ (Section I) for more background on individuals that should be included.
business_entity: Information for business for which the account is being opened and KYB is being
run.
@@ -1127,6 +1110,8 @@ async def create(
workflow: Specifies the type of KYB workflow to run.
+ beneficial_owner_entities: Deprecated.
+
external_id: A user provided id that can be used to link an account holder with an external
system
@@ -1264,7 +1249,6 @@ async def create(
@required_args(
[
- "beneficial_owner_entities",
"beneficial_owner_individuals",
"business_entity",
"control_person",
@@ -1278,8 +1262,6 @@ async def create(
async def create(
self,
*,
- beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity]
- | NotGiven = NOT_GIVEN,
beneficial_owner_individuals: Iterable[account_holder_create_params.KYBBeneficialOwnerIndividual]
| NotGiven = NOT_GIVEN,
business_entity: account_holder_create_params.KYBBusinessEntity | NotGiven = NOT_GIVEN,
@@ -1287,6 +1269,8 @@ async def create(
nature_of_business: str | NotGiven = NOT_GIVEN,
tos_timestamp: str | NotGiven = NOT_GIVEN,
workflow: Literal["KYB_BASIC", "KYB_BYO"] | Literal["KYC_BASIC", "KYC_BYO"] | Literal["KYC_EXEMPT"],
+ beneficial_owner_entities: Iterable[account_holder_create_params.KYBBeneficialOwnerEntity]
+ | NotGiven = NOT_GIVEN,
external_id: str | NotGiven = NOT_GIVEN,
kyb_passed_timestamp: str | NotGiven = NOT_GIVEN,
website_url: str | NotGiven = NOT_GIVEN,
@@ -1312,13 +1296,13 @@ async def create(
"/v1/account_holders",
body=await async_maybe_transform(
{
- "beneficial_owner_entities": beneficial_owner_entities,
"beneficial_owner_individuals": beneficial_owner_individuals,
"business_entity": business_entity,
"control_person": control_person,
"nature_of_business": nature_of_business,
"tos_timestamp": tos_timestamp,
"workflow": workflow,
+ "beneficial_owner_entities": beneficial_owner_entities,
"external_id": external_id,
"kyb_passed_timestamp": kyb_passed_timestamp,
"website_url": website_url,
diff --git a/src/lithic/resources/cards/cards.py b/src/lithic/resources/cards/cards.py
index 71aeef8c..7a0f467b 100644
--- a/src/lithic/resources/cards/cards.py
+++ b/src/lithic/resources/cards/cards.py
@@ -497,7 +497,7 @@ def convert_physical(
shipping_address: ShippingAddress,
carrier: Carrier | NotGiven = NOT_GIVEN,
product_id: str | NotGiven = NOT_GIVEN,
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
| NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -528,8 +528,8 @@ def convert_physical(
manufactured with, and only applies to cards of type `PHYSICAL`. This must be
configured with Lithic before use.
- shipping_method: Shipping method for the card. Use of options besides `STANDARD` require
- additional permissions.
+ shipping_method: Shipping method for the card. Only applies to cards of type PHYSICAL. Use of
+ options besides `STANDARD` require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
@@ -837,7 +837,7 @@ def reissue(
carrier: Carrier | NotGiven = NOT_GIVEN,
product_id: str | NotGiven = NOT_GIVEN,
shipping_address: ShippingAddress | NotGiven = NOT_GIVEN,
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
| NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -863,8 +863,8 @@ def reissue(
shipping_address: If omitted, the previous shipping address will be used.
- shipping_method: Shipping method for the card. Use of options besides `STANDARD` require
- additional permissions.
+ shipping_method: Shipping method for the card. Only applies to cards of type PHYSICAL. Use of
+ options besides `STANDARD` require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
@@ -912,7 +912,7 @@ def renew(
exp_month: str | NotGiven = NOT_GIVEN,
exp_year: str | NotGiven = NOT_GIVEN,
product_id: str | NotGiven = NOT_GIVEN,
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
| NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -921,13 +921,17 @@ def renew(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Card:
- """
- Creates a new card with the same card token and PAN, but updated expiry and CVC2
- code. The original card will keep working for card-present transactions until
- the new card is activated. For card-not-present transactions, the original card
- details (expiry, CVC2) will also keep working until the new card is activated.
- Applies to card types `PHYSICAL` and `VIRTUAL`. A card can be replaced or
- renewed a total of 8 times.
+ """Applies to card types `PHYSICAL` and `VIRTUAL`.
+
+ For `PHYSICAL`, creates a new
+ card with the same card token and PAN, but updated expiry and CVC2 code. The
+ original card will keep working for card-present transactions until the new card
+ is activated. For card-not-present transactions, the original card details
+ (expiry, CVC2) will also keep working until the new card is activated. A
+ `PHYSICAL` card can be replaced or renewed a total of 8 times. For `VIRTUAL`,
+ the card will retain the same card token and PAN and receive an updated expiry
+ and CVC2 code. `product_id`, `shipping_method`, `shipping_address`, `carrier`
+ are only relevant for renewing `PHYSICAL` cards.
Args:
shipping_address: The shipping address this card will be sent to.
@@ -944,8 +948,8 @@ def renew(
manufactured with, and only applies to cards of type `PHYSICAL`. This must be
configured with Lithic before use.
- shipping_method: Shipping method for the card. Use of options besides `STANDARD` require
- additional permissions.
+ shipping_method: Shipping method for the card. Only applies to cards of type PHYSICAL. Use of
+ options besides `STANDARD` require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
@@ -1480,7 +1484,7 @@ async def convert_physical(
shipping_address: ShippingAddress,
carrier: Carrier | NotGiven = NOT_GIVEN,
product_id: str | NotGiven = NOT_GIVEN,
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
| NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1511,8 +1515,8 @@ async def convert_physical(
manufactured with, and only applies to cards of type `PHYSICAL`. This must be
configured with Lithic before use.
- shipping_method: Shipping method for the card. Use of options besides `STANDARD` require
- additional permissions.
+ shipping_method: Shipping method for the card. Only applies to cards of type PHYSICAL. Use of
+ options besides `STANDARD` require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
@@ -1820,7 +1824,7 @@ async def reissue(
carrier: Carrier | NotGiven = NOT_GIVEN,
product_id: str | NotGiven = NOT_GIVEN,
shipping_address: ShippingAddress | NotGiven = NOT_GIVEN,
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
| NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1846,8 +1850,8 @@ async def reissue(
shipping_address: If omitted, the previous shipping address will be used.
- shipping_method: Shipping method for the card. Use of options besides `STANDARD` require
- additional permissions.
+ shipping_method: Shipping method for the card. Only applies to cards of type PHYSICAL. Use of
+ options besides `STANDARD` require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
@@ -1895,7 +1899,7 @@ async def renew(
exp_month: str | NotGiven = NOT_GIVEN,
exp_year: str | NotGiven = NOT_GIVEN,
product_id: str | NotGiven = NOT_GIVEN,
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
| NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1904,13 +1908,17 @@ async def renew(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> Card:
- """
- Creates a new card with the same card token and PAN, but updated expiry and CVC2
- code. The original card will keep working for card-present transactions until
- the new card is activated. For card-not-present transactions, the original card
- details (expiry, CVC2) will also keep working until the new card is activated.
- Applies to card types `PHYSICAL` and `VIRTUAL`. A card can be replaced or
- renewed a total of 8 times.
+ """Applies to card types `PHYSICAL` and `VIRTUAL`.
+
+ For `PHYSICAL`, creates a new
+ card with the same card token and PAN, but updated expiry and CVC2 code. The
+ original card will keep working for card-present transactions until the new card
+ is activated. For card-not-present transactions, the original card details
+ (expiry, CVC2) will also keep working until the new card is activated. A
+ `PHYSICAL` card can be replaced or renewed a total of 8 times. For `VIRTUAL`,
+ the card will retain the same card token and PAN and receive an updated expiry
+ and CVC2 code. `product_id`, `shipping_method`, `shipping_address`, `carrier`
+ are only relevant for renewing `PHYSICAL` cards.
Args:
shipping_address: The shipping address this card will be sent to.
@@ -1927,8 +1935,8 @@ async def renew(
manufactured with, and only applies to cards of type `PHYSICAL`. This must be
configured with Lithic before use.
- shipping_method: Shipping method for the card. Use of options besides `STANDARD` require
- additional permissions.
+ shipping_method: Shipping method for the card. Only applies to cards of type PHYSICAL. Use of
+ options besides `STANDARD` require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
diff --git a/src/lithic/resources/events/__init__.py b/src/lithic/resources/events/__init__.py
index 022e67df..bb505c94 100644
--- a/src/lithic/resources/events/__init__.py
+++ b/src/lithic/resources/events/__init__.py
@@ -16,6 +16,14 @@
SubscriptionsWithStreamingResponse,
AsyncSubscriptionsWithStreamingResponse,
)
+from .event_subscriptions import (
+ EventSubscriptions,
+ AsyncEventSubscriptions,
+ EventSubscriptionsWithRawResponse,
+ AsyncEventSubscriptionsWithRawResponse,
+ EventSubscriptionsWithStreamingResponse,
+ AsyncEventSubscriptionsWithStreamingResponse,
+)
__all__ = [
"Subscriptions",
@@ -24,6 +32,12 @@
"AsyncSubscriptionsWithRawResponse",
"SubscriptionsWithStreamingResponse",
"AsyncSubscriptionsWithStreamingResponse",
+ "EventSubscriptions",
+ "AsyncEventSubscriptions",
+ "EventSubscriptionsWithRawResponse",
+ "AsyncEventSubscriptionsWithRawResponse",
+ "EventSubscriptionsWithStreamingResponse",
+ "AsyncEventSubscriptionsWithStreamingResponse",
"Events",
"AsyncEvents",
"EventsWithRawResponse",
diff --git a/src/lithic/resources/events/event_subscriptions.py b/src/lithic/resources/events/event_subscriptions.py
new file mode 100644
index 00000000..2644dd3f
--- /dev/null
+++ b/src/lithic/resources/events/event_subscriptions.py
@@ -0,0 +1,168 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ... import _legacy_response
+from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
+from ..._base_client import make_request_options
+
+__all__ = ["EventSubscriptions", "AsyncEventSubscriptions"]
+
+
+class EventSubscriptions(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> EventSubscriptionsWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/lithic-com/lithic-python#accessing-raw-response-data-eg-headers
+ """
+ return EventSubscriptionsWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> EventSubscriptionsWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/lithic-com/lithic-python#with_streaming_response
+ """
+ return EventSubscriptionsWithStreamingResponse(self)
+
+ def resend(
+ self,
+ event_subscription_token: str,
+ *,
+ event_token: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Resend an event to an event subscription.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not event_token:
+ raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}")
+ if not event_subscription_token:
+ raise ValueError(
+ f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}"
+ )
+ return self._post(
+ f"/v1/events/{event_token}/event_subscriptions/{event_subscription_token}/resend",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class AsyncEventSubscriptions(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncEventSubscriptionsWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/lithic-com/lithic-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncEventSubscriptionsWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncEventSubscriptionsWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/lithic-com/lithic-python#with_streaming_response
+ """
+ return AsyncEventSubscriptionsWithStreamingResponse(self)
+
+ async def resend(
+ self,
+ event_subscription_token: str,
+ *,
+ event_token: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Resend an event to an event subscription.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not event_token:
+ raise ValueError(f"Expected a non-empty value for `event_token` but received {event_token!r}")
+ if not event_subscription_token:
+ raise ValueError(
+ f"Expected a non-empty value for `event_subscription_token` but received {event_subscription_token!r}"
+ )
+ return await self._post(
+ f"/v1/events/{event_token}/event_subscriptions/{event_subscription_token}/resend",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class EventSubscriptionsWithRawResponse:
+ def __init__(self, event_subscriptions: EventSubscriptions) -> None:
+ self._event_subscriptions = event_subscriptions
+
+ self.resend = _legacy_response.to_raw_response_wrapper(
+ event_subscriptions.resend,
+ )
+
+
+class AsyncEventSubscriptionsWithRawResponse:
+ def __init__(self, event_subscriptions: AsyncEventSubscriptions) -> None:
+ self._event_subscriptions = event_subscriptions
+
+ self.resend = _legacy_response.async_to_raw_response_wrapper(
+ event_subscriptions.resend,
+ )
+
+
+class EventSubscriptionsWithStreamingResponse:
+ def __init__(self, event_subscriptions: EventSubscriptions) -> None:
+ self._event_subscriptions = event_subscriptions
+
+ self.resend = to_streamed_response_wrapper(
+ event_subscriptions.resend,
+ )
+
+
+class AsyncEventSubscriptionsWithStreamingResponse:
+ def __init__(self, event_subscriptions: AsyncEventSubscriptions) -> None:
+ self._event_subscriptions = event_subscriptions
+
+ self.resend = async_to_streamed_response_wrapper(
+ event_subscriptions.resend,
+ )
diff --git a/src/lithic/resources/events/events.py b/src/lithic/resources/events/events.py
index e999da3c..8907c3a3 100644
--- a/src/lithic/resources/events/events.py
+++ b/src/lithic/resources/events/events.py
@@ -26,6 +26,14 @@
AsyncSubscriptionsWithStreamingResponse,
)
from ..._base_client import AsyncPaginator, make_request_options
+from .event_subscriptions import (
+ EventSubscriptions,
+ AsyncEventSubscriptions,
+ EventSubscriptionsWithRawResponse,
+ AsyncEventSubscriptionsWithRawResponse,
+ EventSubscriptionsWithStreamingResponse,
+ AsyncEventSubscriptionsWithStreamingResponse,
+)
from ...types.message_attempt import MessageAttempt
__all__ = ["Events", "AsyncEvents"]
@@ -36,6 +44,10 @@ class Events(SyncAPIResource):
def subscriptions(self) -> Subscriptions:
return Subscriptions(self._client)
+ @cached_property
+ def event_subscriptions(self) -> EventSubscriptions:
+ return EventSubscriptions(self._client)
+
@cached_property
def with_raw_response(self) -> EventsWithRawResponse:
"""
@@ -296,6 +308,10 @@ class AsyncEvents(AsyncAPIResource):
def subscriptions(self) -> AsyncSubscriptions:
return AsyncSubscriptions(self._client)
+ @cached_property
+ def event_subscriptions(self) -> AsyncEventSubscriptions:
+ return AsyncEventSubscriptions(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncEventsWithRawResponse:
"""
@@ -569,6 +585,10 @@ def __init__(self, events: Events) -> None:
def subscriptions(self) -> SubscriptionsWithRawResponse:
return SubscriptionsWithRawResponse(self._events.subscriptions)
+ @cached_property
+ def event_subscriptions(self) -> EventSubscriptionsWithRawResponse:
+ return EventSubscriptionsWithRawResponse(self._events.event_subscriptions)
+
class AsyncEventsWithRawResponse:
def __init__(self, events: AsyncEvents) -> None:
@@ -588,6 +608,10 @@ def __init__(self, events: AsyncEvents) -> None:
def subscriptions(self) -> AsyncSubscriptionsWithRawResponse:
return AsyncSubscriptionsWithRawResponse(self._events.subscriptions)
+ @cached_property
+ def event_subscriptions(self) -> AsyncEventSubscriptionsWithRawResponse:
+ return AsyncEventSubscriptionsWithRawResponse(self._events.event_subscriptions)
+
class EventsWithStreamingResponse:
def __init__(self, events: Events) -> None:
@@ -607,6 +631,10 @@ def __init__(self, events: Events) -> None:
def subscriptions(self) -> SubscriptionsWithStreamingResponse:
return SubscriptionsWithStreamingResponse(self._events.subscriptions)
+ @cached_property
+ def event_subscriptions(self) -> EventSubscriptionsWithStreamingResponse:
+ return EventSubscriptionsWithStreamingResponse(self._events.event_subscriptions)
+
class AsyncEventsWithStreamingResponse:
def __init__(self, events: AsyncEvents) -> None:
@@ -625,3 +653,7 @@ def __init__(self, events: AsyncEvents) -> None:
@cached_property
def subscriptions(self) -> AsyncSubscriptionsWithStreamingResponse:
return AsyncSubscriptionsWithStreamingResponse(self._events.subscriptions)
+
+ @cached_property
+ def event_subscriptions(self) -> AsyncEventSubscriptionsWithStreamingResponse:
+ return AsyncEventSubscriptionsWithStreamingResponse(self._events.event_subscriptions)
diff --git a/src/lithic/resources/financial_accounts/financial_accounts.py b/src/lithic/resources/financial_accounts/financial_accounts.py
index 4aaebb08..5876eeb4 100644
--- a/src/lithic/resources/financial_accounts/financial_accounts.py
+++ b/src/lithic/resources/financial_accounts/financial_accounts.py
@@ -281,9 +281,7 @@ def update_status(
financial_account_token: str,
*,
status: Literal["OPEN", "CLOSED", "SUSPENDED", "PENDING"],
- status_change_reason: Optional[
- Literal["CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "CHARGED_OFF_DELINQUENT"]
- ],
+ substatus: Optional[Literal["CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "CHARGED_OFF_DELINQUENT"]],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -297,7 +295,7 @@ def update_status(
Args:
status: Status of the financial account
- status_change_reason: Reason for the financial account status change
+ substatus: Substatus for the financial account
extra_headers: Send extra headers
@@ -316,7 +314,7 @@ def update_status(
body=maybe_transform(
{
"status": status,
- "status_change_reason": status_change_reason,
+ "substatus": substatus,
},
financial_account_update_status_params.FinancialAccountUpdateStatusParams,
),
@@ -541,9 +539,7 @@ async def update_status(
financial_account_token: str,
*,
status: Literal["OPEN", "CLOSED", "SUSPENDED", "PENDING"],
- status_change_reason: Optional[
- Literal["CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "CHARGED_OFF_DELINQUENT"]
- ],
+ substatus: Optional[Literal["CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "CHARGED_OFF_DELINQUENT"]],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -557,7 +553,7 @@ async def update_status(
Args:
status: Status of the financial account
- status_change_reason: Reason for the financial account status change
+ substatus: Substatus for the financial account
extra_headers: Send extra headers
@@ -576,7 +572,7 @@ async def update_status(
body=await async_maybe_transform(
{
"status": status,
- "status_change_reason": status_change_reason,
+ "substatus": substatus,
},
financial_account_update_status_params.FinancialAccountUpdateStatusParams,
),
diff --git a/src/lithic/types/account_holder.py b/src/lithic/types/account_holder.py
index c21958f4..627df7fc 100644
--- a/src/lithic/types/account_holder.py
+++ b/src/lithic/types/account_holder.py
@@ -206,10 +206,7 @@ class AccountHolder(BaseModel):
"""Globally unique identifier for the account."""
beneficial_owner_entities: Optional[List[BeneficialOwnerEntity]] = None
- """Only present when user_type == "BUSINESS".
-
- List of all entities with >25% ownership in the company.
- """
+ """Deprecated. Only present when user_type == "BUSINESS"."""
beneficial_owner_individuals: Optional[List[BeneficialOwnerIndividual]] = None
"""Only present when user_type == "BUSINESS".
diff --git a/src/lithic/types/account_holder_create_params.py b/src/lithic/types/account_holder_create_params.py
index f1e47dcd..4a328871 100644
--- a/src/lithic/types/account_holder_create_params.py
+++ b/src/lithic/types/account_holder_create_params.py
@@ -10,10 +10,10 @@
__all__ = [
"AccountHolderCreateParams",
"KYB",
- "KYBBeneficialOwnerEntity",
"KYBBeneficialOwnerIndividual",
"KYBBusinessEntity",
"KYBControlPerson",
+ "KYBBeneficialOwnerEntity",
"KYC",
"KYCIndividual",
"KYCExempt",
@@ -21,26 +21,13 @@
class KYB(TypedDict, total=False):
- beneficial_owner_entities: Required[Iterable[KYBBeneficialOwnerEntity]]
- """List of all entities with >25% ownership in the company.
-
- If no entity or individual owns >25% of the company, and the largest shareholder
- is an entity, please identify them in this field. See
- [FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background. If no business owner is an entity, pass in an
- empty list. However, either this parameter or `beneficial_owner_individuals`
- must be populated. on entities that should be included.
- """
-
beneficial_owner_individuals: Required[Iterable[KYBBeneficialOwnerIndividual]]
"""List of all direct and indirect individuals with >25% ownership in the company.
- If no entity or individual owns >25% of the company, and the largest shareholder
- is an individual, please identify them in this field. See
+ If no individual owns >25% of the company, please identify the largest
+ shareholder in this field. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background on individuals that should be included. If no
- individual is an entity, pass in an empty list. However, either this parameter
- or `beneficial_owner_entities` must be populated.
+ (Section I) for more background on individuals that should be included.
"""
business_entity: Required[KYBBusinessEntity]
@@ -77,6 +64,9 @@ class KYB(TypedDict, total=False):
workflow: Required[Literal["KYB_BASIC", "KYB_BYO"]]
"""Specifies the type of KYB workflow to run."""
+ beneficial_owner_entities: Iterable[KYBBeneficialOwnerEntity]
+ """Deprecated."""
+
external_id: str
"""
A user provided id that can be used to link an account holder with an external
@@ -95,39 +85,6 @@ class KYB(TypedDict, total=False):
"""Company website URL."""
-class KYBBeneficialOwnerEntity(TypedDict, total=False):
- address: Required[Address]
- """
- Business's physical address - PO boxes, UPS drops, and FedEx drops are not
- acceptable; APO/FPO are acceptable.
- """
-
- government_id: Required[str]
- """Government-issued identification number.
-
- US Federal Employer Identification Numbers (EIN) are currently supported,
- entered as full nine-digits, with or without hyphens.
- """
-
- legal_business_name: Required[str]
- """Legal (formal) business name."""
-
- phone_numbers: Required[List[str]]
- """
- One or more of the business's phone number(s), entered as a list in E.164
- format.
- """
-
- dba_business_name: str
- """
- Any name that the business operates under that is not its legal business name
- (if applicable).
- """
-
- parent_company: str
- """Parent company name (if applicable)."""
-
-
class KYBBeneficialOwnerIndividual(TypedDict, total=False):
address: Required[Address]
"""
@@ -229,6 +186,39 @@ class KYBControlPerson(TypedDict, total=False):
"""Individual's phone number, entered in E.164 format."""
+class KYBBeneficialOwnerEntity(TypedDict, total=False):
+ address: Required[Address]
+ """
+ Business's physical address - PO boxes, UPS drops, and FedEx drops are not
+ acceptable; APO/FPO are acceptable.
+ """
+
+ government_id: Required[str]
+ """Government-issued identification number.
+
+ US Federal Employer Identification Numbers (EIN) are currently supported,
+ entered as full nine-digits, with or without hyphens.
+ """
+
+ legal_business_name: Required[str]
+ """Legal (formal) business name."""
+
+ phone_numbers: Required[List[str]]
+ """
+ One or more of the business's phone number(s), entered as a list in E.164
+ format.
+ """
+
+ dba_business_name: str
+ """
+ Any name that the business operates under that is not its legal business name
+ (if applicable).
+ """
+
+ parent_company: str
+ """Parent company name (if applicable)."""
+
+
class KYC(TypedDict, total=False):
individual: Required[KYCIndividual]
"""
diff --git a/src/lithic/types/card_convert_physical_params.py b/src/lithic/types/card_convert_physical_params.py
index 6625539b..745c0426 100644
--- a/src/lithic/types/card_convert_physical_params.py
+++ b/src/lithic/types/card_convert_physical_params.py
@@ -24,10 +24,11 @@ class CardConvertPhysicalParams(TypedDict, total=False):
to cards of type `PHYSICAL`. This must be configured with Lithic before use.
"""
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
"""Shipping method for the card.
- Use of options besides `STANDARD` require additional permissions.
+ Only applies to cards of type PHYSICAL. Use of options besides `STANDARD`
+ require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
diff --git a/src/lithic/types/card_reissue_params.py b/src/lithic/types/card_reissue_params.py
index 9be515f4..ca25add9 100644
--- a/src/lithic/types/card_reissue_params.py
+++ b/src/lithic/types/card_reissue_params.py
@@ -24,10 +24,11 @@ class CardReissueParams(TypedDict, total=False):
shipping_address: ShippingAddress
"""If omitted, the previous shipping address will be used."""
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
"""Shipping method for the card.
- Use of options besides `STANDARD` require additional permissions.
+ Only applies to cards of type PHYSICAL. Use of options besides `STANDARD`
+ require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
diff --git a/src/lithic/types/card_renew_params.py b/src/lithic/types/card_renew_params.py
index cac4483b..832b2ca6 100644
--- a/src/lithic/types/card_renew_params.py
+++ b/src/lithic/types/card_renew_params.py
@@ -38,10 +38,11 @@ class CardRenewParams(TypedDict, total=False):
to cards of type `PHYSICAL`. This must be configured with Lithic before use.
"""
- shipping_method: Literal["2-DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
+ shipping_method: Literal["2_DAY", "EXPEDITED", "EXPRESS", "PRIORITY", "STANDARD", "STANDARD_WITH_TRACKING"]
"""Shipping method for the card.
- Use of options besides `STANDARD` require additional permissions.
+ Only applies to cards of type PHYSICAL. Use of options besides `STANDARD`
+ require additional permissions.
- `STANDARD` - USPS regular mail or similar international option, with no
tracking
diff --git a/src/lithic/types/financial_account.py b/src/lithic/types/financial_account.py
index e83dc895..bb763758 100644
--- a/src/lithic/types/financial_account.py
+++ b/src/lithic/types/financial_account.py
@@ -57,7 +57,7 @@ class FinancialAccount(BaseModel):
routing_number: Optional[str] = None
- status_change_reason: Optional[
+ substatus: Optional[
Literal["CHARGED_OFF_DELINQUENT", "CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "DELINQUENT"]
] = None
- """Reason for the financial account status change"""
+ """Substatus for the financial account"""
diff --git a/src/lithic/types/financial_account_update_status_params.py b/src/lithic/types/financial_account_update_status_params.py
index 550151d2..5ae18b85 100644
--- a/src/lithic/types/financial_account_update_status_params.py
+++ b/src/lithic/types/financial_account_update_status_params.py
@@ -12,7 +12,7 @@ class FinancialAccountUpdateStatusParams(TypedDict, total=False):
status: Required[Literal["OPEN", "CLOSED", "SUSPENDED", "PENDING"]]
"""Status of the financial account"""
- status_change_reason: Required[
+ substatus: Required[
Optional[Literal["CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "CHARGED_OFF_DELINQUENT"]]
]
- """Reason for the financial account status change"""
+ """Substatus for the financial account"""
diff --git a/src/lithic/types/financial_accounts/loan_tape.py b/src/lithic/types/financial_accounts/loan_tape.py
index dc923b83..40b2adfb 100644
--- a/src/lithic/types/financial_accounts/loan_tape.py
+++ b/src/lithic/types/financial_accounts/loan_tape.py
@@ -32,10 +32,10 @@ class AccountStandingFinancialAccountState(BaseModel):
status: Literal["OPEN", "CLOSED", "SUSPENDED", "PENDING"]
"""Status of the financial account"""
- status_change_reason: Optional[
+ substatus: Optional[
Literal["CHARGED_OFF_DELINQUENT", "CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "DELINQUENT"]
] = None
- """Reason for the financial account status change"""
+ """Substatus for the financial account"""
class AccountStanding(BaseModel):
diff --git a/src/lithic/types/financial_accounts/statement.py b/src/lithic/types/financial_accounts/statement.py
index 624b41e4..b683f844 100644
--- a/src/lithic/types/financial_accounts/statement.py
+++ b/src/lithic/types/financial_accounts/statement.py
@@ -24,10 +24,10 @@ class AccountStandingFinancialAccountState(BaseModel):
status: Literal["OPEN", "CLOSED", "SUSPENDED", "PENDING"]
"""Status of the financial account"""
- status_change_reason: Optional[
+ substatus: Optional[
Literal["CHARGED_OFF_DELINQUENT", "CHARGED_OFF_FRAUD", "END_USER_REQUEST", "BANK_REQUEST", "DELINQUENT"]
] = None
- """Reason for the financial account status change"""
+ """Substatus for the financial account"""
class AccountStanding(BaseModel):
diff --git a/src/lithic/types/kyb_param.py b/src/lithic/types/kyb_param.py
index 31a83080..864902a9 100644
--- a/src/lithic/types/kyb_param.py
+++ b/src/lithic/types/kyb_param.py
@@ -7,40 +7,7 @@
from .shared_params.address import Address
-__all__ = ["KYBParam", "BeneficialOwnerEntity", "BeneficialOwnerIndividual", "BusinessEntity", "ControlPerson"]
-
-
-class BeneficialOwnerEntity(TypedDict, total=False):
- address: Required[Address]
- """
- Business's physical address - PO boxes, UPS drops, and FedEx drops are not
- acceptable; APO/FPO are acceptable.
- """
-
- government_id: Required[str]
- """Government-issued identification number.
-
- US Federal Employer Identification Numbers (EIN) are currently supported,
- entered as full nine-digits, with or without hyphens.
- """
-
- legal_business_name: Required[str]
- """Legal (formal) business name."""
-
- phone_numbers: Required[List[str]]
- """
- One or more of the business's phone number(s), entered as a list in E.164
- format.
- """
-
- dba_business_name: str
- """
- Any name that the business operates under that is not its legal business name
- (if applicable).
- """
-
- parent_company: str
- """Parent company name (if applicable)."""
+__all__ = ["KYBParam", "BeneficialOwnerIndividual", "BusinessEntity", "ControlPerson", "BeneficialOwnerEntity"]
class BeneficialOwnerIndividual(TypedDict, total=False):
@@ -144,27 +111,47 @@ class ControlPerson(TypedDict, total=False):
"""Individual's phone number, entered in E.164 format."""
-class KYBParam(TypedDict, total=False):
- beneficial_owner_entities: Required[Iterable[BeneficialOwnerEntity]]
- """List of all entities with >25% ownership in the company.
+class BeneficialOwnerEntity(TypedDict, total=False):
+ address: Required[Address]
+ """
+ Business's physical address - PO boxes, UPS drops, and FedEx drops are not
+ acceptable; APO/FPO are acceptable.
+ """
- If no entity or individual owns >25% of the company, and the largest shareholder
- is an entity, please identify them in this field. See
- [FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background. If no business owner is an entity, pass in an
- empty list. However, either this parameter or `beneficial_owner_individuals`
- must be populated. on entities that should be included.
+ government_id: Required[str]
+ """Government-issued identification number.
+
+ US Federal Employer Identification Numbers (EIN) are currently supported,
+ entered as full nine-digits, with or without hyphens.
"""
+ legal_business_name: Required[str]
+ """Legal (formal) business name."""
+
+ phone_numbers: Required[List[str]]
+ """
+ One or more of the business's phone number(s), entered as a list in E.164
+ format.
+ """
+
+ dba_business_name: str
+ """
+ Any name that the business operates under that is not its legal business name
+ (if applicable).
+ """
+
+ parent_company: str
+ """Parent company name (if applicable)."""
+
+
+class KYBParam(TypedDict, total=False):
beneficial_owner_individuals: Required[Iterable[BeneficialOwnerIndividual]]
"""List of all direct and indirect individuals with >25% ownership in the company.
- If no entity or individual owns >25% of the company, and the largest shareholder
- is an individual, please identify them in this field. See
+ If no individual owns >25% of the company, please identify the largest
+ shareholder in this field. See
[FinCEN requirements](https://www.fincen.gov/sites/default/files/shared/CDD_Rev6.7_Sept_2017_Certificate.pdf)
- (Section I) for more background on individuals that should be included. If no
- individual is an entity, pass in an empty list. However, either this parameter
- or `beneficial_owner_entities` must be populated.
+ (Section I) for more background on individuals that should be included.
"""
business_entity: Required[BusinessEntity]
@@ -201,6 +188,9 @@ class KYBParam(TypedDict, total=False):
workflow: Required[Literal["KYB_BASIC", "KYB_BYO"]]
"""Specifies the type of KYB workflow to run."""
+ beneficial_owner_entities: Iterable[BeneficialOwnerEntity]
+ """Deprecated."""
+
external_id: str
"""
A user provided id that can be used to link an account holder with an external
diff --git a/tests/api_resources/events/test_event_subscriptions.py b/tests/api_resources/events/test_event_subscriptions.py
new file mode 100644
index 00000000..a8d7f749
--- /dev/null
+++ b/tests/api_resources/events/test_event_subscriptions.py
@@ -0,0 +1,120 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from lithic import Lithic, AsyncLithic
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestEventSubscriptions:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_resend(self, client: Lithic) -> None:
+ event_subscription = client.events.event_subscriptions.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="event_token",
+ )
+ assert event_subscription is None
+
+ @parametrize
+ def test_raw_response_resend(self, client: Lithic) -> None:
+ response = client.events.event_subscriptions.with_raw_response.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="event_token",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ event_subscription = response.parse()
+ assert event_subscription is None
+
+ @parametrize
+ def test_streaming_response_resend(self, client: Lithic) -> None:
+ with client.events.event_subscriptions.with_streaming_response.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="event_token",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ event_subscription = response.parse()
+ assert event_subscription is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_resend(self, client: Lithic) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `event_token` but received ''"):
+ client.events.event_subscriptions.with_raw_response.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="",
+ )
+
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `event_subscription_token` but received ''"
+ ):
+ client.events.event_subscriptions.with_raw_response.resend(
+ event_subscription_token="",
+ event_token="event_token",
+ )
+
+
+class TestAsyncEventSubscriptions:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_resend(self, async_client: AsyncLithic) -> None:
+ event_subscription = await async_client.events.event_subscriptions.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="event_token",
+ )
+ assert event_subscription is None
+
+ @parametrize
+ async def test_raw_response_resend(self, async_client: AsyncLithic) -> None:
+ response = await async_client.events.event_subscriptions.with_raw_response.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="event_token",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ event_subscription = response.parse()
+ assert event_subscription is None
+
+ @parametrize
+ async def test_streaming_response_resend(self, async_client: AsyncLithic) -> None:
+ async with async_client.events.event_subscriptions.with_streaming_response.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="event_token",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ event_subscription = await response.parse()
+ assert event_subscription is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_resend(self, async_client: AsyncLithic) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `event_token` but received ''"):
+ await async_client.events.event_subscriptions.with_raw_response.resend(
+ event_subscription_token="event_subscription_token",
+ event_token="",
+ )
+
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `event_subscription_token` but received ''"
+ ):
+ await async_client.events.event_subscriptions.with_raw_response.resend(
+ event_subscription_token="",
+ event_token="event_token",
+ )
diff --git a/tests/api_resources/test_account_holders.py b/tests/api_resources/test_account_holders.py
index 6cc7f2d4..e813c3fd 100644
--- a/tests/api_resources/test_account_holders.py
+++ b/tests/api_resources/test_account_holders.py
@@ -29,20 +29,6 @@ class TestAccountHolders:
@parametrize
def test_method_create_overload_1(self, client: Lithic) -> None:
account_holder = client.account_holders.create(
- beneficial_owner_entities=[
- {
- "address": {
- "address1": "123 Old Forest Way",
- "city": "Omaha",
- "country": "USA",
- "postal_code": "68022",
- "state": "NE",
- },
- "government_id": "114-123-1513",
- "legal_business_name": "Acme, Inc.",
- "phone_numbers": ["+15555555555"],
- }
- ],
beneficial_owner_individuals=[
{
"address": {
@@ -94,23 +80,6 @@ def test_method_create_overload_1(self, client: Lithic) -> None:
@parametrize
def test_method_create_with_all_params_overload_1(self, client: Lithic) -> None:
account_holder = client.account_holders.create(
- beneficial_owner_entities=[
- {
- "address": {
- "address1": "123 Old Forest Way",
- "city": "Omaha",
- "country": "USA",
- "postal_code": "68022",
- "state": "NE",
- "address2": "address2",
- },
- "government_id": "114-123-1513",
- "legal_business_name": "Acme, Inc.",
- "phone_numbers": ["+15555555555"],
- "dba_business_name": "dba_business_name",
- "parent_company": "parent_company",
- }
- ],
beneficial_owner_individuals=[
{
"address": {
@@ -163,15 +132,6 @@ def test_method_create_with_all_params_overload_1(self, client: Lithic) -> None:
nature_of_business="Software company selling solutions to the restaurant industry",
tos_timestamp="2018-05-29T21:16:05Z",
workflow="KYB_BASIC",
- external_id="external_id",
- kyb_passed_timestamp="2018-05-29T21:16:05Z",
- website_url="www.mybusiness.com",
- )
- assert_matches_type(AccountHolderCreateResponse, account_holder, path=["response"])
-
- @parametrize
- def test_raw_response_create_overload_1(self, client: Lithic) -> None:
- response = client.account_holders.with_raw_response.create(
beneficial_owner_entities=[
{
"address": {
@@ -180,12 +140,24 @@ def test_raw_response_create_overload_1(self, client: Lithic) -> None:
"country": "USA",
"postal_code": "68022",
"state": "NE",
+ "address2": "address2",
},
"government_id": "114-123-1513",
"legal_business_name": "Acme, Inc.",
"phone_numbers": ["+15555555555"],
+ "dba_business_name": "dba_business_name",
+ "parent_company": "parent_company",
}
],
+ external_id="external_id",
+ kyb_passed_timestamp="2018-05-29T21:16:05Z",
+ website_url="www.mybusiness.com",
+ )
+ assert_matches_type(AccountHolderCreateResponse, account_holder, path=["response"])
+
+ @parametrize
+ def test_raw_response_create_overload_1(self, client: Lithic) -> None:
+ response = client.account_holders.with_raw_response.create(
beneficial_owner_individuals=[
{
"address": {
@@ -241,20 +213,6 @@ def test_raw_response_create_overload_1(self, client: Lithic) -> None:
@parametrize
def test_streaming_response_create_overload_1(self, client: Lithic) -> None:
with client.account_holders.with_streaming_response.create(
- beneficial_owner_entities=[
- {
- "address": {
- "address1": "123 Old Forest Way",
- "city": "Omaha",
- "country": "USA",
- "postal_code": "68022",
- "state": "NE",
- },
- "government_id": "114-123-1513",
- "legal_business_name": "Acme, Inc.",
- "phone_numbers": ["+15555555555"],
- }
- ],
beneficial_owner_individuals=[
{
"address": {
@@ -1040,20 +998,6 @@ class TestAsyncAccountHolders:
@parametrize
async def test_method_create_overload_1(self, async_client: AsyncLithic) -> None:
account_holder = await async_client.account_holders.create(
- beneficial_owner_entities=[
- {
- "address": {
- "address1": "123 Old Forest Way",
- "city": "Omaha",
- "country": "USA",
- "postal_code": "68022",
- "state": "NE",
- },
- "government_id": "114-123-1513",
- "legal_business_name": "Acme, Inc.",
- "phone_numbers": ["+15555555555"],
- }
- ],
beneficial_owner_individuals=[
{
"address": {
@@ -1105,23 +1049,6 @@ async def test_method_create_overload_1(self, async_client: AsyncLithic) -> None
@parametrize
async def test_method_create_with_all_params_overload_1(self, async_client: AsyncLithic) -> None:
account_holder = await async_client.account_holders.create(
- beneficial_owner_entities=[
- {
- "address": {
- "address1": "123 Old Forest Way",
- "city": "Omaha",
- "country": "USA",
- "postal_code": "68022",
- "state": "NE",
- "address2": "address2",
- },
- "government_id": "114-123-1513",
- "legal_business_name": "Acme, Inc.",
- "phone_numbers": ["+15555555555"],
- "dba_business_name": "dba_business_name",
- "parent_company": "parent_company",
- }
- ],
beneficial_owner_individuals=[
{
"address": {
@@ -1174,15 +1101,6 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn
nature_of_business="Software company selling solutions to the restaurant industry",
tos_timestamp="2018-05-29T21:16:05Z",
workflow="KYB_BASIC",
- external_id="external_id",
- kyb_passed_timestamp="2018-05-29T21:16:05Z",
- website_url="www.mybusiness.com",
- )
- assert_matches_type(AccountHolderCreateResponse, account_holder, path=["response"])
-
- @parametrize
- async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) -> None:
- response = await async_client.account_holders.with_raw_response.create(
beneficial_owner_entities=[
{
"address": {
@@ -1191,12 +1109,24 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) -
"country": "USA",
"postal_code": "68022",
"state": "NE",
+ "address2": "address2",
},
"government_id": "114-123-1513",
"legal_business_name": "Acme, Inc.",
"phone_numbers": ["+15555555555"],
+ "dba_business_name": "dba_business_name",
+ "parent_company": "parent_company",
}
],
+ external_id="external_id",
+ kyb_passed_timestamp="2018-05-29T21:16:05Z",
+ website_url="www.mybusiness.com",
+ )
+ assert_matches_type(AccountHolderCreateResponse, account_holder, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) -> None:
+ response = await async_client.account_holders.with_raw_response.create(
beneficial_owner_individuals=[
{
"address": {
@@ -1252,20 +1182,6 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) -
@parametrize
async def test_streaming_response_create_overload_1(self, async_client: AsyncLithic) -> None:
async with async_client.account_holders.with_streaming_response.create(
- beneficial_owner_entities=[
- {
- "address": {
- "address1": "123 Old Forest Way",
- "city": "Omaha",
- "country": "USA",
- "postal_code": "68022",
- "state": "NE",
- },
- "government_id": "114-123-1513",
- "legal_business_name": "Acme, Inc.",
- "phone_numbers": ["+15555555555"],
- }
- ],
beneficial_owner_individuals=[
{
"address": {
diff --git a/tests/api_resources/test_cards.py b/tests/api_resources/test_cards.py
index 2c99fd5f..095e72a7 100644
--- a/tests/api_resources/test_cards.py
+++ b/tests/api_resources/test_cards.py
@@ -252,7 +252,7 @@ def test_method_convert_physical_with_all_params(self, client: Lithic) -> None:
},
carrier={"qr_code_url": "https://lithic.com/activate-card/1"},
product_id="100",
- shipping_method="2-DAY",
+ shipping_method="2_DAY",
)
assert_matches_type(Card, card, path=["response"])
@@ -437,7 +437,7 @@ def test_method_reissue_with_all_params(self, client: Lithic) -> None:
"line2_text": "The Bluth Company",
"phone_number": "+15555555555",
},
- shipping_method="2-DAY",
+ shipping_method="2_DAY",
)
assert_matches_type(Card, card, path=["response"])
@@ -509,7 +509,7 @@ def test_method_renew_with_all_params(self, client: Lithic) -> None:
exp_month="06",
exp_year="2027",
product_id="100",
- shipping_method="2-DAY",
+ shipping_method="2_DAY",
)
assert_matches_type(Card, card, path=["response"])
@@ -873,7 +873,7 @@ async def test_method_convert_physical_with_all_params(self, async_client: Async
},
carrier={"qr_code_url": "https://lithic.com/activate-card/1"},
product_id="100",
- shipping_method="2-DAY",
+ shipping_method="2_DAY",
)
assert_matches_type(Card, card, path=["response"])
@@ -1058,7 +1058,7 @@ async def test_method_reissue_with_all_params(self, async_client: AsyncLithic) -
"line2_text": "The Bluth Company",
"phone_number": "+15555555555",
},
- shipping_method="2-DAY",
+ shipping_method="2_DAY",
)
assert_matches_type(Card, card, path=["response"])
@@ -1130,7 +1130,7 @@ async def test_method_renew_with_all_params(self, async_client: AsyncLithic) ->
exp_month="06",
exp_year="2027",
product_id="100",
- shipping_method="2-DAY",
+ shipping_method="2_DAY",
)
assert_matches_type(Card, card, path=["response"])
diff --git a/tests/api_resources/test_financial_accounts.py b/tests/api_resources/test_financial_accounts.py
index 09158c5c..dc79f4dc 100644
--- a/tests/api_resources/test_financial_accounts.py
+++ b/tests/api_resources/test_financial_accounts.py
@@ -191,7 +191,7 @@ def test_method_update_status(self, client: Lithic) -> None:
financial_account = client.financial_accounts.update_status(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
)
assert_matches_type(FinancialAccount, financial_account, path=["response"])
@@ -200,7 +200,7 @@ def test_raw_response_update_status(self, client: Lithic) -> None:
response = client.financial_accounts.with_raw_response.update_status(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
)
assert response.is_closed is True
@@ -213,7 +213,7 @@ def test_streaming_response_update_status(self, client: Lithic) -> None:
with client.financial_accounts.with_streaming_response.update_status(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -231,7 +231,7 @@ def test_path_params_update_status(self, client: Lithic) -> None:
client.financial_accounts.with_raw_response.update_status(
financial_account_token="",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
)
@@ -409,7 +409,7 @@ async def test_method_update_status(self, async_client: AsyncLithic) -> None:
financial_account = await async_client.financial_accounts.update_status(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
)
assert_matches_type(FinancialAccount, financial_account, path=["response"])
@@ -418,7 +418,7 @@ async def test_raw_response_update_status(self, async_client: AsyncLithic) -> No
response = await async_client.financial_accounts.with_raw_response.update_status(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
)
assert response.is_closed is True
@@ -431,7 +431,7 @@ async def test_streaming_response_update_status(self, async_client: AsyncLithic)
async with async_client.financial_accounts.with_streaming_response.update_status(
financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -449,5 +449,5 @@ async def test_path_params_update_status(self, async_client: AsyncLithic) -> Non
await async_client.financial_accounts.with_raw_response.update_status(
financial_account_token="",
status="OPEN",
- status_change_reason="CHARGED_OFF_FRAUD",
+ substatus="CHARGED_OFF_FRAUD",
)
From 18cc5b7527ab35948426d8df3d1d234a7d2c9eb0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 7 Apr 2025 16:55:04 +0000
Subject: [PATCH 6/6] release: 0.88.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 16 ++++++++++++++++
pyproject.toml | 2 +-
src/lithic/_version.py | 2 +-
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 6da9dbc7..d80a91e2 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.87.1"
+ ".": "0.88.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5cd3e9ff..cd1c020c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# Changelog
+## 0.88.0 (2025-04-07)
+
+Full Changelog: [v0.87.1...v0.88.0](https://github.com/lithic-com/lithic-python/compare/v0.87.1...v0.88.0)
+
+### Features
+
+* **api:** new resend endpoint for Event Subscriptions ([#729](https://github.com/lithic-com/lithic-python/issues/729)) ([8d5e634](https://github.com/lithic-com/lithic-python/commit/8d5e6343610762cb6362c15d52f53635d440dfa4))
+
+
+### Chores
+
+* internal codegen changes ([30d680f](https://github.com/lithic-com/lithic-python/commit/30d680f54263574ca236ad1095ab1775196beae1))
+* internal codegen changes ([54766ec](https://github.com/lithic-com/lithic-python/commit/54766ec079921166182a3bf8cb01e575591379bf))
+* **internal:** only run examples workflow in main repo ([#728](https://github.com/lithic-com/lithic-python/issues/728)) ([4789b73](https://github.com/lithic-com/lithic-python/commit/4789b7322178e77e925c66d95c911dd09e6f6e84))
+* **internal:** remove trailing character ([#727](https://github.com/lithic-com/lithic-python/issues/727)) ([b2f78a5](https://github.com/lithic-com/lithic-python/commit/b2f78a54322e3758fea084c1f2cc893c40d44b59))
+
## 0.87.1 (2025-03-27)
Full Changelog: [v0.87.0...v0.87.1](https://github.com/lithic-com/lithic-python/compare/v0.87.0...v0.87.1)
diff --git a/pyproject.toml b/pyproject.toml
index c10c0da4..88de6f19 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "lithic"
-version = "0.87.1"
+version = "0.88.0"
description = "The official Python library for the lithic API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/lithic/_version.py b/src/lithic/_version.py
index 0ccb5cae..2cf6d98e 100644
--- a/src/lithic/_version.py
+++ b/src/lithic/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "lithic"
-__version__ = "0.87.1" # x-release-please-version
+__version__ = "0.88.0" # x-release-please-version