"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations from autumn_sdk.types import ( BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL, UnrecognizedStr, ) from autumn_sdk.utils import FieldMetadata, HeaderMetadata import pydantic from pydantic import model_serializer from typing import List, Literal, Optional, Union from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict class CreatePlanGlobalsTypedDict(TypedDict): x_api_version: NotRequired[str] class CreatePlanGlobals(BaseModel): x_api_version: Annotated[ Optional[str], pydantic.Field(alias="x-api-version"), FieldMetadata(header=HeaderMetadata(style="simple", explode=False)), ] = "2.1" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["x-api-version"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanPriceIntervalRequest = Literal[ "one_off", "week", "month", "quarter", "semi_annual", "year", ] r"""Billing interval (e.g. 'month', 'year').""" class CreatePlanPriceRequestTypedDict(TypedDict): r"""Base recurring price for the plan. Omit for free or usage-only plans.""" amount: float r"""Base price amount for the plan.""" interval: CreatePlanPriceIntervalRequest r"""Billing interval (e.g. 'month', 'year').""" interval_count: NotRequired[float] r"""Number of intervals per billing cycle. Defaults to 1.""" class CreatePlanPriceRequest(BaseModel): r"""Base recurring price for the plan. Omit for free or usage-only plans.""" amount: float r"""Base price amount for the plan.""" interval: CreatePlanPriceIntervalRequest r"""Billing interval (e.g. 'month', 'year').""" interval_count: Optional[float] = None r"""Number of intervals per billing cycle. Defaults to 1.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["interval_count"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanResetIntervalRequest = Literal[ "one_off", "minute", "hour", "day", "week", "month", "quarter", "semi_annual", "year", ] r"""Interval at which balance resets (e.g. 'month', 'year'). For consumable features only.""" class CreatePlanResetRequestTypedDict(TypedDict): r"""Reset configuration for consumable features. Omit for non-consumable features like seats.""" interval: CreatePlanResetIntervalRequest r"""Interval at which balance resets (e.g. 'month', 'year'). For consumable features only.""" interval_count: NotRequired[float] r"""Number of intervals between resets. Defaults to 1.""" class CreatePlanResetRequest(BaseModel): r"""Reset configuration for consumable features. Omit for non-consumable features like seats.""" interval: CreatePlanResetIntervalRequest r"""Interval at which balance resets (e.g. 'month', 'year'). For consumable features only.""" interval_count: Optional[float] = None r"""Number of intervals between resets. Defaults to 1.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["interval_count"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanToRequestTypedDict = TypeAliasType( "CreatePlanToRequestTypedDict", Union[float, str] ) CreatePlanToRequest = TypeAliasType("CreatePlanToRequest", Union[float, str]) class CreatePlanTierRequestTypedDict(TypedDict): to: CreatePlanToRequestTypedDict amount: float flat_amount: NotRequired[Nullable[float]] class CreatePlanTierRequest(BaseModel): to: CreatePlanToRequest amount: float flat_amount: OptionalNullable[float] = UNSET @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["flat_amount"]) nullable_fields = set(["flat_amount"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m CreatePlanTierBehaviorRequest = Literal[ "graduated", "volume", ] CreatePlanItemPriceIntervalRequest = Literal[ "one_off", "week", "month", "quarter", "semi_annual", "year", ] r"""Billing interval. For consumable features, should match reset.interval.""" CreatePlanBillingMethodRequest = Literal[ "prepaid", "usage_based", ] r"""'prepaid' for upfront payment (seats), 'usage_based' for pay-as-you-go.""" class CreatePlanItemPriceRequestTypedDict(TypedDict): r"""Pricing for usage beyond included units. Omit for free features.""" interval: CreatePlanItemPriceIntervalRequest r"""Billing interval. For consumable features, should match reset.interval.""" billing_method: CreatePlanBillingMethodRequest r"""'prepaid' for upfront payment (seats), 'usage_based' for pay-as-you-go.""" amount: NotRequired[float] r"""Price per billing_units after included usage. Either 'amount' or 'tiers' is required.""" tiers: NotRequired[List[CreatePlanTierRequestTypedDict]] r"""Tiered pricing. Either 'amount' or 'tiers' is required.""" tier_behavior: NotRequired[CreatePlanTierBehaviorRequest] interval_count: NotRequired[float] r"""Number of intervals per billing cycle. Defaults to 1.""" billing_units: NotRequired[float] r"""Units per price increment. Usage is rounded UP when billed (e.g. billing_units=100 means 101 rounds to 200).""" max_purchase: NotRequired[float] r"""Max units purchasable beyond included. E.g. included=100, max_purchase=300 allows 400 total.""" class CreatePlanItemPriceRequest(BaseModel): r"""Pricing for usage beyond included units. Omit for free features.""" interval: CreatePlanItemPriceIntervalRequest r"""Billing interval. For consumable features, should match reset.interval.""" billing_method: CreatePlanBillingMethodRequest r"""'prepaid' for upfront payment (seats), 'usage_based' for pay-as-you-go.""" amount: Optional[float] = None r"""Price per billing_units after included usage. Either 'amount' or 'tiers' is required.""" tiers: Optional[List[CreatePlanTierRequest]] = None r"""Tiered pricing. Either 'amount' or 'tiers' is required.""" tier_behavior: Optional[CreatePlanTierBehaviorRequest] = None interval_count: Optional[float] = 1 r"""Number of intervals per billing cycle. Defaults to 1.""" billing_units: Optional[float] = 1 r"""Units per price increment. Usage is rounded UP when billed (e.g. billing_units=100 means 101 rounds to 200).""" max_purchase: Optional[float] = None r"""Max units purchasable beyond included. E.g. included=100, max_purchase=300 allows 400 total.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set( [ "amount", "tiers", "tier_behavior", "interval_count", "billing_units", "max_purchase", ] ) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanOnIncrease = Literal[ "bill_immediately", "prorate_immediately", "prorate_next_cycle", "bill_next_cycle", ] r"""Billing behavior when quantity increases mid-cycle.""" CreatePlanOnDecrease = Literal[ "prorate", "prorate_immediately", "prorate_next_cycle", "none", "no_prorations", ] r"""Credit behavior when quantity decreases mid-cycle.""" class CreatePlanProrationTypedDict(TypedDict): r"""Proration settings for prepaid features. Controls mid-cycle quantity change billing.""" on_increase: CreatePlanOnIncrease r"""Billing behavior when quantity increases mid-cycle.""" on_decrease: CreatePlanOnDecrease r"""Credit behavior when quantity decreases mid-cycle.""" class CreatePlanProration(BaseModel): r"""Proration settings for prepaid features. Controls mid-cycle quantity change billing.""" on_increase: CreatePlanOnIncrease r"""Billing behavior when quantity increases mid-cycle.""" on_decrease: CreatePlanOnDecrease r"""Credit behavior when quantity decreases mid-cycle.""" CreatePlanExpiryDurationTypeRequest = Literal[ "month", "forever", ] r"""When rolled over units expire.""" class CreatePlanRolloverRequestTypedDict(TypedDict): r"""Rollover config for unused units. If set, unused included units carry over.""" expiry_duration_type: CreatePlanExpiryDurationTypeRequest r"""When rolled over units expire.""" max: NotRequired[float] r"""Max rollover units. Omit for unlimited rollover.""" expiry_duration_length: NotRequired[float] r"""Number of periods before expiry.""" class CreatePlanRolloverRequest(BaseModel): r"""Rollover config for unused units. If set, unused included units carry over.""" expiry_duration_type: CreatePlanExpiryDurationTypeRequest r"""When rolled over units expire.""" max: Optional[float] = None r"""Max rollover units. Omit for unlimited rollover.""" expiry_duration_length: Optional[float] = None r"""Number of periods before expiry.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["max", "expiry_duration_length"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m class CreatePlanPlanItemTypedDict(TypedDict): r"""Configuration for a feature item in a plan, including usage limits, pricing, and rollover settings.""" feature_id: str r"""The ID of the feature to configure.""" included: NotRequired[float] r"""Number of free units included. Balance resets to this each interval for consumable features.""" unlimited: NotRequired[bool] r"""If true, customer has unlimited access to this feature.""" reset: NotRequired[CreatePlanResetRequestTypedDict] r"""Reset configuration for consumable features. Omit for non-consumable features like seats.""" price: NotRequired[CreatePlanItemPriceRequestTypedDict] r"""Pricing for usage beyond included units. Omit for free features.""" proration: NotRequired[CreatePlanProrationTypedDict] r"""Proration settings for prepaid features. Controls mid-cycle quantity change billing.""" rollover: NotRequired[CreatePlanRolloverRequestTypedDict] r"""Rollover config for unused units. If set, unused included units carry over.""" class CreatePlanPlanItem(BaseModel): r"""Configuration for a feature item in a plan, including usage limits, pricing, and rollover settings.""" feature_id: str r"""The ID of the feature to configure.""" included: Optional[float] = None r"""Number of free units included. Balance resets to this each interval for consumable features.""" unlimited: Optional[bool] = None r"""If true, customer has unlimited access to this feature.""" reset: Optional[CreatePlanResetRequest] = None r"""Reset configuration for consumable features. Omit for non-consumable features like seats.""" price: Optional[CreatePlanItemPriceRequest] = None r"""Pricing for usage beyond included units. Omit for free features.""" proration: Optional[CreatePlanProration] = None r"""Proration settings for prepaid features. Controls mid-cycle quantity change billing.""" rollover: Optional[CreatePlanRolloverRequest] = None r"""Rollover config for unused units. If set, unused included units carry over.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set( ["included", "unlimited", "reset", "price", "proration", "rollover"] ) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanDurationTypeRequest = Literal[ "day", "month", "year", ] r"""Unit of time for the trial ('day', 'month', 'year').""" class FreeTrialRequestTypedDict(TypedDict): r"""Free trial configuration. Customers can try this plan before being charged.""" duration_length: float r"""Number of duration_type periods the trial lasts.""" duration_type: NotRequired[CreatePlanDurationTypeRequest] r"""Unit of time for the trial ('day', 'month', 'year').""" card_required: NotRequired[bool] r"""If true, payment method required to start trial. Customer is charged after trial ends.""" class FreeTrialRequest(BaseModel): r"""Free trial configuration. Customers can try this plan before being charged.""" duration_length: float r"""Number of duration_type periods the trial lasts.""" duration_type: Optional[CreatePlanDurationTypeRequest] = "month" r"""Unit of time for the trial ('day', 'month', 'year').""" card_required: Optional[bool] = True r"""If true, payment method required to start trial. Customer is charged after trial ends.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["duration_type", "card_required"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m class CreatePlanParamsTypedDict(TypedDict): plan_id: str r"""The ID of the plan to create.""" name: str r"""Display name of the plan.""" group: NotRequired[str] r"""Group identifier for organizing related plans. Plans in the same group are mutually exclusive.""" description: NotRequired[Nullable[str]] r"""Optional description of the plan.""" add_on: NotRequired[bool] r"""If true, this plan can be attached alongside other plans. Otherwise, attaching replaces existing plans in the same group.""" auto_enable: NotRequired[bool] r"""If true, plan is automatically attached when a customer is created. Use for free tiers.""" price: NotRequired[CreatePlanPriceRequestTypedDict] r"""Base recurring price for the plan. Omit for free or usage-only plans.""" items: NotRequired[List[CreatePlanPlanItemTypedDict]] r"""Feature configurations for this plan. Each item defines included units, pricing, and reset behavior.""" free_trial: NotRequired[FreeTrialRequestTypedDict] r"""Free trial configuration. Customers can try this plan before being charged.""" class CreatePlanParams(BaseModel): plan_id: str r"""The ID of the plan to create.""" name: str r"""Display name of the plan.""" group: Optional[str] = "" r"""Group identifier for organizing related plans. Plans in the same group are mutually exclusive.""" description: OptionalNullable[str] = UNSET r"""Optional description of the plan.""" add_on: Optional[bool] = False r"""If true, this plan can be attached alongside other plans. Otherwise, attaching replaces existing plans in the same group.""" auto_enable: Optional[bool] = False r"""If true, plan is automatically attached when a customer is created. Use for free tiers.""" price: Optional[CreatePlanPriceRequest] = None r"""Base recurring price for the plan. Omit for free or usage-only plans.""" items: Optional[List[CreatePlanPlanItem]] = None r"""Feature configurations for this plan. Each item defines included units, pricing, and reset behavior.""" free_trial: Optional[FreeTrialRequest] = None r"""Free trial configuration. Customers can try this plan before being charged.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set( [ "group", "description", "add_on", "auto_enable", "price", "items", "free_trial", ] ) nullable_fields = set(["description"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m CreatePlanPriceIntervalResponse = Union[ Literal[ "one_off", "week", "month", "quarter", "semi_annual", "year", ], UnrecognizedStr, ] r"""Billing interval (e.g. 'month', 'year').""" class CreatePlanPriceDisplayTypedDict(TypedDict): r"""Display text for showing this price in pricing pages.""" primary_text: str r"""Main display text (e.g. '$10' or '100 messages').""" secondary_text: NotRequired[str] r"""Secondary display text (e.g. 'per month' or 'then $0.5 per 100').""" class CreatePlanPriceDisplay(BaseModel): r"""Display text for showing this price in pricing pages.""" primary_text: str r"""Main display text (e.g. '$10' or '100 messages').""" secondary_text: Optional[str] = None r"""Secondary display text (e.g. 'per month' or 'then $0.5 per 100').""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["secondary_text"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m class CreatePlanPriceResponseTypedDict(TypedDict): amount: float r"""Base price amount for the plan.""" interval: CreatePlanPriceIntervalResponse r"""Billing interval (e.g. 'month', 'year').""" interval_count: NotRequired[float] r"""Number of intervals per billing cycle. Defaults to 1.""" display: NotRequired[CreatePlanPriceDisplayTypedDict] r"""Display text for showing this price in pricing pages.""" class CreatePlanPriceResponse(BaseModel): amount: float r"""Base price amount for the plan.""" interval: CreatePlanPriceIntervalResponse r"""Billing interval (e.g. 'month', 'year').""" interval_count: Optional[float] = None r"""Number of intervals per billing cycle. Defaults to 1.""" display: Optional[CreatePlanPriceDisplay] = None r"""Display text for showing this price in pricing pages.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["interval_count", "display"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanType = Union[ Literal[ "static", "boolean", "single_use", "continuous_use", "credit_system", ], UnrecognizedStr, ] r"""The type of the feature""" class CreatePlanFeatureDisplayTypedDict(TypedDict): singular: str r"""The singular display name for the feature.""" plural: str r"""The plural display name for the feature.""" class CreatePlanFeatureDisplay(BaseModel): singular: str r"""The singular display name for the feature.""" plural: str r"""The plural display name for the feature.""" class CreatePlanCreditSchemaTypedDict(TypedDict): metered_feature_id: str r"""The ID of the metered feature (should be a single_use feature).""" credit_cost: float r"""The credit cost of the metered feature.""" class CreatePlanCreditSchema(BaseModel): metered_feature_id: str r"""The ID of the metered feature (should be a single_use feature).""" credit_cost: float r"""The credit cost of the metered feature.""" class CreatePlanFeatureTypedDict(TypedDict): r"""The full feature object if expanded.""" id: str r"""The ID of the feature, used to refer to it in other API calls like /track or /check.""" type: CreatePlanType r"""The type of the feature""" name: NotRequired[Nullable[str]] r"""The name of the feature.""" display: NotRequired[Nullable[CreatePlanFeatureDisplayTypedDict]] r"""Singular and plural display names for the feature.""" credit_schema: NotRequired[Nullable[List[CreatePlanCreditSchemaTypedDict]]] r"""Credit cost schema for credit system features.""" archived: NotRequired[Nullable[bool]] r"""Whether or not the feature is archived.""" class CreatePlanFeature(BaseModel): r"""The full feature object if expanded.""" id: str r"""The ID of the feature, used to refer to it in other API calls like /track or /check.""" type: CreatePlanType r"""The type of the feature""" name: OptionalNullable[str] = UNSET r"""The name of the feature.""" display: OptionalNullable[CreatePlanFeatureDisplay] = UNSET r"""Singular and plural display names for the feature.""" credit_schema: OptionalNullable[List[CreatePlanCreditSchema]] = UNSET r"""Credit cost schema for credit system features.""" archived: OptionalNullable[bool] = UNSET r"""Whether or not the feature is archived.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["name", "display", "credit_schema", "archived"]) nullable_fields = set(["name", "display", "credit_schema", "archived"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m CreatePlanResetIntervalResponse = Union[ Literal[ "one_off", "minute", "hour", "day", "week", "month", "quarter", "semi_annual", "year", ], UnrecognizedStr, ] r"""The interval at which the feature balance resets (e.g. 'month', 'year'). For consumable features, usage resets to 0 and included units are restored.""" class CreatePlanResetResponseTypedDict(TypedDict): interval: CreatePlanResetIntervalResponse r"""The interval at which the feature balance resets (e.g. 'month', 'year'). For consumable features, usage resets to 0 and included units are restored.""" interval_count: NotRequired[float] r"""Number of intervals between resets. Defaults to 1.""" class CreatePlanResetResponse(BaseModel): interval: CreatePlanResetIntervalResponse r"""The interval at which the feature balance resets (e.g. 'month', 'year'). For consumable features, usage resets to 0 and included units are restored.""" interval_count: Optional[float] = None r"""Number of intervals between resets. Defaults to 1.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["interval_count"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanToResponseTypedDict = TypeAliasType( "CreatePlanToResponseTypedDict", Union[float, str] ) CreatePlanToResponse = TypeAliasType("CreatePlanToResponse", Union[float, str]) class CreatePlanTierResponseTypedDict(TypedDict): to: CreatePlanToResponseTypedDict amount: float flat_amount: NotRequired[Nullable[float]] class CreatePlanTierResponse(BaseModel): to: CreatePlanToResponse amount: float flat_amount: OptionalNullable[float] = UNSET @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["flat_amount"]) nullable_fields = set(["flat_amount"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m CreatePlanTierBehaviorResponse = Union[ Literal[ "graduated", "volume", ], UnrecognizedStr, ] CreatePlanPriceItemIntervalResponse = Union[ Literal[ "one_off", "week", "month", "quarter", "semi_annual", "year", ], UnrecognizedStr, ] r"""Billing interval for this price. For consumable features, should match reset.interval.""" CreatePlanBillingMethodResponse = Union[ Literal[ "prepaid", "usage_based", ], UnrecognizedStr, ] r"""'prepaid' for features like seats where customers pay upfront, 'usage_based' for pay-as-you-go after included usage.""" class CreatePlanItemPriceResponseTypedDict(TypedDict): interval: CreatePlanPriceItemIntervalResponse r"""Billing interval for this price. For consumable features, should match reset.interval.""" billing_units: float r"""Number of units per price increment. Usage is rounded UP to the nearest billing_units when billed (e.g. billing_units=100 means 101 usage rounds to 200).""" billing_method: CreatePlanBillingMethodResponse r"""'prepaid' for features like seats where customers pay upfront, 'usage_based' for pay-as-you-go after included usage.""" max_purchase: Nullable[float] r"""Maximum units a customer can purchase beyond included. E.g. if included=100 and max_purchase=300, customer can use up to 400 total before usage is capped. Null for no limit.""" amount: NotRequired[float] r"""Price per billing_units after included usage is consumed. Mutually exclusive with tiers.""" tiers: NotRequired[List[CreatePlanTierResponseTypedDict]] r"""Tiered pricing configuration. Each tier's 'to' INCLUDES the included amount. Either 'tiers' or 'amount' is required.""" tier_behavior: NotRequired[CreatePlanTierBehaviorResponse] interval_count: NotRequired[float] r"""Number of intervals per billing cycle. Defaults to 1.""" class CreatePlanItemPriceResponse(BaseModel): interval: CreatePlanPriceItemIntervalResponse r"""Billing interval for this price. For consumable features, should match reset.interval.""" billing_units: float r"""Number of units per price increment. Usage is rounded UP to the nearest billing_units when billed (e.g. billing_units=100 means 101 usage rounds to 200).""" billing_method: CreatePlanBillingMethodResponse r"""'prepaid' for features like seats where customers pay upfront, 'usage_based' for pay-as-you-go after included usage.""" max_purchase: Nullable[float] r"""Maximum units a customer can purchase beyond included. E.g. if included=100 and max_purchase=300, customer can use up to 400 total before usage is capped. Null for no limit.""" amount: Optional[float] = None r"""Price per billing_units after included usage is consumed. Mutually exclusive with tiers.""" tiers: Optional[List[CreatePlanTierResponse]] = None r"""Tiered pricing configuration. Each tier's 'to' INCLUDES the included amount. Either 'tiers' or 'amount' is required.""" tier_behavior: Optional[CreatePlanTierBehaviorResponse] = None interval_count: Optional[float] = None r"""Number of intervals per billing cycle. Defaults to 1.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["amount", "tiers", "tier_behavior", "interval_count"]) nullable_fields = set(["max_purchase"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m class CreatePlanItemDisplayTypedDict(TypedDict): r"""Display text for showing this item in pricing pages.""" primary_text: str r"""Main display text (e.g. '$10' or '100 messages').""" secondary_text: NotRequired[str] r"""Secondary display text (e.g. 'per month' or 'then $0.5 per 100').""" class CreatePlanItemDisplay(BaseModel): r"""Display text for showing this item in pricing pages.""" primary_text: str r"""Main display text (e.g. '$10' or '100 messages').""" secondary_text: Optional[str] = None r"""Secondary display text (e.g. 'per month' or 'then $0.5 per 100').""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["secondary_text"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m CreatePlanExpiryDurationTypeResponse = Union[ Literal[ "month", "forever", ], UnrecognizedStr, ] r"""When rolled over units expire.""" class CreatePlanRolloverResponseTypedDict(TypedDict): r"""Rollover configuration for unused units. If set, unused included units roll over to the next period.""" max: Nullable[float] r"""Maximum rollover units. Null for unlimited rollover.""" expiry_duration_type: CreatePlanExpiryDurationTypeResponse r"""When rolled over units expire.""" expiry_duration_length: NotRequired[float] r"""Number of periods before expiry.""" class CreatePlanRolloverResponse(BaseModel): r"""Rollover configuration for unused units. If set, unused included units roll over to the next period.""" max: Nullable[float] r"""Maximum rollover units. Null for unlimited rollover.""" expiry_duration_type: CreatePlanExpiryDurationTypeResponse r"""When rolled over units expire.""" expiry_duration_length: Optional[float] = None r"""Number of periods before expiry.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["expiry_duration_length"]) nullable_fields = set(["max"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m class CreatePlanItemTypedDict(TypedDict): feature_id: str r"""The ID of the feature this item configures.""" included: float r"""Number of free units included. For consumable features, balance resets to this number each interval.""" unlimited: bool r"""Whether the customer has unlimited access to this feature.""" reset: Nullable[CreatePlanResetResponseTypedDict] r"""Reset configuration for consumable features. Null for non-consumable features like seats where usage persists across billing cycles.""" price: Nullable[CreatePlanItemPriceResponseTypedDict] r"""Pricing configuration for usage beyond included units. Null if feature is entirely free.""" feature: NotRequired[CreatePlanFeatureTypedDict] r"""The full feature object if expanded.""" display: NotRequired[CreatePlanItemDisplayTypedDict] r"""Display text for showing this item in pricing pages.""" rollover: NotRequired[CreatePlanRolloverResponseTypedDict] r"""Rollover configuration for unused units. If set, unused included units roll over to the next period.""" class CreatePlanItem(BaseModel): feature_id: str r"""The ID of the feature this item configures.""" included: float r"""Number of free units included. For consumable features, balance resets to this number each interval.""" unlimited: bool r"""Whether the customer has unlimited access to this feature.""" reset: Nullable[CreatePlanResetResponse] r"""Reset configuration for consumable features. Null for non-consumable features like seats where usage persists across billing cycles.""" price: Nullable[CreatePlanItemPriceResponse] r"""Pricing configuration for usage beyond included units. Null if feature is entirely free.""" feature: Optional[CreatePlanFeature] = None r"""The full feature object if expanded.""" display: Optional[CreatePlanItemDisplay] = None r"""Display text for showing this item in pricing pages.""" rollover: Optional[CreatePlanRolloverResponse] = None r"""Rollover configuration for unused units. If set, unused included units roll over to the next period.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["feature", "display", "rollover"]) nullable_fields = set(["reset", "price"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m CreatePlanDurationTypeResponse = Union[ Literal[ "day", "month", "year", ], UnrecognizedStr, ] r"""Unit of time for the trial duration ('day', 'month', 'year').""" class CreatePlanFreeTrialResponseTypedDict(TypedDict): r"""Free trial configuration. If set, new customers can try this plan before being charged.""" duration_length: float r"""Number of duration_type periods the trial lasts.""" duration_type: CreatePlanDurationTypeResponse r"""Unit of time for the trial duration ('day', 'month', 'year').""" card_required: bool r"""Whether a payment method is required to start the trial. If true, customer will be charged after trial ends.""" class CreatePlanFreeTrialResponse(BaseModel): r"""Free trial configuration. If set, new customers can try this plan before being charged.""" duration_length: float r"""Number of duration_type periods the trial lasts.""" duration_type: CreatePlanDurationTypeResponse r"""Unit of time for the trial duration ('day', 'month', 'year').""" card_required: bool r"""Whether a payment method is required to start the trial. If true, customer will be charged after trial ends.""" CreatePlanEnv = Union[ Literal[ "sandbox", "live", ], UnrecognizedStr, ] r"""Environment this plan belongs to ('sandbox' or 'live').""" CreatePlanScenario = Union[ Literal[ "scheduled", "active", "new", "renew", "upgrade", "downgrade", "cancel", "expired", "past_due", ], UnrecognizedStr, ] r"""The attach scenario for this customer (e.g. new_subscription, upgrade, downgrade).""" class CreatePlanCustomerEligibilityTypedDict(TypedDict): scenario: CreatePlanScenario r"""The attach scenario for this customer (e.g. new_subscription, upgrade, downgrade).""" trial_available: NotRequired[bool] r"""Whether a free trial is available for this customer.""" class CreatePlanCustomerEligibility(BaseModel): scenario: CreatePlanScenario r"""The attach scenario for this customer (e.g. new_subscription, upgrade, downgrade).""" trial_available: Optional[bool] = None r"""Whether a free trial is available for this customer.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["trial_available"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) if val != UNSET_SENTINEL: if val is not None or k not in optional_fields: m[k] = val return m class CreatePlanResponseTypedDict(TypedDict): r"""A plan defines a set of features, pricing, and entitlements that can be attached to customers.""" id: str r"""Unique identifier for the plan.""" name: str r"""Display name of the plan.""" description: Nullable[str] r"""Optional description of the plan.""" group: Nullable[str] r"""Group identifier for organizing related plans. Plans in the same group are mutually exclusive.""" version: float r"""Version number of the plan. Incremented when plan configuration changes.""" add_on: bool r"""Whether this is an add-on plan that can be attached alongside a main plan.""" auto_enable: bool r"""If true, this plan is automatically attached when a customer is created. Used for free plans.""" price: Nullable[CreatePlanPriceResponseTypedDict] r"""Base recurring price for the plan. Null for free plans or usage-only plans.""" items: List[CreatePlanItemTypedDict] r"""Feature configurations included in this plan. Each item defines included units, pricing, and reset behavior for a feature.""" created_at: float r"""Unix timestamp (ms) when the plan was created.""" env: CreatePlanEnv r"""Environment this plan belongs to ('sandbox' or 'live').""" archived: bool r"""Whether the plan is archived. Archived plans cannot be attached to new customers.""" base_variant_id: Nullable[str] r"""If this is a variant, the ID of the base plan it was created from.""" free_trial: NotRequired[CreatePlanFreeTrialResponseTypedDict] r"""Free trial configuration. If set, new customers can try this plan before being charged.""" customer_eligibility: NotRequired[CreatePlanCustomerEligibilityTypedDict] class CreatePlanResponse(BaseModel): r"""A plan defines a set of features, pricing, and entitlements that can be attached to customers.""" id: str r"""Unique identifier for the plan.""" name: str r"""Display name of the plan.""" description: Nullable[str] r"""Optional description of the plan.""" group: Nullable[str] r"""Group identifier for organizing related plans. Plans in the same group are mutually exclusive.""" version: float r"""Version number of the plan. Incremented when plan configuration changes.""" add_on: bool r"""Whether this is an add-on plan that can be attached alongside a main plan.""" auto_enable: bool r"""If true, this plan is automatically attached when a customer is created. Used for free plans.""" price: Nullable[CreatePlanPriceResponse] r"""Base recurring price for the plan. Null for free plans or usage-only plans.""" items: List[CreatePlanItem] r"""Feature configurations included in this plan. Each item defines included units, pricing, and reset behavior for a feature.""" created_at: float r"""Unix timestamp (ms) when the plan was created.""" env: CreatePlanEnv r"""Environment this plan belongs to ('sandbox' or 'live').""" archived: bool r"""Whether the plan is archived. Archived plans cannot be attached to new customers.""" base_variant_id: Nullable[str] r"""If this is a variant, the ID of the base plan it was created from.""" free_trial: Optional[CreatePlanFreeTrialResponse] = None r"""Free trial configuration. If set, new customers can try this plan before being charged.""" customer_eligibility: Optional[CreatePlanCustomerEligibility] = None @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set(["free_trial", "customer_eligibility"]) nullable_fields = set(["description", "group", "price", "base_variant_id"]) serialized = handler(self) m = {} for n, f in type(self).model_fields.items(): k = f.alias or n val = serialized.get(k) is_nullable_and_explicitly_set = ( k in nullable_fields and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member ) if val != UNSET_SENTINEL: if ( val is not None or k not in optional_fields or is_nullable_and_explicitly_set ): m[k] = val return m