diff --git a/.fern/metadata.json b/.fern/metadata.json
index 3d72628..d6ba897 100644
--- a/.fern/metadata.json
+++ b/.fern/metadata.json
@@ -23,6 +23,6 @@
}
]
},
- "originGitCommit": "786b643cc0bf17aff1114597108246b5cf8af395",
- "sdkVersion": "1.2.4"
+ "originGitCommit": "c7ae462826a6e814bff92fd1ae9fc8c18b8359ba",
+ "sdkVersion": "1.2.5"
}
\ No newline at end of file
diff --git a/poetry.lock b/poetry.lock
index bda43d0..c2268b5 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -240,14 +240,14 @@ files = [
[[package]]
name = "certifi"
-version = "2026.5.20"
+version = "2026.6.17"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
- {file = "certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897"},
- {file = "certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d"},
+ {file = "certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db"},
+ {file = "certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432"},
]
[[package]]
diff --git a/pyproject.toml b/pyproject.toml
index 279d823..900d0e3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ dynamic = ["version"]
[tool.poetry]
name = "schematichq"
-version = "1.2.4"
+version = "1.2.5"
description = ""
readme = "README.md"
authors = []
diff --git a/reference.md b/reference.md
index c2f7baf..decafbd 100644
--- a/reference.md
+++ b/reference.md
@@ -2749,6 +2749,7 @@ client.billing.list_billing_prices(
],
interval="interval",
is_active=True,
+ plan_version_id="plan_version_id",
price=1000000,
product_id="product_id",
product_ids=[
@@ -2825,6 +2826,14 @@ client.billing.list_billing_prices(
-
+**plan_version_id:** `typing.Optional[str]` — Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
+
+
+
+
+-
+
**price:** `typing.Optional[int]`
@@ -3206,6 +3215,7 @@ client.billing.list_billing_product_prices(
],
interval="interval",
is_active=True,
+ plan_version_id="plan_version_id",
price=1000000,
product_id="product_id",
product_ids=[
@@ -3282,6 +3292,14 @@ client.billing.list_billing_product_prices(
-
+**plan_version_id:** `typing.Optional[str]` — Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
+
+
+
+
+-
+
**price:** `typing.Optional[int]`
@@ -21771,6 +21789,74 @@ client.webhooks.delete_webhook(
+
+
+
+
+client.webhooks.send_test_webhook_action(...) -> SendTestWebhookActionResponse
+
+-
+
+#### 🔌 Usage
+
+
+-
+
+
+-
+
+```python
+from schematic import Schematic
+from schematic.environment import SchematicEnvironment
+
+client = Schematic(
+ api_key="",
+ environment=SchematicEnvironment.DEFAULT,
+)
+
+client.webhooks.send_test_webhook_action(
+ webhook_id="webhook_id",
+ request_type="subscription.trial.ended",
+)
+
+```
+
+
+
+
+
+#### ⚙️ Parameters
+
+
+-
+
+
+-
+
+**webhook_id:** `str` — webhook_id
+
+
+
+
+
+-
+
+**request_type:** `WebhookRequestType`
+
+
+
+
+
+-
+
+**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+
+
+
+
+
diff --git a/src/schematic/__init__.py b/src/schematic/__init__.py
index 9b8f5c7..1072af4 100644
--- a/src/schematic/__init__.py
+++ b/src/schematic/__init__.py
@@ -82,6 +82,7 @@
CheckoutSettingsResponseData,
CheckoutSubscription,
ClerkIntegrationConfig,
+ CompanyCreditBalance,
CompanyCreditBalanceResponseData,
CompanyDetailResponseData,
CompanyEventPeriodMetricsResponseData,
@@ -353,6 +354,7 @@
SubscriptionType,
TemporaryAccessTokenResourceType,
TemporaryAccessTokenResponseData,
+ TestWebhookResponseData,
TimeSeriesGranularity,
TopFeatureByUsageResponseData,
TopFeaturesByUsageResponseData,
@@ -761,6 +763,7 @@
ListWebhookEventsResponse,
ListWebhooksParams,
ListWebhooksResponse,
+ SendTestWebhookActionResponse,
UpdateWebhookResponse,
)
_dynamic_imports: typing.Dict[str, str] = {
@@ -849,6 +852,7 @@
"CheckoutSettingsResponseData": ".types",
"CheckoutSubscription": ".types",
"ClerkIntegrationConfig": ".types",
+ "CompanyCreditBalance": ".types",
"CompanyCreditBalanceResponseData": ".types",
"CompanyDetailResponseData": ".types",
"CompanyEventPeriodMetricsResponseData": ".types",
@@ -1391,6 +1395,7 @@
"SchematicConfig": ".client",
"SchematicEnvironment": ".environment",
"SegmentStatusResp": ".types",
+ "SendTestWebhookActionResponse": ".webhooks",
"SkippedEntitlementErrorResponseData": ".types",
"SkippedEntitlementResponseData": ".types",
"SoftDeleteBillingCreditResponse": ".credits",
@@ -1403,6 +1408,7 @@
"SubscriptionType": ".types",
"TemporaryAccessTokenResourceType": ".types",
"TemporaryAccessTokenResponseData": ".types",
+ "TestWebhookResponseData": ".types",
"TimeSeriesGranularity": ".types",
"TopFeatureByUsageResponseData": ".types",
"TopFeaturesByUsageResponseData": ".types",
@@ -1610,6 +1616,7 @@ def __dir__():
"CheckoutSettingsResponseData",
"CheckoutSubscription",
"ClerkIntegrationConfig",
+ "CompanyCreditBalance",
"CompanyCreditBalanceResponseData",
"CompanyDetailResponseData",
"CompanyEventPeriodMetricsResponseData",
@@ -2152,6 +2159,7 @@ def __dir__():
"SchematicConfig",
"SchematicEnvironment",
"SegmentStatusResp",
+ "SendTestWebhookActionResponse",
"SkippedEntitlementErrorResponseData",
"SkippedEntitlementResponseData",
"SoftDeleteBillingCreditResponse",
@@ -2164,6 +2172,7 @@ def __dir__():
"SubscriptionType",
"TemporaryAccessTokenResourceType",
"TemporaryAccessTokenResponseData",
+ "TestWebhookResponseData",
"TimeSeriesGranularity",
"TopFeatureByUsageResponseData",
"TopFeaturesByUsageResponseData",
diff --git a/src/schematic/billing/client.py b/src/schematic/billing/client.py
index eb242ec..28cadde 100644
--- a/src/schematic/billing/client.py
+++ b/src/schematic/billing/client.py
@@ -792,6 +792,7 @@ def list_billing_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -823,6 +824,9 @@ def list_billing_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -868,6 +872,7 @@ def list_billing_prices(
ids=["ids"],
interval="interval",
is_active=True,
+ plan_version_id="plan_version_id",
price=1000000,
product_id="product_id",
product_ids=["product_ids"],
@@ -887,6 +892,7 @@ def list_billing_prices(
ids=ids,
interval=interval,
is_active=is_active,
+ plan_version_id=plan_version_id,
price=price,
product_id=product_id,
product_ids=product_ids,
@@ -1054,6 +1060,7 @@ def list_billing_product_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -1085,6 +1092,9 @@ def list_billing_product_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -1130,6 +1140,7 @@ def list_billing_product_prices(
ids=["ids"],
interval="interval",
is_active=True,
+ plan_version_id="plan_version_id",
price=1000000,
product_id="product_id",
product_ids=["product_ids"],
@@ -1149,6 +1160,7 @@ def list_billing_product_prices(
ids=ids,
interval=interval,
is_active=is_active,
+ plan_version_id=plan_version_id,
price=price,
product_id=product_id,
product_ids=product_ids,
@@ -2451,6 +2463,7 @@ async def list_billing_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -2482,6 +2495,9 @@ async def list_billing_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -2532,6 +2548,7 @@ async def main() -> None:
ids=["ids"],
interval="interval",
is_active=True,
+ plan_version_id="plan_version_id",
price=1000000,
product_id="product_id",
product_ids=["product_ids"],
@@ -2554,6 +2571,7 @@ async def main() -> None:
ids=ids,
interval=interval,
is_active=is_active,
+ plan_version_id=plan_version_id,
price=price,
product_id=product_id,
product_ids=product_ids,
@@ -2737,6 +2755,7 @@ async def list_billing_product_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -2768,6 +2787,9 @@ async def list_billing_product_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -2818,6 +2840,7 @@ async def main() -> None:
ids=["ids"],
interval="interval",
is_active=True,
+ plan_version_id="plan_version_id",
price=1000000,
product_id="product_id",
product_ids=["product_ids"],
@@ -2840,6 +2863,7 @@ async def main() -> None:
ids=ids,
interval=interval,
is_active=is_active,
+ plan_version_id=plan_version_id,
price=price,
product_id=product_id,
product_ids=product_ids,
diff --git a/src/schematic/billing/raw_client.py b/src/schematic/billing/raw_client.py
index 16f4a44..b485cdf 100644
--- a/src/schematic/billing/raw_client.py
+++ b/src/schematic/billing/raw_client.py
@@ -1606,6 +1606,7 @@ def list_billing_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -1637,6 +1638,9 @@ def list_billing_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -1678,6 +1682,7 @@ def list_billing_prices(
"ids": ids,
"interval": interval,
"is_active": is_active,
+ "plan_version_id": plan_version_id,
"price": price,
"product_id": product_id,
"product_ids": product_ids,
@@ -2055,6 +2060,7 @@ def list_billing_product_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -2086,6 +2092,9 @@ def list_billing_product_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -2127,6 +2136,7 @@ def list_billing_product_prices(
"ids": ids,
"interval": interval,
"is_active": is_active,
+ "plan_version_id": plan_version_id,
"price": price,
"product_id": product_id,
"product_ids": product_ids,
@@ -4507,6 +4517,7 @@ async def list_billing_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -4538,6 +4549,9 @@ async def list_billing_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -4579,6 +4593,7 @@ async def list_billing_prices(
"ids": ids,
"interval": interval,
"is_active": is_active,
+ "plan_version_id": plan_version_id,
"price": price,
"product_id": product_id,
"product_ids": product_ids,
@@ -4956,6 +4971,7 @@ async def list_billing_product_prices(
ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
interval: typing.Optional[str] = None,
is_active: typing.Optional[bool] = None,
+ plan_version_id: typing.Optional[str] = None,
price: typing.Optional[int] = None,
product_id: typing.Optional[str] = None,
product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
@@ -4987,6 +5003,9 @@ async def list_billing_product_prices(
is_active : typing.Optional[bool]
Filter for active prices on active products (defaults to true if not specified)
+ plan_version_id : typing.Optional[str]
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+
price : typing.Optional[int]
product_id : typing.Optional[str]
@@ -5028,6 +5047,7 @@ async def list_billing_product_prices(
"ids": ids,
"interval": interval,
"is_active": is_active,
+ "plan_version_id": plan_version_id,
"price": price,
"product_id": product_id,
"product_ids": product_ids,
diff --git a/src/schematic/billing/types/list_billing_prices_params.py b/src/schematic/billing/types/list_billing_prices_params.py
index efa4a69..88c83bd 100644
--- a/src/schematic/billing/types/list_billing_prices_params.py
+++ b/src/schematic/billing/types/list_billing_prices_params.py
@@ -46,6 +46,11 @@ class ListBillingPricesParams(UniversalBaseModel):
Page offset (default 0)
"""
+ plan_version_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+ """
+
price: typing.Optional[int] = None
product_id: typing.Optional[str] = None
product_ids: typing.Optional[typing.List[str]] = None
diff --git a/src/schematic/billing/types/list_billing_product_prices_params.py b/src/schematic/billing/types/list_billing_product_prices_params.py
index 8727f29..c71ca9f 100644
--- a/src/schematic/billing/types/list_billing_product_prices_params.py
+++ b/src/schematic/billing/types/list_billing_product_prices_params.py
@@ -46,6 +46,11 @@ class ListBillingProductPricesParams(UniversalBaseModel):
Page offset (default 0)
"""
+ plan_version_id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Filter for prices belonging to a specific plan version (e.g. the latest published version)
+ """
+
price: typing.Optional[int] = None
product_id: typing.Optional[str] = None
product_ids: typing.Optional[typing.List[str]] = None
diff --git a/src/schematic/core/client_wrapper.py b/src/schematic/core/client_wrapper.py
index c123af8..376eaa0 100644
--- a/src/schematic/core/client_wrapper.py
+++ b/src/schematic/core/client_wrapper.py
@@ -27,12 +27,12 @@ def get_headers(self) -> typing.Dict[str, str]:
import platform
headers: typing.Dict[str, str] = {
- "User-Agent": "schematichq/1.2.4",
+ "User-Agent": "schematichq/1.2.5",
"X-Fern-Language": "Python",
"X-Fern-Runtime": f"python/{platform.python_version()}",
"X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}",
"X-Fern-SDK-Name": "schematichq",
- "X-Fern-SDK-Version": "1.2.4",
+ "X-Fern-SDK-Version": "1.2.5",
**(self.get_custom_headers() or {}),
}
headers["X-Schematic-Api-Key"] = self.api_key
diff --git a/src/schematic/types/__init__.py b/src/schematic/types/__init__.py
index a924857..31003e4 100644
--- a/src/schematic/types/__init__.py
+++ b/src/schematic/types/__init__.py
@@ -81,6 +81,7 @@
from .checkout_settings_response_data import CheckoutSettingsResponseData
from .checkout_subscription import CheckoutSubscription
from .clerk_integration_config import ClerkIntegrationConfig
+ from .company_credit_balance import CompanyCreditBalance
from .company_credit_balance_response_data import CompanyCreditBalanceResponseData
from .company_detail_response_data import CompanyDetailResponseData
from .company_event_period_metrics_response_data import CompanyEventPeriodMetricsResponseData
@@ -354,6 +355,7 @@
from .subscription_type import SubscriptionType
from .temporary_access_token_resource_type import TemporaryAccessTokenResourceType
from .temporary_access_token_response_data import TemporaryAccessTokenResponseData
+ from .test_webhook_response_data import TestWebhookResponseData
from .time_series_granularity import TimeSeriesGranularity
from .top_feature_by_usage_response_data import TopFeatureByUsageResponseData
from .top_features_by_usage_response_data import TopFeaturesByUsageResponseData
@@ -467,6 +469,7 @@
"CheckoutSettingsResponseData": ".checkout_settings_response_data",
"CheckoutSubscription": ".checkout_subscription",
"ClerkIntegrationConfig": ".clerk_integration_config",
+ "CompanyCreditBalance": ".company_credit_balance",
"CompanyCreditBalanceResponseData": ".company_credit_balance_response_data",
"CompanyDetailResponseData": ".company_detail_response_data",
"CompanyEventPeriodMetricsResponseData": ".company_event_period_metrics_response_data",
@@ -738,6 +741,7 @@
"SubscriptionType": ".subscription_type",
"TemporaryAccessTokenResourceType": ".temporary_access_token_resource_type",
"TemporaryAccessTokenResponseData": ".temporary_access_token_response_data",
+ "TestWebhookResponseData": ".test_webhook_response_data",
"TimeSeriesGranularity": ".time_series_granularity",
"TopFeatureByUsageResponseData": ".top_feature_by_usage_response_data",
"TopFeaturesByUsageResponseData": ".top_features_by_usage_response_data",
@@ -875,6 +879,7 @@ def __dir__():
"CheckoutSettingsResponseData",
"CheckoutSubscription",
"ClerkIntegrationConfig",
+ "CompanyCreditBalance",
"CompanyCreditBalanceResponseData",
"CompanyDetailResponseData",
"CompanyEventPeriodMetricsResponseData",
@@ -1146,6 +1151,7 @@ def __dir__():
"SubscriptionType",
"TemporaryAccessTokenResourceType",
"TemporaryAccessTokenResponseData",
+ "TestWebhookResponseData",
"TimeSeriesGranularity",
"TopFeatureByUsageResponseData",
"TopFeaturesByUsageResponseData",
diff --git a/src/schematic/types/account_member_permission.py b/src/schematic/types/account_member_permission.py
index a05bbef..693e716 100644
--- a/src/schematic/types/account_member_permission.py
+++ b/src/schematic/types/account_member_permission.py
@@ -4,7 +4,6 @@
AccountMemberPermission = typing.Union[
typing.Literal[
- "billing_credits_edit",
"companies_edit",
"company_users_edit",
"components_edit",
diff --git a/src/schematic/types/check_flags_response_data.py b/src/schematic/types/check_flags_response_data.py
index 5c84d91..c804a4a 100644
--- a/src/schematic/types/check_flags_response_data.py
+++ b/src/schematic/types/check_flags_response_data.py
@@ -5,10 +5,16 @@
import pydantic
from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
from .check_flag_response_data import CheckFlagResponseData
+from .company_credit_balance import CompanyCreditBalance
from .datastream_company_plan import DatastreamCompanyPlan
class CheckFlagsResponseData(UniversalBaseModel):
+ credit_balances: typing.Optional[typing.Dict[str, CompanyCreditBalance]] = pydantic.Field(default=None)
+ """
+ Lease-aware credit balances keyed by credit ID, covering every credit type the company holds a balance in
+ """
+
flags: typing.List[CheckFlagResponseData]
plan: typing.Optional[DatastreamCompanyPlan] = None
diff --git a/src/schematic/types/company_credit_balance.py b/src/schematic/types/company_credit_balance.py
new file mode 100644
index 0000000..472e0db
--- /dev/null
+++ b/src/schematic/types/company_credit_balance.py
@@ -0,0 +1,32 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class CompanyCreditBalance(UniversalBaseModel):
+ remaining: float = pydantic.Field()
+ """
+ Remaining credit, excluding any open lease hold (the value SDKs gate on)
+ """
+
+ reserved: float = pydantic.Field()
+ """
+ Amount held by the company's open credit lease, 0 when none is open
+ """
+
+ settled: float = pydantic.Field()
+ """
+ Spendable balance including the open lease hold (remaining + reserved)
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/schematic/types/company_subscription_response_data.py b/src/schematic/types/company_subscription_response_data.py
index 80ecdb7..91c1c3a 100644
--- a/src/schematic/types/company_subscription_response_data.py
+++ b/src/schematic/types/company_subscription_response_data.py
@@ -20,6 +20,7 @@ class CompanySubscriptionResponseData(UniversalBaseModel):
discounts: typing.List[BillingSubscriptionDiscountView]
expired_at: typing.Optional[dt.datetime] = None
interval: str
+ is_initial: bool
latest_invoice: typing.Optional[InvoiceResponseData] = None
payment_method: typing.Optional[PaymentMethodResponseData] = None
products: typing.List[BillingProductForSubscriptionResponseData]
diff --git a/src/schematic/types/feature_entitlement.py b/src/schematic/types/feature_entitlement.py
index a05f081..5b076e7 100644
--- a/src/schematic/types/feature_entitlement.py
+++ b/src/schematic/types/feature_entitlement.py
@@ -16,6 +16,11 @@ class FeatureEntitlement(UniversalBaseModel):
If the company has a numeric entitlement for this feature, the allocated amount
"""
+ consumption_rate: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ If the company has a credit-based entitlement for this feature, the credit cost per unit of usage
+ """
+
credit_id: typing.Optional[str] = pydantic.Field(default=None)
"""
If the company has a credit-based entitlement for this feature, the ID of the credit
@@ -51,6 +56,11 @@ class FeatureEntitlement(UniversalBaseModel):
If the feature is event-based, the name of the event tracked for usage
"""
+ event_subtype: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ For event-based or credit-metered feature entitlements, the event subtype whose usage is tracked
+ """
+
feature_id: str = pydantic.Field()
"""
The ID of the feature
diff --git a/src/schematic/types/rulesengine_feature_entitlement.py b/src/schematic/types/rulesengine_feature_entitlement.py
index b592231..f236814 100644
--- a/src/schematic/types/rulesengine_feature_entitlement.py
+++ b/src/schematic/types/rulesengine_feature_entitlement.py
@@ -16,6 +16,11 @@ class RulesengineFeatureEntitlement(UniversalBaseModel):
If the company has a numeric entitlement for this feature, the allocated amount
"""
+ consumption_rate: typing.Optional[float] = pydantic.Field(default=None)
+ """
+ If the company has a credit-based entitlement for this feature, the credit cost per unit of usage
+ """
+
credit_id: typing.Optional[str] = pydantic.Field(default=None)
"""
If the company has a credit-based entitlement for this feature, the ID of the credit
@@ -51,6 +56,11 @@ class RulesengineFeatureEntitlement(UniversalBaseModel):
If the feature is event-based, the name of the event tracked for usage
"""
+ event_subtype: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ For event-based or credit-metered feature entitlements, the event subtype whose usage is tracked
+ """
+
feature_id: str = pydantic.Field()
"""
The ID of the feature
diff --git a/src/schematic/types/test_webhook_response_data.py b/src/schematic/types/test_webhook_response_data.py
new file mode 100644
index 0000000..28cd96d
--- /dev/null
+++ b/src/schematic/types/test_webhook_response_data.py
@@ -0,0 +1,20 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class TestWebhookResponseData(UniversalBaseModel):
+ response_code: int
+ success: bool
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/schematic/webhooks/__init__.py b/src/schematic/webhooks/__init__.py
index f3b8204..fa4102f 100644
--- a/src/schematic/webhooks/__init__.py
+++ b/src/schematic/webhooks/__init__.py
@@ -19,6 +19,7 @@
ListWebhookEventsResponse,
ListWebhooksParams,
ListWebhooksResponse,
+ SendTestWebhookActionResponse,
UpdateWebhookResponse,
)
_dynamic_imports: typing.Dict[str, str] = {
@@ -34,6 +35,7 @@
"ListWebhookEventsResponse": ".types",
"ListWebhooksParams": ".types",
"ListWebhooksResponse": ".types",
+ "SendTestWebhookActionResponse": ".types",
"UpdateWebhookResponse": ".types",
}
@@ -72,5 +74,6 @@ def __dir__():
"ListWebhookEventsResponse",
"ListWebhooksParams",
"ListWebhooksResponse",
+ "SendTestWebhookActionResponse",
"UpdateWebhookResponse",
]
diff --git a/src/schematic/webhooks/client.py b/src/schematic/webhooks/client.py
index 19d4fb3..c89581f 100644
--- a/src/schematic/webhooks/client.py
+++ b/src/schematic/webhooks/client.py
@@ -17,6 +17,7 @@
from .types.get_webhook_response import GetWebhookResponse
from .types.list_webhook_events_response import ListWebhookEventsResponse
from .types.list_webhooks_response import ListWebhooksResponse
+from .types.send_test_webhook_action_response import SendTestWebhookActionResponse
from .types.update_webhook_response import UpdateWebhookResponse
# this is used as the default value for optional parameters
@@ -395,6 +396,46 @@ def delete_webhook(
_response = self._raw_client.delete_webhook(webhook_id, request_options=request_options)
return _response.data
+ def send_test_webhook_action(
+ self,
+ webhook_id: str,
+ *,
+ request_type: WebhookRequestType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SendTestWebhookActionResponse:
+ """
+ Parameters
+ ----------
+ webhook_id : str
+ webhook_id
+
+ request_type : WebhookRequestType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SendTestWebhookActionResponse
+ OK
+
+ Examples
+ --------
+ from schematic import Schematic
+
+ client = Schematic(
+ api_key="YOUR_API_KEY",
+ )
+ client.webhooks.send_test_webhook_action(
+ webhook_id="webhook_id",
+ request_type="subscription.trial.ended",
+ )
+ """
+ _response = self._raw_client.send_test_webhook_action(
+ webhook_id, request_type=request_type, request_options=request_options
+ )
+ return _response.data
+
def count_webhooks(
self,
*,
@@ -877,6 +918,54 @@ async def main() -> None:
_response = await self._raw_client.delete_webhook(webhook_id, request_options=request_options)
return _response.data
+ async def send_test_webhook_action(
+ self,
+ webhook_id: str,
+ *,
+ request_type: WebhookRequestType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> SendTestWebhookActionResponse:
+ """
+ Parameters
+ ----------
+ webhook_id : str
+ webhook_id
+
+ request_type : WebhookRequestType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ SendTestWebhookActionResponse
+ OK
+
+ Examples
+ --------
+ import asyncio
+
+ from schematic import AsyncSchematic
+
+ client = AsyncSchematic(
+ api_key="YOUR_API_KEY",
+ )
+
+
+ async def main() -> None:
+ await client.webhooks.send_test_webhook_action(
+ webhook_id="webhook_id",
+ request_type="subscription.trial.ended",
+ )
+
+
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.send_test_webhook_action(
+ webhook_id, request_type=request_type, request_options=request_options
+ )
+ return _response.data
+
async def count_webhooks(
self,
*,
diff --git a/src/schematic/webhooks/raw_client.py b/src/schematic/webhooks/raw_client.py
index 81afbe6..cd85f14 100644
--- a/src/schematic/webhooks/raw_client.py
+++ b/src/schematic/webhooks/raw_client.py
@@ -29,6 +29,7 @@
from .types.get_webhook_response import GetWebhookResponse
from .types.list_webhook_events_response import ListWebhookEventsResponse
from .types.list_webhooks_response import ListWebhooksResponse
+from .types.send_test_webhook_action_response import SendTestWebhookActionResponse
from .types.update_webhook_response import UpdateWebhookResponse
from pydantic import ValidationError
@@ -949,6 +950,119 @@ def delete_webhook(
status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
)
+ def send_test_webhook_action(
+ self,
+ webhook_id: str,
+ *,
+ request_type: WebhookRequestType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[SendTestWebhookActionResponse]:
+ """
+ Parameters
+ ----------
+ webhook_id : str
+ webhook_id
+
+ request_type : WebhookRequestType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[SendTestWebhookActionResponse]
+ OK
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"webhooks/{jsonable_encoder(webhook_id)}/test",
+ method="POST",
+ json={
+ "request_type": request_type,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ SendTestWebhookActionResponse,
+ parse_obj_as(
+ type_=SendTestWebhookActionResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise core_api_error_ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
+ )
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise core_api_error_ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
+ )
+
def count_webhooks(
self,
*,
@@ -1978,6 +2092,119 @@ async def delete_webhook(
status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
)
+ async def send_test_webhook_action(
+ self,
+ webhook_id: str,
+ *,
+ request_type: WebhookRequestType,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[SendTestWebhookActionResponse]:
+ """
+ Parameters
+ ----------
+ webhook_id : str
+ webhook_id
+
+ request_type : WebhookRequestType
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[SendTestWebhookActionResponse]
+ OK
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"webhooks/{jsonable_encoder(webhook_id)}/test",
+ method="POST",
+ json={
+ "request_type": request_type,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ SendTestWebhookActionResponse,
+ parse_obj_as(
+ type_=SendTestWebhookActionResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 401:
+ raise UnauthorizedError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ headers=dict(_response.headers),
+ body=typing.cast(
+ types_api_error_ApiError,
+ parse_obj_as(
+ type_=types_api_error_ApiError, # type: ignore
+ object_=_response.json(),
+ ),
+ ),
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise core_api_error_ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.text
+ )
+ except ValidationError as e:
+ raise ParsingError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
+ )
+ raise core_api_error_ApiError(
+ status_code=_response.status_code, headers=dict(_response.headers), body=_response_json
+ )
+
async def count_webhooks(
self,
*,
diff --git a/src/schematic/webhooks/types/__init__.py b/src/schematic/webhooks/types/__init__.py
index bff22ec..bd7dbc2 100644
--- a/src/schematic/webhooks/types/__init__.py
+++ b/src/schematic/webhooks/types/__init__.py
@@ -18,6 +18,7 @@
from .list_webhook_events_response import ListWebhookEventsResponse
from .list_webhooks_params import ListWebhooksParams
from .list_webhooks_response import ListWebhooksResponse
+ from .send_test_webhook_action_response import SendTestWebhookActionResponse
from .update_webhook_response import UpdateWebhookResponse
_dynamic_imports: typing.Dict[str, str] = {
"CountWebhookEventsParams": ".count_webhook_events_params",
@@ -32,6 +33,7 @@
"ListWebhookEventsResponse": ".list_webhook_events_response",
"ListWebhooksParams": ".list_webhooks_params",
"ListWebhooksResponse": ".list_webhooks_response",
+ "SendTestWebhookActionResponse": ".send_test_webhook_action_response",
"UpdateWebhookResponse": ".update_webhook_response",
}
@@ -70,5 +72,6 @@ def __dir__():
"ListWebhookEventsResponse",
"ListWebhooksParams",
"ListWebhooksResponse",
+ "SendTestWebhookActionResponse",
"UpdateWebhookResponse",
]
diff --git a/src/schematic/webhooks/types/send_test_webhook_action_response.py b/src/schematic/webhooks/types/send_test_webhook_action_response.py
new file mode 100644
index 0000000..c19a71e
--- /dev/null
+++ b/src/schematic/webhooks/types/send_test_webhook_action_response.py
@@ -0,0 +1,24 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from ...types.test_webhook_response_data import TestWebhookResponseData
+
+
+class SendTestWebhookActionResponse(UniversalBaseModel):
+ data: TestWebhookResponseData
+ params: typing.Dict[str, typing.Any] = pydantic.Field()
+ """
+ Input parameters
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow