diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 016de58f..7ec2e07d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -61,14 +61,18 @@ jobs:
run: rye build
- name: Get GitHub OIDC Token
- if: github.repository == 'stainless-sdks/lithic-python'
+ if: |-
+ github.repository == 'stainless-sdks/lithic-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());
- name: Upload tarball
- if: github.repository == 'stainless-sdks/lithic-python'
+ if: |-
+ github.repository == 'stainless-sdks/lithic-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b6700282..617f7502 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.117.0"
+ ".": "0.118.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index eba290a5..9a8e226d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 184
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-ee8607f0a2cdcaee420935050334a439db8dd097be83023fccdaf1d6f9a7de14.yml
-openapi_spec_hash: 0f21c68cdddb7c5bd99f42356d507393
-config_hash: fb5070d41fcabdedbc084b83964b592a
+configured_endpoints: 188
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-1e902917b2eae41d549957e790eb6b137969e451efe673815647deba330fe05a.yml
+openapi_spec_hash: 82cab06ce65462e60316939db630460a
+config_hash: 8799cfd589579f105ef8696a6d664c71
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b82d9dc5..c350af99 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,24 @@
# Changelog
+## 0.118.0 (2026-03-10)
+
+Full Changelog: [v0.117.0...v0.118.0](https://github.com/lithic-com/lithic-python/compare/v0.117.0...v0.118.0)
+
+### Features
+
+* **api:** add EARLY_DIRECT_DEPOSIT_FLOAT type to financial accounts ([6b3cfd6](https://github.com/lithic-com/lithic-python/commit/6b3cfd6ac06980b80d110b19b20697068bbeeee9))
+* **api:** add typescript_code rule type, state/error fields to auth_rules ([f6dc800](https://github.com/lithic-com/lithic-python/commit/f6dc800f95e413c8a9436c5a966a2bb12d27b6b6))
+
+
+### Bug Fixes
+
+* **api:** Disable MCP server to fix TypeScript SDK package publishing ([f23d302](https://github.com/lithic-com/lithic-python/commit/f23d3022b0b0a860db16cefc008153f09c0bae48))
+
+
+### Chores
+
+* **internal:** codegen related update ([845458d](https://github.com/lithic-com/lithic-python/commit/845458d17d741e51d1ef212fac9de9a9cbd8b0e5))
+
## 0.117.0 (2026-03-05)
Full Changelog: [v0.116.0...v0.117.0](https://github.com/lithic-com/lithic-python/compare/v0.116.0...v0.117.0)
diff --git a/README.md b/README.md
index d91fcf39..0aaa73df 100644
--- a/README.md
+++ b/README.md
@@ -7,15 +7,6 @@ The Lithic Python library provides convenient access to the Lithic REST API from
application. The library includes type definitions for all request params and response fields,
and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
-## MCP Server
-
-Use the Lithic MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
-
-[](https://cursor.com/en-US/install-mcp?name=lithic-mcp&config=eyJuYW1lIjoibGl0aGljLW1jcCIsInRyYW5zcG9ydCI6Imh0dHAiLCJ1cmwiOiJodHRwczovL2xpdGhpYy5zdGxtY3AuY29tIiwiaGVhZGVycyI6eyJ4LWxpdGhpYy1hcGkta2V5IjoiTXkgTGl0aGljIEFQSSBLZXkifX0)
-[](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22lithic-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Flithic.stlmcp.com%22%2C%22headers%22%3A%7B%22x-lithic-api-key%22%3A%22My%20Lithic%20API%20Key%22%7D%7D)
-
-> Note: You may need to set environment variables in your MCP client.
-
## Documentation
The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com). The full API of this library can be found in [api.md](api.md).
diff --git a/api.md b/api.md
index e247a6e0..ef4fa828 100644
--- a/api.md
+++ b/api.md
@@ -108,6 +108,9 @@ from lithic.types.auth_rules import (
EventStream,
MerchantLockParameters,
ReportStats,
+ RuleFeature,
+ TypescriptCodeParameters,
+ VelocityLimitFilters,
VelocityLimitParams,
VelocityLimitPeriod,
V2ListResultsResponse,
@@ -827,6 +830,21 @@ Methods:
- client.network_programs.retrieve(network_program_token) -> NetworkProgram
- client.network_programs.list(\*\*params) -> SyncSinglePage[NetworkProgram]
+# Holds
+
+Types:
+
+```python
+from lithic.types import Hold, HoldEvent
+```
+
+Methods:
+
+- client.holds.create(financial_account_token, \*\*params) -> Hold
+- client.holds.retrieve(hold_token) -> Hold
+- client.holds.list(financial_account_token, \*\*params) -> SyncCursorPage[Hold]
+- client.holds.void(hold_token, \*\*params) -> Hold
+
# AccountActivity
Types:
diff --git a/pyproject.toml b/pyproject.toml
index 33fa6251..9df22bbb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "lithic"
-version = "0.117.0"
+version = "0.118.0"
description = "The official Python library for the lithic API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/lithic/_client.py b/src/lithic/_client.py
index 4f9fd51a..4a7a8a88 100644
--- a/src/lithic/_client.py
+++ b/src/lithic/_client.py
@@ -40,6 +40,7 @@
from .resources import (
cards,
fraud,
+ holds,
events,
reports,
accounts,
@@ -69,6 +70,7 @@
external_bank_accounts,
tokenization_decisioning,
)
+ from .resources.holds import Holds, AsyncHolds
from .resources.accounts import Accounts, AsyncAccounts
from .resources.balances import Balances, AsyncBalances
from .resources.disputes import Disputes, AsyncDisputes
@@ -374,6 +376,12 @@ def network_programs(self) -> NetworkPrograms:
return NetworkPrograms(self)
+ @cached_property
+ def holds(self) -> Holds:
+ from .resources.holds import Holds
+
+ return Holds(self)
+
@cached_property
def account_activity(self) -> AccountActivity:
from .resources.account_activity import AccountActivity
@@ -783,6 +791,12 @@ def network_programs(self) -> AsyncNetworkPrograms:
return AsyncNetworkPrograms(self)
+ @cached_property
+ def holds(self) -> AsyncHolds:
+ from .resources.holds import AsyncHolds
+
+ return AsyncHolds(self)
+
@cached_property
def account_activity(self) -> AsyncAccountActivity:
from .resources.account_activity import AsyncAccountActivity
@@ -1115,6 +1129,12 @@ def network_programs(self) -> network_programs.NetworkProgramsWithRawResponse:
return NetworkProgramsWithRawResponse(self._client.network_programs)
+ @cached_property
+ def holds(self) -> holds.HoldsWithRawResponse:
+ from .resources.holds import HoldsWithRawResponse
+
+ return HoldsWithRawResponse(self._client.holds)
+
@cached_property
def account_activity(self) -> account_activity.AccountActivityWithRawResponse:
from .resources.account_activity import AccountActivityWithRawResponse
@@ -1306,6 +1326,12 @@ def network_programs(self) -> network_programs.AsyncNetworkProgramsWithRawRespon
return AsyncNetworkProgramsWithRawResponse(self._client.network_programs)
+ @cached_property
+ def holds(self) -> holds.AsyncHoldsWithRawResponse:
+ from .resources.holds import AsyncHoldsWithRawResponse
+
+ return AsyncHoldsWithRawResponse(self._client.holds)
+
@cached_property
def account_activity(self) -> account_activity.AsyncAccountActivityWithRawResponse:
from .resources.account_activity import AsyncAccountActivityWithRawResponse
@@ -1497,6 +1523,12 @@ def network_programs(self) -> network_programs.NetworkProgramsWithStreamingRespo
return NetworkProgramsWithStreamingResponse(self._client.network_programs)
+ @cached_property
+ def holds(self) -> holds.HoldsWithStreamingResponse:
+ from .resources.holds import HoldsWithStreamingResponse
+
+ return HoldsWithStreamingResponse(self._client.holds)
+
@cached_property
def account_activity(self) -> account_activity.AccountActivityWithStreamingResponse:
from .resources.account_activity import AccountActivityWithStreamingResponse
@@ -1688,6 +1720,12 @@ def network_programs(self) -> network_programs.AsyncNetworkProgramsWithStreaming
return AsyncNetworkProgramsWithStreamingResponse(self._client.network_programs)
+ @cached_property
+ def holds(self) -> holds.AsyncHoldsWithStreamingResponse:
+ from .resources.holds import AsyncHoldsWithStreamingResponse
+
+ return AsyncHoldsWithStreamingResponse(self._client.holds)
+
@cached_property
def account_activity(self) -> account_activity.AsyncAccountActivityWithStreamingResponse:
from .resources.account_activity import AsyncAccountActivityWithStreamingResponse
diff --git a/src/lithic/_version.py b/src/lithic/_version.py
index 39276f3d..86511f28 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.117.0" # x-release-please-version
+__version__ = "0.118.0" # x-release-please-version
diff --git a/src/lithic/resources/__init__.py b/src/lithic/resources/__init__.py
index 07be719f..47ee1966 100644
--- a/src/lithic/resources/__init__.py
+++ b/src/lithic/resources/__init__.py
@@ -16,6 +16,14 @@
FraudWithStreamingResponse,
AsyncFraudWithStreamingResponse,
)
+from .holds import (
+ Holds,
+ AsyncHolds,
+ HoldsWithRawResponse,
+ AsyncHoldsWithRawResponse,
+ HoldsWithStreamingResponse,
+ AsyncHoldsWithStreamingResponse,
+)
from .events import (
Events,
AsyncEvents,
@@ -411,6 +419,12 @@
"AsyncNetworkProgramsWithRawResponse",
"NetworkProgramsWithStreamingResponse",
"AsyncNetworkProgramsWithStreamingResponse",
+ "Holds",
+ "AsyncHolds",
+ "HoldsWithRawResponse",
+ "AsyncHoldsWithRawResponse",
+ "HoldsWithStreamingResponse",
+ "AsyncHoldsWithStreamingResponse",
"AccountActivity",
"AsyncAccountActivity",
"AccountActivityWithRawResponse",
diff --git a/src/lithic/resources/account_activity.py b/src/lithic/resources/account_activity.py
index c9cd0223..6a4045b1 100644
--- a/src/lithic/resources/account_activity.py
+++ b/src/lithic/resources/account_activity.py
@@ -69,6 +69,7 @@ def list(
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
"MANAGEMENT_DISBURSEMENT",
+ "HOLD",
"PROGRAM_FUNDING",
]
| Omit = omit,
@@ -239,6 +240,7 @@ def list(
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
"MANAGEMENT_DISBURSEMENT",
+ "HOLD",
"PROGRAM_FUNDING",
]
| Omit = omit,
diff --git a/src/lithic/resources/auth_rules/v2/v2.py b/src/lithic/resources/auth_rules/v2/v2.py
index 59a7ad20..3e2ef6ed 100644
--- a/src/lithic/resources/auth_rules/v2/v2.py
+++ b/src/lithic/resources/auth_rules/v2/v2.py
@@ -72,7 +72,7 @@ def create(
self,
*,
parameters: v2_create_params.AccountLevelRuleParameters,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
account_tokens: SequenceNotStr[str] | Omit = omit,
business_account_tokens: SequenceNotStr[str] | Omit = omit,
event_stream: EventStream | Omit = omit,
@@ -101,6 +101,8 @@ def create(
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
account_tokens: Account tokens to which the Auth Rule applies.
@@ -126,7 +128,7 @@ def create(
*,
card_tokens: SequenceNotStr[str],
parameters: v2_create_params.CardLevelRuleParameters,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
event_stream: EventStream | Omit = omit,
name: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -155,6 +157,8 @@ def create(
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
event_stream: The event stream during which the rule will be evaluated.
@@ -176,7 +180,7 @@ def create(
*,
parameters: v2_create_params.ProgramLevelRuleParameters,
program_level: bool,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
event_stream: EventStream | Omit = omit,
excluded_card_tokens: SequenceNotStr[str] | Omit = omit,
name: Optional[str] | Omit = omit,
@@ -206,6 +210,8 @@ def create(
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
event_stream: The event stream during which the rule will be evaluated.
@@ -232,7 +238,7 @@ def create(
parameters: v2_create_params.AccountLevelRuleParameters
| v2_create_params.CardLevelRuleParameters
| v2_create_params.ProgramLevelRuleParameters,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
account_tokens: SequenceNotStr[str] | Omit = omit,
business_account_tokens: SequenceNotStr[str] | Omit = omit,
event_stream: EventStream | Omit = omit,
@@ -890,7 +896,7 @@ async def create(
self,
*,
parameters: v2_create_params.AccountLevelRuleParameters,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
account_tokens: SequenceNotStr[str] | Omit = omit,
business_account_tokens: SequenceNotStr[str] | Omit = omit,
event_stream: EventStream | Omit = omit,
@@ -919,6 +925,8 @@ async def create(
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
account_tokens: Account tokens to which the Auth Rule applies.
@@ -944,7 +952,7 @@ async def create(
*,
card_tokens: SequenceNotStr[str],
parameters: v2_create_params.CardLevelRuleParameters,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
event_stream: EventStream | Omit = omit,
name: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -973,6 +981,8 @@ async def create(
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
event_stream: The event stream during which the rule will be evaluated.
@@ -994,7 +1004,7 @@ async def create(
*,
parameters: v2_create_params.ProgramLevelRuleParameters,
program_level: bool,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
event_stream: EventStream | Omit = omit,
excluded_card_tokens: SequenceNotStr[str] | Omit = omit,
name: Optional[str] | Omit = omit,
@@ -1024,6 +1034,8 @@ async def create(
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
event_stream: The event stream during which the rule will be evaluated.
@@ -1050,7 +1062,7 @@ async def create(
parameters: v2_create_params.AccountLevelRuleParameters
| v2_create_params.CardLevelRuleParameters
| v2_create_params.ProgramLevelRuleParameters,
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"],
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"],
account_tokens: SequenceNotStr[str] | Omit = omit,
business_account_tokens: SequenceNotStr[str] | Omit = omit,
event_stream: EventStream | Omit = omit,
diff --git a/src/lithic/resources/financial_accounts/financial_accounts.py b/src/lithic/resources/financial_accounts/financial_accounts.py
index e26c023c..3c42d154 100644
--- a/src/lithic/resources/financial_accounts/financial_accounts.py
+++ b/src/lithic/resources/financial_accounts/financial_accounts.py
@@ -251,7 +251,7 @@ def list(
*,
account_token: str | Omit = omit,
business_account_token: str | Omit = omit,
- type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY"] | Omit = omit,
+ type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY", "EARLY_DIRECT_DEPOSIT_FLOAT"] | Omit = omit,
# 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,
@@ -569,7 +569,7 @@ def list(
*,
account_token: str | Omit = omit,
business_account_token: str | Omit = omit,
- type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY"] | Omit = omit,
+ type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY", "EARLY_DIRECT_DEPOSIT_FLOAT"] | Omit = omit,
# 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,
diff --git a/src/lithic/resources/holds.py b/src/lithic/resources/holds.py
new file mode 100644
index 00000000..45d6c4ae
--- /dev/null
+++ b/src/lithic/resources/holds.py
@@ -0,0 +1,550 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+import httpx
+
+from .. import _legacy_response
+from ..types import hold_list_params, hold_void_params, hold_create_params
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from .._utils import maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
+from ..pagination import SyncCursorPage, AsyncCursorPage
+from ..types.hold import Hold
+from .._base_client import AsyncPaginator, make_request_options
+
+__all__ = ["Holds", "AsyncHolds"]
+
+
+class Holds(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> HoldsWithRawResponse:
+ """
+ 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 HoldsWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> HoldsWithStreamingResponse:
+ """
+ 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 HoldsWithStreamingResponse(self)
+
+ def create(
+ self,
+ financial_account_token: str,
+ *,
+ amount: int,
+ token: str | Omit = omit,
+ expiration_datetime: Union[str, datetime] | Omit = omit,
+ memo: Optional[str] | Omit = omit,
+ user_defined_id: str | Omit = omit,
+ # 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,
+ ) -> Hold:
+ """Create a hold on a financial account.
+
+ Holds reserve funds by moving them from
+ available to pending balance. They can be resolved via settlement (linked to a
+ payment or book transfer), voiding, or expiration.
+
+ Args:
+ amount: Amount to hold in cents
+
+ token: Customer-provided token for idempotency. Becomes the hold token.
+
+ expiration_datetime: When the hold should auto-expire
+
+ memo: Reason for the hold
+
+ user_defined_id: User-provided identifier for the hold
+
+ 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 financial_account_token:
+ raise ValueError(
+ f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}"
+ )
+ return self._post(
+ f"/v1/financial_accounts/{financial_account_token}/holds",
+ body=maybe_transform(
+ {
+ "amount": amount,
+ "token": token,
+ "expiration_datetime": expiration_datetime,
+ "memo": memo,
+ "user_defined_id": user_defined_id,
+ },
+ hold_create_params.HoldCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Hold,
+ )
+
+ def retrieve(
+ self,
+ hold_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,
+ ) -> Hold:
+ """
+ Get hold by token.
+
+ 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 hold_token:
+ raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}")
+ return self._get(
+ f"/v1/holds/{hold_token}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Hold,
+ )
+
+ def list(
+ self,
+ financial_account_token: str,
+ *,
+ begin: Union[str, datetime] | Omit = omit,
+ end: Union[str, datetime] | Omit = omit,
+ ending_before: str | Omit = omit,
+ page_size: int | Omit = omit,
+ starting_after: str | Omit = omit,
+ status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED"] | Omit = omit,
+ # 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,
+ ) -> SyncCursorPage[Hold]:
+ """
+ List holds for a financial account.
+
+ Args:
+ begin: Date string in RFC 3339 format. Only entries created after the specified time
+ will be included. UTC time zone.
+
+ end: Date string in RFC 3339 format. Only entries created before the specified time
+ will be included. UTC time zone.
+
+ ending_before: A cursor representing an item's token before which a page of results should end.
+ Used to retrieve the previous page of results before this item.
+
+ page_size: Page size (for pagination).
+
+ starting_after: A cursor representing an item's token after which a page of results should
+ begin. Used to retrieve the next page of results after this item.
+
+ status: Hold status to filter by.
+
+ 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 financial_account_token:
+ raise ValueError(
+ f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}"
+ )
+ return self._get_api_list(
+ f"/v1/financial_accounts/{financial_account_token}/holds",
+ page=SyncCursorPage[Hold],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "begin": begin,
+ "end": end,
+ "ending_before": ending_before,
+ "page_size": page_size,
+ "starting_after": starting_after,
+ "status": status,
+ },
+ hold_list_params.HoldListParams,
+ ),
+ ),
+ model=Hold,
+ )
+
+ def void(
+ self,
+ hold_token: str,
+ *,
+ memo: Optional[str] | Omit = omit,
+ # 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,
+ ) -> Hold:
+ """Void an active hold.
+
+ This returns the held funds from pending back to available
+ balance. Only holds in PENDING status can be voided.
+
+ Args:
+ memo: Reason for voiding the hold
+
+ 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 hold_token:
+ raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}")
+ return self._post(
+ f"/v1/holds/{hold_token}/void",
+ body=maybe_transform({"memo": memo}, hold_void_params.HoldVoidParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Hold,
+ )
+
+
+class AsyncHolds(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncHoldsWithRawResponse:
+ """
+ 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 AsyncHoldsWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncHoldsWithStreamingResponse:
+ """
+ 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 AsyncHoldsWithStreamingResponse(self)
+
+ async def create(
+ self,
+ financial_account_token: str,
+ *,
+ amount: int,
+ token: str | Omit = omit,
+ expiration_datetime: Union[str, datetime] | Omit = omit,
+ memo: Optional[str] | Omit = omit,
+ user_defined_id: str | Omit = omit,
+ # 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,
+ ) -> Hold:
+ """Create a hold on a financial account.
+
+ Holds reserve funds by moving them from
+ available to pending balance. They can be resolved via settlement (linked to a
+ payment or book transfer), voiding, or expiration.
+
+ Args:
+ amount: Amount to hold in cents
+
+ token: Customer-provided token for idempotency. Becomes the hold token.
+
+ expiration_datetime: When the hold should auto-expire
+
+ memo: Reason for the hold
+
+ user_defined_id: User-provided identifier for the hold
+
+ 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 financial_account_token:
+ raise ValueError(
+ f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}"
+ )
+ return await self._post(
+ f"/v1/financial_accounts/{financial_account_token}/holds",
+ body=await async_maybe_transform(
+ {
+ "amount": amount,
+ "token": token,
+ "expiration_datetime": expiration_datetime,
+ "memo": memo,
+ "user_defined_id": user_defined_id,
+ },
+ hold_create_params.HoldCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Hold,
+ )
+
+ async def retrieve(
+ self,
+ hold_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,
+ ) -> Hold:
+ """
+ Get hold by token.
+
+ 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 hold_token:
+ raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}")
+ return await self._get(
+ f"/v1/holds/{hold_token}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Hold,
+ )
+
+ def list(
+ self,
+ financial_account_token: str,
+ *,
+ begin: Union[str, datetime] | Omit = omit,
+ end: Union[str, datetime] | Omit = omit,
+ ending_before: str | Omit = omit,
+ page_size: int | Omit = omit,
+ starting_after: str | Omit = omit,
+ status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED"] | Omit = omit,
+ # 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,
+ ) -> AsyncPaginator[Hold, AsyncCursorPage[Hold]]:
+ """
+ List holds for a financial account.
+
+ Args:
+ begin: Date string in RFC 3339 format. Only entries created after the specified time
+ will be included. UTC time zone.
+
+ end: Date string in RFC 3339 format. Only entries created before the specified time
+ will be included. UTC time zone.
+
+ ending_before: A cursor representing an item's token before which a page of results should end.
+ Used to retrieve the previous page of results before this item.
+
+ page_size: Page size (for pagination).
+
+ starting_after: A cursor representing an item's token after which a page of results should
+ begin. Used to retrieve the next page of results after this item.
+
+ status: Hold status to filter by.
+
+ 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 financial_account_token:
+ raise ValueError(
+ f"Expected a non-empty value for `financial_account_token` but received {financial_account_token!r}"
+ )
+ return self._get_api_list(
+ f"/v1/financial_accounts/{financial_account_token}/holds",
+ page=AsyncCursorPage[Hold],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "begin": begin,
+ "end": end,
+ "ending_before": ending_before,
+ "page_size": page_size,
+ "starting_after": starting_after,
+ "status": status,
+ },
+ hold_list_params.HoldListParams,
+ ),
+ ),
+ model=Hold,
+ )
+
+ async def void(
+ self,
+ hold_token: str,
+ *,
+ memo: Optional[str] | Omit = omit,
+ # 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,
+ ) -> Hold:
+ """Void an active hold.
+
+ This returns the held funds from pending back to available
+ balance. Only holds in PENDING status can be voided.
+
+ Args:
+ memo: Reason for voiding the hold
+
+ 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 hold_token:
+ raise ValueError(f"Expected a non-empty value for `hold_token` but received {hold_token!r}")
+ return await self._post(
+ f"/v1/holds/{hold_token}/void",
+ body=await async_maybe_transform({"memo": memo}, hold_void_params.HoldVoidParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Hold,
+ )
+
+
+class HoldsWithRawResponse:
+ def __init__(self, holds: Holds) -> None:
+ self._holds = holds
+
+ self.create = _legacy_response.to_raw_response_wrapper(
+ holds.create,
+ )
+ self.retrieve = _legacy_response.to_raw_response_wrapper(
+ holds.retrieve,
+ )
+ self.list = _legacy_response.to_raw_response_wrapper(
+ holds.list,
+ )
+ self.void = _legacy_response.to_raw_response_wrapper(
+ holds.void,
+ )
+
+
+class AsyncHoldsWithRawResponse:
+ def __init__(self, holds: AsyncHolds) -> None:
+ self._holds = holds
+
+ self.create = _legacy_response.async_to_raw_response_wrapper(
+ holds.create,
+ )
+ self.retrieve = _legacy_response.async_to_raw_response_wrapper(
+ holds.retrieve,
+ )
+ self.list = _legacy_response.async_to_raw_response_wrapper(
+ holds.list,
+ )
+ self.void = _legacy_response.async_to_raw_response_wrapper(
+ holds.void,
+ )
+
+
+class HoldsWithStreamingResponse:
+ def __init__(self, holds: Holds) -> None:
+ self._holds = holds
+
+ self.create = to_streamed_response_wrapper(
+ holds.create,
+ )
+ self.retrieve = to_streamed_response_wrapper(
+ holds.retrieve,
+ )
+ self.list = to_streamed_response_wrapper(
+ holds.list,
+ )
+ self.void = to_streamed_response_wrapper(
+ holds.void,
+ )
+
+
+class AsyncHoldsWithStreamingResponse:
+ def __init__(self, holds: AsyncHolds) -> None:
+ self._holds = holds
+
+ self.create = async_to_streamed_response_wrapper(
+ holds.create,
+ )
+ self.retrieve = async_to_streamed_response_wrapper(
+ holds.retrieve,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ holds.list,
+ )
+ self.void = async_to_streamed_response_wrapper(
+ holds.void,
+ )
diff --git a/src/lithic/types/__init__.py b/src/lithic/types/__init__.py
index 5532206f..60253cf5 100644
--- a/src/lithic/types/__init__.py
+++ b/src/lithic/types/__init__.py
@@ -3,6 +3,7 @@
from __future__ import annotations
from .card import Card as Card
+from .hold import Hold as Hold
from .event import Event as Event
from .device import Device as Device
from .shared import (
@@ -24,6 +25,7 @@
from .kyc_param import KYCParam as KYCParam
from .api_status import APIStatus as APIStatus
from .dispute_v2 import DisputeV2 as DisputeV2
+from .hold_event import HoldEvent as HoldEvent
from .owner_type import OwnerType as OwnerType
from .token_info import TokenInfo as TokenInfo
from .transaction import Transaction as Transaction
@@ -42,6 +44,8 @@
from .digital_card_art import DigitalCardArt as DigitalCardArt
from .dispute_evidence import DisputeEvidence as DisputeEvidence
from .external_payment import ExternalPayment as ExternalPayment
+from .hold_list_params import HoldListParams as HoldListParams
+from .hold_void_params import HoldVoidParams as HoldVoidParams
from .kyc_exempt_param import KYCExemptParam as KYCExemptParam
from .statement_totals import StatementTotals as StatementTotals
from .card_embed_params import CardEmbedParams as CardEmbedParams
@@ -57,6 +61,7 @@
from .card_create_params import CardCreateParams as CardCreateParams
from .card_update_params import CardUpdateParams as CardUpdateParams
from .event_subscription import EventSubscription as EventSubscription
+from .hold_create_params import HoldCreateParams as HoldCreateParams
from .provision_response import ProvisionResponse as ProvisionResponse
from .wire_party_details import WirePartyDetails as WirePartyDetails
from .account_list_params import AccountListParams as AccountListParams
diff --git a/src/lithic/types/account_activity_list_params.py b/src/lithic/types/account_activity_list_params.py
index 7b28515b..6e3990c3 100644
--- a/src/lithic/types/account_activity_list_params.py
+++ b/src/lithic/types/account_activity_list_params.py
@@ -44,6 +44,7 @@ class AccountActivityListParams(TypedDict, total=False):
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
"MANAGEMENT_DISBURSEMENT",
+ "HOLD",
"PROGRAM_FUNDING",
]
"""Filter by transaction category"""
diff --git a/src/lithic/types/account_activity_list_response.py b/src/lithic/types/account_activity_list_response.py
index 33992124..8b126e38 100644
--- a/src/lithic/types/account_activity_list_response.py
+++ b/src/lithic/types/account_activity_list_response.py
@@ -4,6 +4,7 @@
from datetime import datetime
from typing_extensions import Literal, Annotated, TypeAlias
+from .hold import Hold
from .._utils import PropertyInfo
from .payment import Payment
from .._models import BaseModel
@@ -42,6 +43,7 @@ class FinancialTransaction(BaseModel):
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
"MANAGEMENT_DISBURSEMENT",
+ "HOLD",
"PROGRAM_FUNDING",
]
"""Transaction category"""
@@ -107,6 +109,7 @@ class CardTransaction(Transaction):
Payment,
ExternalPayment,
ManagementOperationTransaction,
+ Hold,
],
PropertyInfo(discriminator="family"),
]
diff --git a/src/lithic/types/account_activity_retrieve_transaction_response.py b/src/lithic/types/account_activity_retrieve_transaction_response.py
index 202fd3eb..532b7cf3 100644
--- a/src/lithic/types/account_activity_retrieve_transaction_response.py
+++ b/src/lithic/types/account_activity_retrieve_transaction_response.py
@@ -4,6 +4,7 @@
from datetime import datetime
from typing_extensions import Literal, Annotated, TypeAlias
+from .hold import Hold
from .._utils import PropertyInfo
from .payment import Payment
from .._models import BaseModel
@@ -42,6 +43,7 @@ class FinancialTransaction(BaseModel):
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
"MANAGEMENT_DISBURSEMENT",
+ "HOLD",
"PROGRAM_FUNDING",
]
"""Transaction category"""
@@ -107,6 +109,7 @@ class CardTransaction(Transaction):
Payment,
ExternalPayment,
ManagementOperationTransaction,
+ Hold,
],
PropertyInfo(discriminator="family"),
]
diff --git a/src/lithic/types/auth_rules/__init__.py b/src/lithic/types/auth_rules/__init__.py
index a580f180..71af2699 100644
--- a/src/lithic/types/auth_rules/__init__.py
+++ b/src/lithic/types/auth_rules/__init__.py
@@ -5,30 +5,36 @@
from .auth_rule import AuthRule as AuthRule
from .event_stream import EventStream as EventStream
from .report_stats import ReportStats as ReportStats
+from .rule_feature import RuleFeature as RuleFeature
from .backtest_stats import BacktestStats as BacktestStats
from .v2_list_params import V2ListParams as V2ListParams
from .v2_draft_params import V2DraftParams as V2DraftParams
from .v2_create_params import V2CreateParams as V2CreateParams
from .v2_update_params import V2UpdateParams as V2UpdateParams
from .conditional_value import ConditionalValue as ConditionalValue
+from .rule_feature_param import RuleFeatureParam as RuleFeatureParam
from .auth_rule_condition import AuthRuleCondition as AuthRuleCondition
from .conditional_attribute import ConditionalAttribute as ConditionalAttribute
from .conditional_operation import ConditionalOperation as ConditionalOperation
from .velocity_limit_params import VelocityLimitParams as VelocityLimitParams
from .velocity_limit_period import VelocityLimitPeriod as VelocityLimitPeriod
from .v2_list_results_params import V2ListResultsParams as V2ListResultsParams
+from .velocity_limit_filters import VelocityLimitFilters as VelocityLimitFilters
from .conditional_value_param import ConditionalValueParam as ConditionalValueParam
from .merchant_lock_parameters import MerchantLockParameters as MerchantLockParameters
from .v2_list_results_response import V2ListResultsResponse as V2ListResultsResponse
from .auth_rule_condition_param import AuthRuleConditionParam as AuthRuleConditionParam
from .v2_retrieve_report_params import V2RetrieveReportParams as V2RetrieveReportParams
+from .typescript_code_parameters import TypescriptCodeParameters as TypescriptCodeParameters
from .v2_retrieve_features_params import V2RetrieveFeaturesParams as V2RetrieveFeaturesParams
from .v2_retrieve_report_response import V2RetrieveReportResponse as V2RetrieveReportResponse
from .velocity_limit_params_param import VelocityLimitParamsParam as VelocityLimitParamsParam
from .velocity_limit_period_param import VelocityLimitPeriodParam as VelocityLimitPeriodParam
from .conditional_block_parameters import ConditionalBlockParameters as ConditionalBlockParameters
+from .velocity_limit_filters_param import VelocityLimitFiltersParam as VelocityLimitFiltersParam
from .v2_retrieve_features_response import V2RetrieveFeaturesResponse as V2RetrieveFeaturesResponse
from .merchant_lock_parameters_param import MerchantLockParametersParam as MerchantLockParametersParam
+from .typescript_code_parameters_param import TypescriptCodeParametersParam as TypescriptCodeParametersParam
from .conditional_3ds_action_parameters import Conditional3DSActionParameters as Conditional3DSActionParameters
from .conditional_ach_action_parameters import ConditionalACHActionParameters as ConditionalACHActionParameters
from .conditional_block_parameters_param import ConditionalBlockParametersParam as ConditionalBlockParametersParam
diff --git a/src/lithic/types/auth_rules/auth_rule.py b/src/lithic/types/auth_rules/auth_rule.py
index 3708f7e1..f85d7c04 100644
--- a/src/lithic/types/auth_rules/auth_rule.py
+++ b/src/lithic/types/auth_rules/auth_rule.py
@@ -7,6 +7,7 @@
from .event_stream import EventStream
from .velocity_limit_params import VelocityLimitParams
from .merchant_lock_parameters import MerchantLockParameters
+from .typescript_code_parameters import TypescriptCodeParameters
from .conditional_block_parameters import ConditionalBlockParameters
from .conditional_3ds_action_parameters import Conditional3DSActionParameters
from .conditional_ach_action_parameters import ConditionalACHActionParameters
@@ -23,6 +24,7 @@
ConditionalAuthorizationActionParameters,
ConditionalACHActionParameters,
ConditionalTokenizationActionParameters,
+ TypescriptCodeParameters,
]
@@ -45,13 +47,34 @@ class CurrentVersion(BaseModel):
ConditionalAuthorizationActionParameters,
ConditionalACHActionParameters,
ConditionalTokenizationActionParameters,
+ TypescriptCodeParameters,
]
class DraftVersion(BaseModel):
+ error: Optional[str] = None
+ """An error message if the draft version failed compilation.
+
+ Populated when `state` is `ERROR`, `null` otherwise.
+ """
+
parameters: DraftVersionParameters
"""Parameters for the Auth Rule"""
+ state: Literal["PENDING", "SHADOWING", "ERROR"]
+ """The state of the draft version.
+
+ Most rules are created synchronously and the state is immediately `SHADOWING`.
+ Rules backed by TypeScript code are compiled asynchronously — the state starts
+ as `PENDING` and transitions to `SHADOWING` on success or `ERROR` on failure.
+
+ - `PENDING`: Compilation of the rule is in progress (TypeScript rules only).
+ - `SHADOWING`: The draft version is ready and evaluating in shadow mode
+ alongside the current active version. It can be promoted to the active
+ version.
+ - `ERROR`: Compilation of the rule failed. Check the `error` field for details.
+ """
+
version: int
"""
The version of the rule, this is incremented whenever the rule's parameters
@@ -94,7 +117,7 @@ class AuthRule(BaseModel):
state: Literal["ACTIVE", "INACTIVE"]
"""The state of the Auth Rule"""
- type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"]
+ type: Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"]
"""The type of Auth Rule.
For certain rule types, this determines the event stream during which it will be
@@ -107,6 +130,8 @@ class AuthRule(BaseModel):
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
"""
excluded_card_tokens: Optional[List[str]] = None
diff --git a/src/lithic/types/auth_rules/rule_feature.py b/src/lithic/types/auth_rules/rule_feature.py
new file mode 100644
index 00000000..40fffc14
--- /dev/null
+++ b/src/lithic/types/auth_rules/rule_feature.py
@@ -0,0 +1,96 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from ..._models import BaseModel
+from .velocity_limit_period import VelocityLimitPeriod
+from .velocity_limit_filters import VelocityLimitFilters
+
+__all__ = [
+ "RuleFeature",
+ "AuthorizationFeature",
+ "AuthenticationFeature",
+ "TokenizationFeature",
+ "ACHReceiptFeature",
+ "CardFeature",
+ "AccountHolderFeature",
+ "IPMetadataFeature",
+ "SpendVelocityFeature",
+]
+
+
+class AuthorizationFeature(BaseModel):
+ type: Literal["AUTHORIZATION"]
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+class AuthenticationFeature(BaseModel):
+ type: Literal["AUTHENTICATION"]
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+class TokenizationFeature(BaseModel):
+ type: Literal["TOKENIZATION"]
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+class ACHReceiptFeature(BaseModel):
+ type: Literal["ACH_RECEIPT"]
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+class CardFeature(BaseModel):
+ type: Literal["CARD"]
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+class AccountHolderFeature(BaseModel):
+ type: Literal["ACCOUNT_HOLDER"]
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+class IPMetadataFeature(BaseModel):
+ type: Literal["IP_METADATA"]
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+class SpendVelocityFeature(BaseModel):
+ period: VelocityLimitPeriod
+ """Velocity over the current day since 00:00 / 12 AM in Eastern Time"""
+
+ scope: Literal["CARD", "ACCOUNT"]
+ """The scope the velocity is calculated for"""
+
+ type: Literal["SPEND_VELOCITY"]
+
+ filters: Optional[VelocityLimitFilters] = None
+
+ name: Optional[str] = None
+ """The variable name for this feature in the rule function signature"""
+
+
+RuleFeature: TypeAlias = Union[
+ AuthorizationFeature,
+ AuthenticationFeature,
+ TokenizationFeature,
+ ACHReceiptFeature,
+ CardFeature,
+ AccountHolderFeature,
+ IPMetadataFeature,
+ SpendVelocityFeature,
+]
diff --git a/src/lithic/types/auth_rules/rule_feature_param.py b/src/lithic/types/auth_rules/rule_feature_param.py
new file mode 100644
index 00000000..0d32b726
--- /dev/null
+++ b/src/lithic/types/auth_rules/rule_feature_param.py
@@ -0,0 +1,97 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+from .velocity_limit_period_param import VelocityLimitPeriodParam
+from .velocity_limit_filters_param import VelocityLimitFiltersParam
+
+__all__ = [
+ "RuleFeatureParam",
+ "AuthorizationFeature",
+ "AuthenticationFeature",
+ "TokenizationFeature",
+ "ACHReceiptFeature",
+ "CardFeature",
+ "AccountHolderFeature",
+ "IPMetadataFeature",
+ "SpendVelocityFeature",
+]
+
+
+class AuthorizationFeature(TypedDict, total=False):
+ type: Required[Literal["AUTHORIZATION"]]
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+class AuthenticationFeature(TypedDict, total=False):
+ type: Required[Literal["AUTHENTICATION"]]
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+class TokenizationFeature(TypedDict, total=False):
+ type: Required[Literal["TOKENIZATION"]]
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+class ACHReceiptFeature(TypedDict, total=False):
+ type: Required[Literal["ACH_RECEIPT"]]
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+class CardFeature(TypedDict, total=False):
+ type: Required[Literal["CARD"]]
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+class AccountHolderFeature(TypedDict, total=False):
+ type: Required[Literal["ACCOUNT_HOLDER"]]
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+class IPMetadataFeature(TypedDict, total=False):
+ type: Required[Literal["IP_METADATA"]]
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+class SpendVelocityFeature(TypedDict, total=False):
+ period: Required[VelocityLimitPeriodParam]
+ """Velocity over the current day since 00:00 / 12 AM in Eastern Time"""
+
+ scope: Required[Literal["CARD", "ACCOUNT"]]
+ """The scope the velocity is calculated for"""
+
+ type: Required[Literal["SPEND_VELOCITY"]]
+
+ filters: VelocityLimitFiltersParam
+
+ name: str
+ """The variable name for this feature in the rule function signature"""
+
+
+RuleFeatureParam: TypeAlias = Union[
+ AuthorizationFeature,
+ AuthenticationFeature,
+ TokenizationFeature,
+ ACHReceiptFeature,
+ CardFeature,
+ AccountHolderFeature,
+ IPMetadataFeature,
+ SpendVelocityFeature,
+]
diff --git a/src/lithic/types/auth_rules/typescript_code_parameters.py b/src/lithic/types/auth_rules/typescript_code_parameters.py
new file mode 100644
index 00000000..d80a49db
--- /dev/null
+++ b/src/lithic/types/auth_rules/typescript_code_parameters.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ..._models import BaseModel
+from .rule_feature import RuleFeature
+
+__all__ = ["TypescriptCodeParameters"]
+
+
+class TypescriptCodeParameters(BaseModel):
+ """Parameters for defining a TypeScript code rule"""
+
+ code: str
+ """The TypeScript source code of the rule.
+
+ Must define a `rule()` function that accepts the declared features as positional
+ arguments (in the same order as the `features` array) and returns an array of
+ actions.
+ """
+
+ features: List[RuleFeature]
+ """Features available to the TypeScript code at evaluation time"""
diff --git a/src/lithic/types/auth_rules/typescript_code_parameters_param.py b/src/lithic/types/auth_rules/typescript_code_parameters_param.py
new file mode 100644
index 00000000..3871954d
--- /dev/null
+++ b/src/lithic/types/auth_rules/typescript_code_parameters_param.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, TypedDict
+
+from .rule_feature_param import RuleFeatureParam
+
+__all__ = ["TypescriptCodeParametersParam"]
+
+
+class TypescriptCodeParametersParam(TypedDict, total=False):
+ """Parameters for defining a TypeScript code rule"""
+
+ code: Required[str]
+ """The TypeScript source code of the rule.
+
+ Must define a `rule()` function that accepts the declared features as positional
+ arguments (in the same order as the `features` array) and returns an array of
+ actions.
+ """
+
+ features: Required[Iterable[RuleFeatureParam]]
+ """Features available to the TypeScript code at evaluation time"""
diff --git a/src/lithic/types/auth_rules/v2_create_params.py b/src/lithic/types/auth_rules/v2_create_params.py
index 2af4efd9..3cbae7f4 100644
--- a/src/lithic/types/auth_rules/v2_create_params.py
+++ b/src/lithic/types/auth_rules/v2_create_params.py
@@ -9,6 +9,7 @@
from .event_stream import EventStream
from .velocity_limit_params_param import VelocityLimitParamsParam
from .merchant_lock_parameters_param import MerchantLockParametersParam
+from .typescript_code_parameters_param import TypescriptCodeParametersParam
from .conditional_block_parameters_param import ConditionalBlockParametersParam
from .conditional_3ds_action_parameters_param import Conditional3DSActionParametersParam
from .conditional_ach_action_parameters_param import ConditionalACHActionParametersParam
@@ -30,7 +31,9 @@ class AccountLevelRule(TypedDict, total=False):
parameters: Required[AccountLevelRuleParameters]
"""Parameters for the Auth Rule"""
- type: Required[Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"]]
+ type: Required[
+ Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"]
+ ]
"""The type of Auth Rule.
For certain rule types, this determines the event stream during which it will be
@@ -43,6 +46,8 @@ class AccountLevelRule(TypedDict, total=False):
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
"""
account_tokens: SequenceNotStr[str]
@@ -66,6 +71,7 @@ class AccountLevelRule(TypedDict, total=False):
ConditionalAuthorizationActionParametersParam,
ConditionalACHActionParametersParam,
ConditionalTokenizationActionParametersParam,
+ TypescriptCodeParametersParam,
]
@@ -76,7 +82,9 @@ class CardLevelRule(TypedDict, total=False):
parameters: Required[CardLevelRuleParameters]
"""Parameters for the Auth Rule"""
- type: Required[Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"]]
+ type: Required[
+ Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"]
+ ]
"""The type of Auth Rule.
For certain rule types, this determines the event stream during which it will be
@@ -89,6 +97,8 @@ class CardLevelRule(TypedDict, total=False):
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
"""
event_stream: EventStream
@@ -106,6 +116,7 @@ class CardLevelRule(TypedDict, total=False):
ConditionalAuthorizationActionParametersParam,
ConditionalACHActionParametersParam,
ConditionalTokenizationActionParametersParam,
+ TypescriptCodeParametersParam,
]
@@ -116,7 +127,9 @@ class ProgramLevelRule(TypedDict, total=False):
program_level: Required[bool]
"""Whether the Auth Rule applies to all authorizations on the card program."""
- type: Required[Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION"]]
+ type: Required[
+ Literal["CONDITIONAL_BLOCK", "VELOCITY_LIMIT", "MERCHANT_LOCK", "CONDITIONAL_ACTION", "TYPESCRIPT_CODE"]
+ ]
"""The type of Auth Rule.
For certain rule types, this determines the event stream during which it will be
@@ -129,6 +142,8 @@ class ProgramLevelRule(TypedDict, total=False):
- `MERCHANT_LOCK`: AUTHORIZATION event stream.
- `CONDITIONAL_ACTION`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
+ - `TYPESCRIPT_CODE`: AUTHORIZATION, THREE_DS_AUTHENTICATION, TOKENIZATION,
+ ACH_CREDIT_RECEIPT, or ACH_DEBIT_RECEIPT event stream.
"""
event_stream: EventStream
@@ -149,6 +164,7 @@ class ProgramLevelRule(TypedDict, total=False):
ConditionalAuthorizationActionParametersParam,
ConditionalACHActionParametersParam,
ConditionalTokenizationActionParametersParam,
+ TypescriptCodeParametersParam,
]
V2CreateParams: TypeAlias = Union[AccountLevelRule, CardLevelRule, ProgramLevelRule]
diff --git a/src/lithic/types/auth_rules/v2_draft_params.py b/src/lithic/types/auth_rules/v2_draft_params.py
index 2352a6b7..2b0d4363 100644
--- a/src/lithic/types/auth_rules/v2_draft_params.py
+++ b/src/lithic/types/auth_rules/v2_draft_params.py
@@ -7,6 +7,7 @@
from .velocity_limit_params_param import VelocityLimitParamsParam
from .merchant_lock_parameters_param import MerchantLockParametersParam
+from .typescript_code_parameters_param import TypescriptCodeParametersParam
from .conditional_block_parameters_param import ConditionalBlockParametersParam
from .conditional_3ds_action_parameters_param import Conditional3DSActionParametersParam
from .conditional_ach_action_parameters_param import ConditionalACHActionParametersParam
@@ -29,4 +30,5 @@ class V2DraftParams(TypedDict, total=False):
ConditionalAuthorizationActionParametersParam,
ConditionalACHActionParametersParam,
ConditionalTokenizationActionParametersParam,
+ TypescriptCodeParametersParam,
]
diff --git a/src/lithic/types/auth_rules/v2_retrieve_features_response.py b/src/lithic/types/auth_rules/v2_retrieve_features_response.py
index 708a3fdc..4bfe4037 100644
--- a/src/lithic/types/auth_rules/v2_retrieve_features_response.py
+++ b/src/lithic/types/auth_rules/v2_retrieve_features_response.py
@@ -1,69 +1,14 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import List
from datetime import datetime
from typing_extensions import Literal
from ..._models import BaseModel
from .velocity_limit_period import VelocityLimitPeriod
+from .velocity_limit_filters import VelocityLimitFilters
-__all__ = ["V2RetrieveFeaturesResponse", "Feature", "FeatureFilters", "FeatureValue"]
-
-
-class FeatureFilters(BaseModel):
- exclude_countries: Optional[List[str]] = None
- """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation.
-
- Transactions matching any of the provided will be excluded from the calculated
- velocity.
- """
-
- exclude_mccs: Optional[List[str]] = None
- """Merchant Category Codes to exclude from the velocity calculation.
-
- Transactions matching this MCC will be excluded from the calculated velocity.
- """
-
- include_countries: Optional[List[str]] = None
- """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation.
-
- Transactions not matching any of the provided will not be included in the
- calculated velocity.
- """
-
- include_mccs: Optional[List[str]] = None
- """Merchant Category Codes to include in the velocity calculation.
-
- Transactions not matching this MCC will not be included in the calculated
- velocity.
- """
-
- include_pan_entry_modes: Optional[
- List[
- Literal[
- "AUTO_ENTRY",
- "BAR_CODE",
- "CONTACTLESS",
- "CREDENTIAL_ON_FILE",
- "ECOMMERCE",
- "ERROR_KEYED",
- "ERROR_MAGNETIC_STRIPE",
- "ICC",
- "KEY_ENTERED",
- "MAGNETIC_STRIPE",
- "MANUAL",
- "OCR",
- "SECURE_CARDLESS",
- "UNSPECIFIED",
- "UNKNOWN",
- ]
- ]
- ] = None
- """PAN entry modes to include in the velocity calculation.
-
- Transactions not matching any of the provided will not be included in the
- calculated velocity.
- """
+__all__ = ["V2RetrieveFeaturesResponse", "Feature", "FeatureValue"]
class FeatureValue(BaseModel):
@@ -82,7 +27,7 @@ class FeatureValue(BaseModel):
class Feature(BaseModel):
- filters: FeatureFilters
+ filters: VelocityLimitFilters
period: VelocityLimitPeriod
"""Velocity over the current day since 00:00 / 12 AM in Eastern Time"""
diff --git a/src/lithic/types/auth_rules/velocity_limit_filters.py b/src/lithic/types/auth_rules/velocity_limit_filters.py
new file mode 100644
index 00000000..97bded04
--- /dev/null
+++ b/src/lithic/types/auth_rules/velocity_limit_filters.py
@@ -0,0 +1,64 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["VelocityLimitFilters"]
+
+
+class VelocityLimitFilters(BaseModel):
+ exclude_countries: Optional[List[str]] = None
+ """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation.
+
+ Transactions matching any of the provided will be excluded from the calculated
+ velocity.
+ """
+
+ exclude_mccs: Optional[List[str]] = None
+ """Merchant Category Codes to exclude from the velocity calculation.
+
+ Transactions matching this MCC will be excluded from the calculated velocity.
+ """
+
+ include_countries: Optional[List[str]] = None
+ """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation.
+
+ Transactions not matching any of the provided will not be included in the
+ calculated velocity.
+ """
+
+ include_mccs: Optional[List[str]] = None
+ """Merchant Category Codes to include in the velocity calculation.
+
+ Transactions not matching this MCC will not be included in the calculated
+ velocity.
+ """
+
+ include_pan_entry_modes: Optional[
+ List[
+ Literal[
+ "AUTO_ENTRY",
+ "BAR_CODE",
+ "CONTACTLESS",
+ "CREDENTIAL_ON_FILE",
+ "ECOMMERCE",
+ "ERROR_KEYED",
+ "ERROR_MAGNETIC_STRIPE",
+ "ICC",
+ "KEY_ENTERED",
+ "MAGNETIC_STRIPE",
+ "MANUAL",
+ "OCR",
+ "SECURE_CARDLESS",
+ "UNSPECIFIED",
+ "UNKNOWN",
+ ]
+ ]
+ ] = None
+ """PAN entry modes to include in the velocity calculation.
+
+ Transactions not matching any of the provided will not be included in the
+ calculated velocity.
+ """
diff --git a/src/lithic/types/auth_rules/velocity_limit_filters_param.py b/src/lithic/types/auth_rules/velocity_limit_filters_param.py
new file mode 100644
index 00000000..e9a3498b
--- /dev/null
+++ b/src/lithic/types/auth_rules/velocity_limit_filters_param.py
@@ -0,0 +1,66 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from typing_extensions import Literal, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["VelocityLimitFiltersParam"]
+
+
+class VelocityLimitFiltersParam(TypedDict, total=False):
+ exclude_countries: Optional[SequenceNotStr[str]]
+ """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation.
+
+ Transactions matching any of the provided will be excluded from the calculated
+ velocity.
+ """
+
+ exclude_mccs: Optional[SequenceNotStr[str]]
+ """Merchant Category Codes to exclude from the velocity calculation.
+
+ Transactions matching this MCC will be excluded from the calculated velocity.
+ """
+
+ include_countries: Optional[SequenceNotStr[str]]
+ """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation.
+
+ Transactions not matching any of the provided will not be included in the
+ calculated velocity.
+ """
+
+ include_mccs: Optional[SequenceNotStr[str]]
+ """Merchant Category Codes to include in the velocity calculation.
+
+ Transactions not matching this MCC will not be included in the calculated
+ velocity.
+ """
+
+ include_pan_entry_modes: Optional[
+ List[
+ Literal[
+ "AUTO_ENTRY",
+ "BAR_CODE",
+ "CONTACTLESS",
+ "CREDENTIAL_ON_FILE",
+ "ECOMMERCE",
+ "ERROR_KEYED",
+ "ERROR_MAGNETIC_STRIPE",
+ "ICC",
+ "KEY_ENTERED",
+ "MAGNETIC_STRIPE",
+ "MANUAL",
+ "OCR",
+ "SECURE_CARDLESS",
+ "UNSPECIFIED",
+ "UNKNOWN",
+ ]
+ ]
+ ]
+ """PAN entry modes to include in the velocity calculation.
+
+ Transactions not matching any of the provided will not be included in the
+ calculated velocity.
+ """
diff --git a/src/lithic/types/auth_rules/velocity_limit_params.py b/src/lithic/types/auth_rules/velocity_limit_params.py
index fbbe32c9..061a8de7 100644
--- a/src/lithic/types/auth_rules/velocity_limit_params.py
+++ b/src/lithic/types/auth_rules/velocity_limit_params.py
@@ -1,68 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import Optional
from typing_extensions import Literal
from ..._models import BaseModel
from .velocity_limit_period import VelocityLimitPeriod
+from .velocity_limit_filters import VelocityLimitFilters
-__all__ = ["VelocityLimitParams", "Filters"]
-
-
-class Filters(BaseModel):
- exclude_countries: Optional[List[str]] = None
- """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation.
-
- Transactions matching any of the provided will be excluded from the calculated
- velocity.
- """
-
- exclude_mccs: Optional[List[str]] = None
- """Merchant Category Codes to exclude from the velocity calculation.
-
- Transactions matching this MCC will be excluded from the calculated velocity.
- """
-
- include_countries: Optional[List[str]] = None
- """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation.
-
- Transactions not matching any of the provided will not be included in the
- calculated velocity.
- """
-
- include_mccs: Optional[List[str]] = None
- """Merchant Category Codes to include in the velocity calculation.
-
- Transactions not matching this MCC will not be included in the calculated
- velocity.
- """
-
- include_pan_entry_modes: Optional[
- List[
- Literal[
- "AUTO_ENTRY",
- "BAR_CODE",
- "CONTACTLESS",
- "CREDENTIAL_ON_FILE",
- "ECOMMERCE",
- "ERROR_KEYED",
- "ERROR_MAGNETIC_STRIPE",
- "ICC",
- "KEY_ENTERED",
- "MAGNETIC_STRIPE",
- "MANUAL",
- "OCR",
- "SECURE_CARDLESS",
- "UNSPECIFIED",
- "UNKNOWN",
- ]
- ]
- ] = None
- """PAN entry modes to include in the velocity calculation.
-
- Transactions not matching any of the provided will not be included in the
- calculated velocity.
- """
+__all__ = ["VelocityLimitParams"]
class VelocityLimitParams(BaseModel):
@@ -72,7 +17,7 @@ class VelocityLimitParams(BaseModel):
scope: Literal["CARD", "ACCOUNT"]
"""The scope the velocity is calculated for"""
- filters: Optional[Filters] = None
+ filters: Optional[VelocityLimitFilters] = None
limit_amount: Optional[int] = None
"""
diff --git a/src/lithic/types/auth_rules/velocity_limit_params_param.py b/src/lithic/types/auth_rules/velocity_limit_params_param.py
index 1bee3cbb..e91557fa 100644
--- a/src/lithic/types/auth_rules/velocity_limit_params_param.py
+++ b/src/lithic/types/auth_rules/velocity_limit_params_param.py
@@ -2,69 +2,13 @@
from __future__ import annotations
-from typing import List, Optional
+from typing import Optional
from typing_extensions import Literal, Required, TypedDict
-from ..._types import SequenceNotStr
from .velocity_limit_period_param import VelocityLimitPeriodParam
+from .velocity_limit_filters_param import VelocityLimitFiltersParam
-__all__ = ["VelocityLimitParamsParam", "Filters"]
-
-
-class Filters(TypedDict, total=False):
- exclude_countries: Optional[SequenceNotStr[str]]
- """ISO-3166-1 alpha-3 Country Codes to exclude from the velocity calculation.
-
- Transactions matching any of the provided will be excluded from the calculated
- velocity.
- """
-
- exclude_mccs: Optional[SequenceNotStr[str]]
- """Merchant Category Codes to exclude from the velocity calculation.
-
- Transactions matching this MCC will be excluded from the calculated velocity.
- """
-
- include_countries: Optional[SequenceNotStr[str]]
- """ISO-3166-1 alpha-3 Country Codes to include in the velocity calculation.
-
- Transactions not matching any of the provided will not be included in the
- calculated velocity.
- """
-
- include_mccs: Optional[SequenceNotStr[str]]
- """Merchant Category Codes to include in the velocity calculation.
-
- Transactions not matching this MCC will not be included in the calculated
- velocity.
- """
-
- include_pan_entry_modes: Optional[
- List[
- Literal[
- "AUTO_ENTRY",
- "BAR_CODE",
- "CONTACTLESS",
- "CREDENTIAL_ON_FILE",
- "ECOMMERCE",
- "ERROR_KEYED",
- "ERROR_MAGNETIC_STRIPE",
- "ICC",
- "KEY_ENTERED",
- "MAGNETIC_STRIPE",
- "MANUAL",
- "OCR",
- "SECURE_CARDLESS",
- "UNSPECIFIED",
- "UNKNOWN",
- ]
- ]
- ]
- """PAN entry modes to include in the velocity calculation.
-
- Transactions not matching any of the provided will not be included in the
- calculated velocity.
- """
+__all__ = ["VelocityLimitParamsParam"]
class VelocityLimitParamsParam(TypedDict, total=False):
@@ -74,7 +18,7 @@ class VelocityLimitParamsParam(TypedDict, total=False):
scope: Required[Literal["CARD", "ACCOUNT"]]
"""The scope the velocity is calculated for"""
- filters: Filters
+ filters: VelocityLimitFiltersParam
limit_amount: Optional[int]
"""
diff --git a/src/lithic/types/financial_account.py b/src/lithic/types/financial_account.py
index 92e7ddd4..f15dfccd 100644
--- a/src/lithic/types/financial_account.py
+++ b/src/lithic/types/financial_account.py
@@ -69,6 +69,7 @@ class FinancialAccount(BaseModel):
"PROGRAM_RECEIVABLES",
"COLLECTION",
"PROGRAM_BANK_ACCOUNTS_PAYABLE",
+ "EARLY_DIRECT_DEPOSIT_FLOAT",
]
updated: datetime
diff --git a/src/lithic/types/financial_account_list_params.py b/src/lithic/types/financial_account_list_params.py
index 0228f2b6..20b2605f 100644
--- a/src/lithic/types/financial_account_list_params.py
+++ b/src/lithic/types/financial_account_list_params.py
@@ -14,5 +14,5 @@ class FinancialAccountListParams(TypedDict, total=False):
business_account_token: str
"""List financial accounts for a given business_account_token"""
- type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY"]
+ type: Literal["ISSUING", "OPERATING", "RESERVE", "SECURITY", "EARLY_DIRECT_DEPOSIT_FLOAT"]
"""List financial accounts of a given type"""
diff --git a/src/lithic/types/financial_accounts/statements/statement_line_items.py b/src/lithic/types/financial_accounts/statements/statement_line_items.py
index c1816c30..98b9cf97 100644
--- a/src/lithic/types/financial_accounts/statements/statement_line_items.py
+++ b/src/lithic/types/financial_accounts/statements/statement_line_items.py
@@ -36,6 +36,7 @@ class Data(BaseModel):
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
"MANAGEMENT_DISBURSEMENT",
+ "HOLD",
"PROGRAM_FUNDING",
]
diff --git a/src/lithic/types/hold.py b/src/lithic/types/hold.py
new file mode 100644
index 00000000..448da4cc
--- /dev/null
+++ b/src/lithic/types/hold.py
@@ -0,0 +1,48 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .hold_event import HoldEvent
+
+__all__ = ["Hold"]
+
+
+class Hold(BaseModel):
+ """A hold transaction representing reserved funds on a financial account.
+
+ Holds move funds from available to pending balance in anticipation of future payments. They can be resolved via settlement (linked to payment), manual release, or expiration.
+ """
+
+ token: str
+ """Unique identifier for the transaction"""
+
+ created: datetime
+ """ISO 8601 timestamp of when the transaction was created"""
+
+ status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED", "DECLINED", "REVERSED", "CANCELED", "RETURNED"]
+ """Status of a hold transaction"""
+
+ updated: datetime
+ """ISO 8601 timestamp of when the transaction was last updated"""
+
+ currency: Optional[str] = None
+
+ events: Optional[List[HoldEvent]] = None
+
+ expiration_datetime: Optional[datetime] = None
+ """When the hold will auto-expire if not resolved"""
+
+ family: Optional[Literal["HOLD"]] = None
+ """HOLD - Hold Transaction"""
+
+ financial_account_token: Optional[str] = None
+
+ pending_amount: Optional[int] = None
+ """Current pending amount (0 when resolved)"""
+
+ result: Optional[Literal["APPROVED", "DECLINED"]] = None
+
+ user_defined_id: Optional[str] = None
diff --git a/src/lithic/types/hold_create_params.py b/src/lithic/types/hold_create_params.py
new file mode 100644
index 00000000..fb68d3de
--- /dev/null
+++ b/src/lithic/types/hold_create_params.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Optional
+from datetime import datetime
+from typing_extensions import Required, Annotated, TypedDict
+
+from .._utils import PropertyInfo
+
+__all__ = ["HoldCreateParams"]
+
+
+class HoldCreateParams(TypedDict, total=False):
+ amount: Required[int]
+ """Amount to hold in cents"""
+
+ token: str
+ """Customer-provided token for idempotency. Becomes the hold token."""
+
+ expiration_datetime: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """When the hold should auto-expire"""
+
+ memo: Optional[str]
+ """Reason for the hold"""
+
+ user_defined_id: str
+ """User-provided identifier for the hold"""
diff --git a/src/lithic/types/hold_event.py b/src/lithic/types/hold_event.py
new file mode 100644
index 00000000..b0c8d0ba
--- /dev/null
+++ b/src/lithic/types/hold_event.py
@@ -0,0 +1,35 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["HoldEvent"]
+
+
+class HoldEvent(BaseModel):
+ """Event representing a lifecycle change to a hold"""
+
+ token: str
+
+ amount: int
+ """Amount in cents"""
+
+ created: datetime
+
+ detailed_results: List[Literal["APPROVED", "INSUFFICIENT_FUNDS"]]
+
+ memo: Optional[str] = None
+
+ result: Literal["APPROVED", "DECLINED"]
+
+ settling_transaction_token: Optional[str] = None
+ """
+ Transaction token of the payment that settled this hold (only populated for
+ HOLD_SETTLED events)
+ """
+
+ type: Literal["HOLD_INITIATED", "HOLD_VOIDED", "HOLD_EXPIRED", "HOLD_SETTLED"]
+ """Type of hold lifecycle event"""
diff --git a/src/lithic/types/hold_list_params.py b/src/lithic/types/hold_list_params.py
new file mode 100644
index 00000000..3a7cf534
--- /dev/null
+++ b/src/lithic/types/hold_list_params.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Literal, Annotated, TypedDict
+
+from .._utils import PropertyInfo
+
+__all__ = ["HoldListParams"]
+
+
+class HoldListParams(TypedDict, total=False):
+ begin: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """Date string in RFC 3339 format.
+
+ Only entries created after the specified time will be included. UTC time zone.
+ """
+
+ end: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """Date string in RFC 3339 format.
+
+ Only entries created before the specified time will be included. UTC time zone.
+ """
+
+ ending_before: str
+ """A cursor representing an item's token before which a page of results should end.
+
+ Used to retrieve the previous page of results before this item.
+ """
+
+ page_size: int
+ """Page size (for pagination)."""
+
+ starting_after: str
+ """A cursor representing an item's token after which a page of results should
+ begin.
+
+ Used to retrieve the next page of results after this item.
+ """
+
+ status: Literal["PENDING", "SETTLED", "EXPIRED", "VOIDED"]
+ """Hold status to filter by."""
diff --git a/src/lithic/types/hold_void_params.py b/src/lithic/types/hold_void_params.py
new file mode 100644
index 00000000..c01ce288
--- /dev/null
+++ b/src/lithic/types/hold_void_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["HoldVoidParams"]
+
+
+class HoldVoidParams(TypedDict, total=False):
+ memo: Optional[str]
+ """Reason for voiding the hold"""
diff --git a/src/lithic/types/payment.py b/src/lithic/types/payment.py
index 686f8978..4095d525 100644
--- a/src/lithic/types/payment.py
+++ b/src/lithic/types/payment.py
@@ -185,6 +185,7 @@ class Payment(BaseModel):
"MANAGEMENT_FEE",
"MANAGEMENT_REWARD",
"MANAGEMENT_DISBURSEMENT",
+ "HOLD",
"PROGRAM_FUNDING",
]
"""Transaction category"""
diff --git a/src/lithic/types/shared/instance_financial_account_type.py b/src/lithic/types/shared/instance_financial_account_type.py
index 72a4a348..4cd1bd35 100644
--- a/src/lithic/types/shared/instance_financial_account_type.py
+++ b/src/lithic/types/shared/instance_financial_account_type.py
@@ -15,4 +15,5 @@
"PROGRAM_RECEIVABLES",
"COLLECTION",
"PROGRAM_BANK_ACCOUNTS_PAYABLE",
+ "EARLY_DIRECT_DEPOSIT_FLOAT",
]
diff --git a/tests/api_resources/test_holds.py b/tests/api_resources/test_holds.py
new file mode 100644
index 00000000..c2bf4f08
--- /dev/null
+++ b/tests/api_resources/test_holds.py
@@ -0,0 +1,412 @@
+# 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
+from tests.utils import assert_matches_type
+from lithic.types import Hold
+from lithic._utils import parse_datetime
+from lithic.pagination import SyncCursorPage, AsyncCursorPage
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestHolds:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Lithic) -> None:
+ hold = client.holds.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Lithic) -> None:
+ hold = client.holds.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ expiration_datetime=parse_datetime("2019-12-27T18:11:19.117Z"),
+ memo="memo",
+ user_defined_id="user_defined_id",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Lithic) -> None:
+ response = client.holds.with_raw_response.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Lithic) -> None:
+ with client.holds.with_streaming_response.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_create(self, client: Lithic) -> None:
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''"
+ ):
+ client.holds.with_raw_response.create(
+ financial_account_token="",
+ amount=1,
+ )
+
+ @parametrize
+ def test_method_retrieve(self, client: Lithic) -> None:
+ hold = client.holds.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_raw_response_retrieve(self, client: Lithic) -> None:
+ response = client.holds.with_raw_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Lithic) -> None:
+ with client.holds.with_streaming_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_retrieve(self, client: Lithic) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"):
+ client.holds.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Lithic) -> None:
+ hold = client.holds.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(SyncCursorPage[Hold], hold, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Lithic) -> None:
+ hold = client.holds.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ begin=parse_datetime("2019-12-27T18:11:19.117Z"),
+ end=parse_datetime("2019-12-27T18:11:19.117Z"),
+ ending_before="ending_before",
+ page_size=1,
+ starting_after="starting_after",
+ status="PENDING",
+ )
+ assert_matches_type(SyncCursorPage[Hold], hold, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Lithic) -> None:
+ response = client.holds.with_raw_response.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(SyncCursorPage[Hold], hold, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Lithic) -> None:
+ with client.holds.with_streaming_response.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = response.parse()
+ assert_matches_type(SyncCursorPage[Hold], hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Lithic) -> None:
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''"
+ ):
+ client.holds.with_raw_response.list(
+ financial_account_token="",
+ )
+
+ @parametrize
+ def test_method_void(self, client: Lithic) -> None:
+ hold = client.holds.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_method_void_with_all_params(self, client: Lithic) -> None:
+ hold = client.holds.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ memo="memo",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_raw_response_void(self, client: Lithic) -> None:
+ response = client.holds.with_raw_response.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ def test_streaming_response_void(self, client: Lithic) -> None:
+ with client.holds.with_streaming_response.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_void(self, client: Lithic) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"):
+ client.holds.with_raw_response.void(
+ hold_token="",
+ )
+
+
+class TestAsyncHolds:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncLithic) -> None:
+ hold = await async_client.holds.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncLithic) -> None:
+ hold = await async_client.holds.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ expiration_datetime=parse_datetime("2019-12-27T18:11:19.117Z"),
+ memo="memo",
+ user_defined_id="user_defined_id",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncLithic) -> None:
+ response = await async_client.holds.with_raw_response.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncLithic) -> None:
+ async with async_client.holds.with_streaming_response.create(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ amount=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = await response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_create(self, async_client: AsyncLithic) -> None:
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''"
+ ):
+ await async_client.holds.with_raw_response.create(
+ financial_account_token="",
+ amount=1,
+ )
+
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncLithic) -> None:
+ hold = await async_client.holds.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncLithic) -> None:
+ response = await async_client.holds.with_raw_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncLithic) -> None:
+ async with async_client.holds.with_streaming_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = await response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_retrieve(self, async_client: AsyncLithic) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"):
+ await async_client.holds.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncLithic) -> None:
+ hold = await async_client.holds.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncLithic) -> None:
+ hold = await async_client.holds.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ begin=parse_datetime("2019-12-27T18:11:19.117Z"),
+ end=parse_datetime("2019-12-27T18:11:19.117Z"),
+ ending_before="ending_before",
+ page_size=1,
+ starting_after="starting_after",
+ status="PENDING",
+ )
+ assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncLithic) -> None:
+ response = await async_client.holds.with_raw_response.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncLithic) -> None:
+ async with async_client.holds.with_streaming_response.list(
+ financial_account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = await response.parse()
+ assert_matches_type(AsyncCursorPage[Hold], hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncLithic) -> None:
+ with pytest.raises(
+ ValueError, match=r"Expected a non-empty value for `financial_account_token` but received ''"
+ ):
+ await async_client.holds.with_raw_response.list(
+ financial_account_token="",
+ )
+
+ @parametrize
+ async def test_method_void(self, async_client: AsyncLithic) -> None:
+ hold = await async_client.holds.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_method_void_with_all_params(self, async_client: AsyncLithic) -> None:
+ hold = await async_client.holds.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ memo="memo",
+ )
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_raw_response_void(self, async_client: AsyncLithic) -> None:
+ response = await async_client.holds.with_raw_response.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ hold = response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_void(self, async_client: AsyncLithic) -> None:
+ async with async_client.holds.with_streaming_response.void(
+ hold_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ hold = await response.parse()
+ assert_matches_type(Hold, hold, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_void(self, async_client: AsyncLithic) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `hold_token` but received ''"):
+ await async_client.holds.with_raw_response.void(
+ hold_token="",
+ )