diff --git a/.spec-sha b/.spec-sha index 7dd08d4..2767676 100644 --- a/.spec-sha +++ b/.spec-sha @@ -1 +1 @@ -6ace098c56527cf0a0e5018b67ec454412ee6926 +fde7e27884fc5355f46c368a3688c1653f937a2d diff --git a/src/onepin/.fern/metadata.json b/src/onepin/.fern/metadata.json index 6f11267..da28c6e 100644 --- a/src/onepin/.fern/metadata.json +++ b/src/onepin/.fern/metadata.json @@ -30,7 +30,7 @@ } ] }, - "originGitCommit": "9e634eff3eb65ab32b4a77b6fee5e0d27aa126cf", + "originGitCommit": "8161f2e78f880139a10f4fbd560a506103452095", "originGitCommitIsDirty": false, "invokedBy": "ci", "ciProvider": "github" diff --git a/src/onepin/__init__.py b/src/onepin/__init__.py index 3fa3327..1178a5d 100644 --- a/src/onepin/__init__.py +++ b/src/onepin/__init__.py @@ -98,6 +98,7 @@ NumericOption, PaginationMeta, PlanLimits, + PlanLimitsCreditsRenewal, PlanTier, PortOut, PronunciationSuggestion, @@ -192,6 +193,9 @@ WorkflowRunOverviewValidatorOut, WorkflowRunOverviewValidatorOutStatus, WorkflowRunOverviewWorkflowOut, + WorkflowRunSinkOutputDelivery, + WorkflowRunSinkOutputDeliveryCheck, + WorkflowRunSinkOutputLine, WorkflowRunSinkOutputOut, WorkflowRunStartIn, WorkflowRunStatusOut, @@ -368,6 +372,7 @@ "OnepinClient": "._client", "PaginationMeta": ".types", "PlanLimits": ".types", + "PlanLimitsCreditsRenewal": ".types", "PlanTier": ".types", "PortOut": ".types", "PronunciationSuggestion": ".types", @@ -473,6 +478,9 @@ "WorkflowRunOverviewValidatorOut": ".types", "WorkflowRunOverviewValidatorOutStatus": ".types", "WorkflowRunOverviewWorkflowOut": ".types", + "WorkflowRunSinkOutputDelivery": ".types", + "WorkflowRunSinkOutputDeliveryCheck": ".types", + "WorkflowRunSinkOutputLine": ".types", "WorkflowRunSinkOutputOut": ".types", "WorkflowRunStartIn": ".types", "WorkflowRunStatusOut": ".types", @@ -639,6 +647,7 @@ def __dir__(): "OnepinClient", "PaginationMeta", "PlanLimits", + "PlanLimitsCreditsRenewal", "PlanTier", "PortOut", "PronunciationSuggestion", @@ -744,6 +753,9 @@ def __dir__(): "WorkflowRunOverviewValidatorOut", "WorkflowRunOverviewValidatorOutStatus", "WorkflowRunOverviewWorkflowOut", + "WorkflowRunSinkOutputDelivery", + "WorkflowRunSinkOutputDeliveryCheck", + "WorkflowRunSinkOutputLine", "WorkflowRunSinkOutputOut", "WorkflowRunStartIn", "WorkflowRunStatusOut", diff --git a/src/onepin/dictionary/types/list_dictionary_entries_api_v1dictionary_get_request_language.py b/src/onepin/dictionary/types/list_dictionary_entries_api_v1dictionary_get_request_language.py index a062a7d..225635d 100644 --- a/src/onepin/dictionary/types/list_dictionary_entries_api_v1dictionary_get_request_language.py +++ b/src/onepin/dictionary/types/list_dictionary_entries_api_v1dictionary_get_request_language.py @@ -3,5 +3,6 @@ import typing ListDictionaryEntriesApiV1DictionaryGetRequestLanguage = typing.Union[ - typing.Literal["de-de", "en-gb", "en-us", "es-es", "fr-fr", "it-it", "ja-jp", "ko-kr", "pt-br", "zh-cn"], typing.Any + typing.Literal["de-de", "en-gb", "en-us", "es-es", "es-mx", "fr-fr", "ja-jp", "ko-kr", "pt-br", "pt-pt", "zh-cn"], + typing.Any, ] diff --git a/src/onepin/dictionary/types/search_dictionary_entries_api_v1dictionary_search_get_request_language_item.py b/src/onepin/dictionary/types/search_dictionary_entries_api_v1dictionary_search_get_request_language_item.py index 91bec6a..52ef385 100644 --- a/src/onepin/dictionary/types/search_dictionary_entries_api_v1dictionary_search_get_request_language_item.py +++ b/src/onepin/dictionary/types/search_dictionary_entries_api_v1dictionary_search_get_request_language_item.py @@ -3,5 +3,6 @@ import typing SearchDictionaryEntriesApiV1DictionarySearchGetRequestLanguageItem = typing.Union[ - typing.Literal["de-de", "en-gb", "en-us", "es-es", "fr-fr", "it-it", "ja-jp", "ko-kr", "pt-br", "zh-cn"], typing.Any + typing.Literal["de-de", "en-gb", "en-us", "es-es", "es-mx", "fr-fr", "ja-jp", "ko-kr", "pt-br", "pt-pt", "zh-cn"], + typing.Any, ] diff --git a/src/onepin/reference.md b/src/onepin/reference.md index 0271a82..ccdb161 100644 --- a/src/onepin/reference.md +++ b/src/onepin/reference.md @@ -2682,7 +2682,7 @@ client.voices.list()
-**search:** `typing.Optional[str]` — Full-text search against voice name, description, and tags. +**search:** `typing.Optional[str]` — Searches name, tags, and the voice's summary-derived descriptor text (closely tracks the served description; summary beyond 200 chars is not searched).
@@ -5316,9 +5316,14 @@ attempt a workflow run. `remaining` is a display convenience derived from settled ledger entries and may temporarily exceed `balance` while a workflow run holds an open reserve. `used` reflects credits consumed in the current billing period. `plan_grant` is the total monthly credit allowance for the -caller's plan, enabling a "X / Y used" display. `period_start` and -`period_end` mark the boundaries of the current billing window; free-tier -callers use a calendar-month boundary. +caller's plan, enabling a "X / Y used" display. `period_start` is the current +credit anchor and `period_end` is the next EXPECTED credit-reset boundary +(`period_start` + 1 month), or null when no reset is promised — Free/one-time, +unanchored, a canceling/ended entitlement, or a monthly renewal whose boundary +passed without confirmed payment. `period_end` is the expected boundary, not a +guaranteed grant time: monthly credits stay gated on successful Stripe payment. +For an annual subscriber this GET may perform idempotent maintenance, granting +any due intermediate monthly credits before returning; retries remain safe. diff --git a/src/onepin/types/__init__.py b/src/onepin/types/__init__.py index c2f5808..2d338cb 100644 --- a/src/onepin/types/__init__.py +++ b/src/onepin/types/__init__.py @@ -99,6 +99,7 @@ from .numeric_option import NumericOption from .pagination_meta import PaginationMeta from .plan_limits import PlanLimits + from .plan_limits_credits_renewal import PlanLimitsCreditsRenewal from .plan_tier import PlanTier from .port_out import PortOut from .pronunciation_suggestion import PronunciationSuggestion @@ -193,6 +194,9 @@ from .workflow_run_overview_validator_out import WorkflowRunOverviewValidatorOut from .workflow_run_overview_validator_out_status import WorkflowRunOverviewValidatorOutStatus from .workflow_run_overview_workflow_out import WorkflowRunOverviewWorkflowOut + from .workflow_run_sink_output_delivery import WorkflowRunSinkOutputDelivery + from .workflow_run_sink_output_delivery_check import WorkflowRunSinkOutputDeliveryCheck + from .workflow_run_sink_output_line import WorkflowRunSinkOutputLine from .workflow_run_sink_output_out import WorkflowRunSinkOutputOut from .workflow_run_start_in import WorkflowRunStartIn from .workflow_run_status_out import WorkflowRunStatusOut @@ -295,6 +299,7 @@ "NumericOption": ".numeric_option", "PaginationMeta": ".pagination_meta", "PlanLimits": ".plan_limits", + "PlanLimitsCreditsRenewal": ".plan_limits_credits_renewal", "PlanTier": ".plan_tier", "PortOut": ".port_out", "PronunciationSuggestion": ".pronunciation_suggestion", @@ -389,6 +394,9 @@ "WorkflowRunOverviewValidatorOut": ".workflow_run_overview_validator_out", "WorkflowRunOverviewValidatorOutStatus": ".workflow_run_overview_validator_out_status", "WorkflowRunOverviewWorkflowOut": ".workflow_run_overview_workflow_out", + "WorkflowRunSinkOutputDelivery": ".workflow_run_sink_output_delivery", + "WorkflowRunSinkOutputDeliveryCheck": ".workflow_run_sink_output_delivery_check", + "WorkflowRunSinkOutputLine": ".workflow_run_sink_output_line", "WorkflowRunSinkOutputOut": ".workflow_run_sink_output_out", "WorkflowRunStartIn": ".workflow_run_start_in", "WorkflowRunStatusOut": ".workflow_run_status_out", @@ -515,6 +523,7 @@ def __dir__(): "NumericOption", "PaginationMeta", "PlanLimits", + "PlanLimitsCreditsRenewal", "PlanTier", "PortOut", "PronunciationSuggestion", @@ -609,6 +618,9 @@ def __dir__(): "WorkflowRunOverviewValidatorOut", "WorkflowRunOverviewValidatorOutStatus", "WorkflowRunOverviewWorkflowOut", + "WorkflowRunSinkOutputDelivery", + "WorkflowRunSinkOutputDeliveryCheck", + "WorkflowRunSinkOutputLine", "WorkflowRunSinkOutputOut", "WorkflowRunStartIn", "WorkflowRunStatusOut", diff --git a/src/onepin/types/api_error_detail.py b/src/onepin/types/api_error_detail.py index 8b6b8eb..1c95971 100644 --- a/src/onepin/types/api_error_detail.py +++ b/src/onepin/types/api_error_detail.py @@ -9,6 +9,8 @@ class ApiErrorDetail(UniversalBaseModel): field: str message: str + line_numbers: typing.Optional[typing.List[int]] = None + min_chars: typing.Optional[int] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/onepin/types/balance_response.py b/src/onepin/types/balance_response.py index 18e36c6..6a77746 100644 --- a/src/onepin/types/balance_response.py +++ b/src/onepin/types/balance_response.py @@ -13,7 +13,26 @@ class BalanceResponse(UniversalBaseModel): Per-user credit balance + period anchor (consumed by GET /users/me/credits). """ - balance: int + balance: int = pydantic.Field() + """ + Total spendable credits = monthly_balance + free_balance. + """ + + monthly_balance: typing.Optional[int] = pydantic.Field(default=None) + """ + Expiring bucket: the current paid cycle's allowance, replaced each renewal. 0 on Free. + """ + + free_balance: typing.Optional[int] = pydantic.Field(default=None) + """ + Lifetime bucket: the one-time Free grant. Never expires; spent last (after monthly). + """ + + free_grant: typing.Optional[int] = pydantic.Field(default=None) + """ + All-time ceiling of the lifetime free bucket. + """ + used: typing.Optional[int] = pydantic.Field(default=None) """ Ledger-derived credits used in the current billing period. @@ -24,10 +43,28 @@ class BalanceResponse(UniversalBaseModel): Ledger-derived settled credits remaining for display only. Excludes in-flight open reserves, so this may exceed `balance` while a workflow is executing. Use `balance` for gate decisions. """ - period_start: typing.Optional[dt.datetime] = None - period_end: typing.Optional[dt.datetime] = None + period_start: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Start of the current credit period (the stored credit anchor). Null on Free/unanchored accounts. + """ + + period_end: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Next EXPECTED credit-reset boundary (`period_start` + 1 calendar month), or null when no reset is currently promised: Free/one-time or unanchored accounts, a canceling/ended entitlement with no future grant, or a monthly renewal whose boundary has already passed without confirmed payment. This is the expected boundary, not a guaranteed grant time — monthly credits (including an annual subscription's renewal) stay gated on successful Stripe payment and may become available shortly after this time. An annual subscription's intermediate monthly boundaries are deterministic and are granted on access. Distinct from `CustomerSubscriptionResponse.current_period_end`, which remains the Stripe billing/entitlement boundary and must not be used as the credit-refresh time. + """ + plan_grant: int plan_tier: PlanTier + overage_rate_cents_per_credit: typing.Optional[float] = None + overage_cents: typing.Optional[int] = pydantic.Field(default=None) + """ + Overage billed so far this billing cycle, in cents. + """ + + credits_absorbed: typing.Optional[float] = pydantic.Field(default=None) + """ + Total credits discounted by floor-rounding this billing period. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/onepin/types/estimate_response.py b/src/onepin/types/estimate_response.py index d17cae6..bdede5b 100644 --- a/src/onepin/types/estimate_response.py +++ b/src/onepin/types/estimate_response.py @@ -22,6 +22,9 @@ class EstimateResponse(UniversalBaseModel): current_balance: int deficit_at_max: int can_run: bool + overage_rate_cents_per_credit: typing.Optional[float] = None + will_incur_overage: typing.Optional[bool] = None + estimated_overage_cents: typing.Optional[int] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/onepin/types/plan_limits.py b/src/onepin/types/plan_limits.py index 71c2c19..95d541c 100644 --- a/src/onepin/types/plan_limits.py +++ b/src/onepin/types/plan_limits.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .plan_limits_credits_renewal import PlanLimitsCreditsRenewal class PlanLimits(UniversalBaseModel): @@ -18,6 +19,9 @@ class PlanLimits(UniversalBaseModel): retention_days: typing.Optional[int] = None byok_enabled: typing.Optional[bool] = None auto_fix_enabled: typing.Optional[bool] = None + credits_renewal: typing.Optional[PlanLimitsCreditsRenewal] = None + downloads_enabled: typing.Optional[bool] = None + overage_rate_cents_per_credit: typing.Optional[float] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/onepin/types/plan_limits_credits_renewal.py b/src/onepin/types/plan_limits_credits_renewal.py new file mode 100644 index 0000000..29af1b6 --- /dev/null +++ b/src/onepin/types/plan_limits_credits_renewal.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PlanLimitsCreditsRenewal = typing.Union[typing.Literal["monthly", "one_time"], typing.Any] diff --git a/src/onepin/types/voice_out.py b/src/onepin/types/voice_out.py index c4e7610..3f736aa 100644 --- a/src/onepin/types/voice_out.py +++ b/src/onepin/types/voice_out.py @@ -73,11 +73,6 @@ class VoiceOut(UniversalBaseModel): Freeform keyword tags for filtering and search. """ - descriptor: typing.Optional[str] = pydantic.Field(default=None) - """ - Short one-line voice personality descriptor. - """ - uses_count: typing.Optional[int] = pydantic.Field(default=None) """ Number of times this voice has been used in workflow runs across the platform. diff --git a/src/onepin/types/voice_similar_out.py b/src/onepin/types/voice_similar_out.py index d20d6fe..bc97998 100644 --- a/src/onepin/types/voice_similar_out.py +++ b/src/onepin/types/voice_similar_out.py @@ -73,11 +73,6 @@ class VoiceSimilarOut(UniversalBaseModel): Freeform keyword tags for filtering and search. """ - descriptor: typing.Optional[str] = pydantic.Field(default=None) - """ - Short one-line voice personality descriptor. - """ - uses_count: typing.Optional[int] = pydantic.Field(default=None) """ Number of times this voice has been used in workflow runs across the platform. diff --git a/src/onepin/types/workflow_run_detail_out.py b/src/onepin/types/workflow_run_detail_out.py index f018add..8d4d115 100644 --- a/src/onepin/types/workflow_run_detail_out.py +++ b/src/onepin/types/workflow_run_detail_out.py @@ -36,6 +36,11 @@ class WorkflowRunDetailOut(UniversalBaseModel): has_export: typing.Optional[bool] = None triggered_by: typing.Optional[TriggeredByOut] = None credits: typing.Optional[int] = None + credits_absorbed: typing.Optional[float] = pydantic.Field(default=None) + """ + Credits discounted by floor-rounding for this run. This is the sub-credit remainder above the charged (floored) credits; charged credits plus this value reconstructs true cost only for fully covered, uncapped runs. Returns 0 for unsettled or legacy runs. + """ + definition_snapshot: typing.Optional[typing.Dict[str, typing.Any]] = None if IS_PYDANTIC_V2: diff --git a/src/onepin/types/workflow_run_outputs_out.py b/src/onepin/types/workflow_run_outputs_out.py index 73c4dcb..41e5554 100644 --- a/src/onepin/types/workflow_run_outputs_out.py +++ b/src/onepin/types/workflow_run_outputs_out.py @@ -11,6 +11,11 @@ class WorkflowRunOutputsOut(UniversalBaseModel): run_id: str run_status: str credits: typing.Optional[int] = None + credits_absorbed: typing.Optional[float] = pydantic.Field(default=None) + """ + Credits discounted by floor-rounding for this run. This is the sub-credit remainder above the charged (floored) credits; charged credits plus this value reconstructs true cost only for fully covered, uncapped runs. Returns 0 for unsettled or legacy runs. + """ + outputs: typing.List[WorkflowRunSinkOutputOut] if IS_PYDANTIC_V2: diff --git a/src/onepin/types/workflow_run_sink_output_delivery.py b/src/onepin/types/workflow_run_sink_output_delivery.py new file mode 100644 index 0000000..295bdfb --- /dev/null +++ b/src/onepin/types/workflow_run_sink_output_delivery.py @@ -0,0 +1,21 @@ +# 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 .workflow_run_sink_output_delivery_check import WorkflowRunSinkOutputDeliveryCheck + + +class WorkflowRunSinkOutputDelivery(UniversalBaseModel): + passed: bool + failing_checks: typing.List[WorkflowRunSinkOutputDeliveryCheck] + + 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/onepin/types/workflow_run_sink_output_delivery_check.py b/src/onepin/types/workflow_run_sink_output_delivery_check.py new file mode 100644 index 0000000..d0f2249 --- /dev/null +++ b/src/onepin/types/workflow_run_sink_output_delivery_check.py @@ -0,0 +1,22 @@ +# 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 WorkflowRunSinkOutputDeliveryCheck(UniversalBaseModel): + kind: str + label: str + score: typing.Optional[float] = None + threshold: typing.Optional[float] = None + + 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/onepin/types/workflow_run_sink_output_line.py b/src/onepin/types/workflow_run_sink_output_line.py new file mode 100644 index 0000000..cf09ceb --- /dev/null +++ b/src/onepin/types/workflow_run_sink_output_line.py @@ -0,0 +1,22 @@ +# 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 .workflow_run_sink_output_delivery import WorkflowRunSinkOutputDelivery + + +class WorkflowRunSinkOutputLine(UniversalBaseModel): + audio_files: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = None + recommended_audio_file_index: typing.Optional[int] = None + delivery: typing.Optional[WorkflowRunSinkOutputDelivery] = None + + 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/onepin/types/workflow_run_sink_output_out.py b/src/onepin/types/workflow_run_sink_output_out.py index af315b0..d3110e2 100644 --- a/src/onepin/types/workflow_run_sink_output_out.py +++ b/src/onepin/types/workflow_run_sink_output_out.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .workflow_run_sink_output_line import WorkflowRunSinkOutputLine class WorkflowRunSinkOutputOut(UniversalBaseModel): @@ -11,7 +12,7 @@ class WorkflowRunSinkOutputOut(UniversalBaseModel): node_type: str display_name: str status: str - lines: typing.List[typing.Dict[str, typing.Any]] + lines: typing.List[WorkflowRunSinkOutputLine] line_count: int truncated: bool diff --git a/src/onepin/users/client.py b/src/onepin/users/client.py index 4de6674..e2a5d91 100644 --- a/src/onepin/users/client.py +++ b/src/onepin/users/client.py @@ -42,9 +42,14 @@ def get_my_credits(self, *, request_options: typing.Optional[RequestOptions] = N settled ledger entries and may temporarily exceed `balance` while a workflow run holds an open reserve. `used` reflects credits consumed in the current billing period. `plan_grant` is the total monthly credit allowance for the - caller's plan, enabling a "X / Y used" display. `period_start` and - `period_end` mark the boundaries of the current billing window; free-tier - callers use a calendar-month boundary. + caller's plan, enabling a "X / Y used" display. `period_start` is the current + credit anchor and `period_end` is the next EXPECTED credit-reset boundary + (`period_start` + 1 month), or null when no reset is promised — Free/one-time, + unanchored, a canceling/ended entitlement, or a monthly renewal whose boundary + passed without confirmed payment. `period_end` is the expected boundary, not a + guaranteed grant time: monthly credits stay gated on successful Stripe payment. + For an annual subscriber this GET may perform idempotent maintenance, granting + any due intermediate monthly credits before returning; retries remain safe. Parameters ---------- @@ -276,9 +281,14 @@ async def get_my_credits( settled ledger entries and may temporarily exceed `balance` while a workflow run holds an open reserve. `used` reflects credits consumed in the current billing period. `plan_grant` is the total monthly credit allowance for the - caller's plan, enabling a "X / Y used" display. `period_start` and - `period_end` mark the boundaries of the current billing window; free-tier - callers use a calendar-month boundary. + caller's plan, enabling a "X / Y used" display. `period_start` is the current + credit anchor and `period_end` is the next EXPECTED credit-reset boundary + (`period_start` + 1 month), or null when no reset is promised — Free/one-time, + unanchored, a canceling/ended entitlement, or a monthly renewal whose boundary + passed without confirmed payment. `period_end` is the expected boundary, not a + guaranteed grant time: monthly credits stay gated on successful Stripe payment. + For an annual subscriber this GET may perform idempotent maintenance, granting + any due intermediate monthly credits before returning; retries remain safe. Parameters ---------- diff --git a/src/onepin/users/raw_client.py b/src/onepin/users/raw_client.py index 6da6376..d86b812 100644 --- a/src/onepin/users/raw_client.py +++ b/src/onepin/users/raw_client.py @@ -39,9 +39,14 @@ def get_my_credits( settled ledger entries and may temporarily exceed `balance` while a workflow run holds an open reserve. `used` reflects credits consumed in the current billing period. `plan_grant` is the total monthly credit allowance for the - caller's plan, enabling a "X / Y used" display. `period_start` and - `period_end` mark the boundaries of the current billing window; free-tier - callers use a calendar-month boundary. + caller's plan, enabling a "X / Y used" display. `period_start` is the current + credit anchor and `period_end` is the next EXPECTED credit-reset boundary + (`period_start` + 1 month), or null when no reset is promised — Free/one-time, + unanchored, a canceling/ended entitlement, or a monthly renewal whose boundary + passed without confirmed payment. `period_end` is the expected boundary, not a + guaranteed grant time: monthly credits stay gated on successful Stripe payment. + For an annual subscriber this GET may perform idempotent maintenance, granting + any due intermediate monthly credits before returning; retries remain safe. Parameters ---------- @@ -385,9 +390,14 @@ async def get_my_credits( settled ledger entries and may temporarily exceed `balance` while a workflow run holds an open reserve. `used` reflects credits consumed in the current billing period. `plan_grant` is the total monthly credit allowance for the - caller's plan, enabling a "X / Y used" display. `period_start` and - `period_end` mark the boundaries of the current billing window; free-tier - callers use a calendar-month boundary. + caller's plan, enabling a "X / Y used" display. `period_start` is the current + credit anchor and `period_end` is the next EXPECTED credit-reset boundary + (`period_start` + 1 month), or null when no reset is promised — Free/one-time, + unanchored, a canceling/ended entitlement, or a monthly renewal whose boundary + passed without confirmed payment. `period_end` is the expected boundary, not a + guaranteed grant time: monthly credits stay gated on successful Stripe payment. + For an annual subscriber this GET may perform idempotent maintenance, granting + any due intermediate monthly credits before returning; retries remain safe. Parameters ---------- diff --git a/src/onepin/voices/client.py b/src/onepin/voices/client.py index 8ad7f77..b9e6cf4 100644 --- a/src/onepin/voices/client.py +++ b/src/onepin/voices/client.py @@ -107,7 +107,7 @@ def list( Repeat for OR search : typing.Optional[str] - Full-text search against voice name, description, and tags. + Searches name, tags, and the voice's summary-derived descriptor text (closely tracks the served description; summary beyond 200 chars is not searched). sort : typing.Optional[typing.Sequence[ListVoicesRequestSortItem]] Repeat for multi-sort. Pairs with `order` index-wise. @@ -556,7 +556,7 @@ async def list( Repeat for OR search : typing.Optional[str] - Full-text search against voice name, description, and tags. + Searches name, tags, and the voice's summary-derived descriptor text (closely tracks the served description; summary beyond 200 chars is not searched). sort : typing.Optional[typing.Sequence[ListVoicesRequestSortItem]] Repeat for multi-sort. Pairs with `order` index-wise. diff --git a/src/onepin/voices/raw_client.py b/src/onepin/voices/raw_client.py index ecfef41..fc0752b 100644 --- a/src/onepin/voices/raw_client.py +++ b/src/onepin/voices/raw_client.py @@ -103,7 +103,7 @@ def list( Repeat for OR search : typing.Optional[str] - Full-text search against voice name, description, and tags. + Searches name, tags, and the voice's summary-derived descriptor text (closely tracks the served description; summary beyond 200 chars is not searched). sort : typing.Optional[typing.Sequence[ListVoicesRequestSortItem]] Repeat for multi-sort. Pairs with `order` index-wise. @@ -685,7 +685,7 @@ async def list( Repeat for OR search : typing.Optional[str] - Full-text search against voice name, description, and tags. + Searches name, tags, and the voice's summary-derived descriptor text (closely tracks the served description; summary beyond 200 chars is not searched). sort : typing.Optional[typing.Sequence[ListVoicesRequestSortItem]] Repeat for multi-sort. Pairs with `order` index-wise. diff --git a/src/onepin/voices/types/list_voices_request_language_item.py b/src/onepin/voices/types/list_voices_request_language_item.py index 535d427..d2a3d6f 100644 --- a/src/onepin/voices/types/list_voices_request_language_item.py +++ b/src/onepin/voices/types/list_voices_request_language_item.py @@ -3,5 +3,6 @@ import typing ListVoicesRequestLanguageItem = typing.Union[ - typing.Literal["de-de", "en-gb", "en-us", "es-es", "fr-fr", "it-it", "ja-jp", "ko-kr", "pt-br", "zh-cn"], typing.Any + typing.Literal["de-de", "en-gb", "en-us", "es-es", "es-mx", "fr-fr", "ja-jp", "ko-kr", "pt-br", "pt-pt", "zh-cn"], + typing.Any, ]