diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 1269f909f..1eec10e9f 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.6.0"
+ ".": "4.7.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 7309c957c..a0aad2266 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 118
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/metronome/metronome-f7e0e0ddfc48af411be9cceb4ff2f2902fd49e10a0e37375e291c2a06a6ddf6d.yml
-openapi_spec_hash: 51a0820e0399b218d44af30e9e0cb2da
-config_hash: e73a5fed3fb2fc458b2cd21b1e3e7b91
+configured_endpoints: 115
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/metronome/metronome-f12f505faf40d5f25d74c0b5a417e2b36c7f3f9621a0e23acd3d6ec4c615443e.yml
+openapi_spec_hash: 5c1f13896608a69feebd8855703b76df
+config_hash: 6bd82f310398d5d47bcfeb8d7ed150b3
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a804df984..b8f55dd10 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# Changelog
+## 4.7.0 (2026-05-29)
+
+Full Changelog: [v4.6.0...v4.7.0](https://github.com/Metronome-Industries/metronome-python/compare/v4.6.0...v4.7.0)
+
+### Features
+
+* [LAUNCH-2814] editContract returns full edit in the response ([918e37c](https://github.com/Metronome-Industries/metronome-python/commit/918e37cf7c332247cbee157cfd027e9fe544b323))
+* [orch-1860] remove all deprecated `/payments/*` endpoints from API ([18e35ff](https://github.com/Metronome-Industries/metronome-python/commit/18e35ffc40321d898069710cca6beccc8de0bd8d))
+* create contract returns contract data ([d389dd3](https://github.com/Metronome-Industries/metronome-python/commit/d389dd34fb1fba3845e269efc7ba9e51c761840c))
+* nikku-orch-1723-update-create-contract ([55828d8](https://github.com/Metronome-Industries/metronome-python/commit/55828d8566c304e7ca8a5333dc45b3611e3c9298))
+
+
+### Chores
+
+* (internal) Add threshold balance specifier to contract create & edit, package create and both contract and package retrievals ([69b5ffe](https://github.com/Metronome-Industries/metronome-python/commit/69b5ffeeefbfccad8d0ee40d5e0abe8fff254bfc))
+
## 4.6.0 (2026-05-18)
Full Changelog: [v4.5.0...v4.6.0](https://github.com/Metronome-Industries/metronome-python/compare/v4.5.0...v4.6.0)
diff --git a/api.md b/api.md
index 2f36e2f4c..b651bace5 100644
--- a/api.md
+++ b/api.md
@@ -558,20 +558,6 @@ Methods:
- client.v1.packages.archive(\*\*params) -> PackageArchiveResponse
- client.v1.packages.list_contracts_on_package(\*\*params) -> SyncCursorPage[PackageListContractsOnPackageResponse]
-## Payments
-
-Types:
-
-```python
-from metronome.types.v1 import Payment, PaymentStatus, PaymentAttemptResponse, PaymentCancelResponse
-```
-
-Methods:
-
-- client.v1.payments.list(\*\*params) -> SyncBodyCursorPage[Payment]
-- client.v1.payments.attempt(\*\*params) -> PaymentAttemptResponse
-- client.v1.payments.cancel(\*\*params) -> PaymentCancelResponse
-
## Settings
Types:
diff --git a/pyproject.toml b/pyproject.toml
index ba1a95514..1b6a2d3b0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "metronome-sdk"
-version = "4.6.0"
+version = "4.7.0"
description = "The official Python library for the metronome API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/metronome/_version.py b/src/metronome/_version.py
index 70296be17..befc4d1fa 100644
--- a/src/metronome/_version.py
+++ b/src/metronome/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "metronome"
-__version__ = "4.6.0" # x-release-please-version
+__version__ = "4.7.0" # x-release-please-version
diff --git a/src/metronome/resources/v1/__init__.py b/src/metronome/resources/v1/__init__.py
index 1319a76f6..6dbefad8d 100644
--- a/src/metronome/resources/v1/__init__.py
+++ b/src/metronome/resources/v1/__init__.py
@@ -48,14 +48,6 @@
PackagesResourceWithStreamingResponse,
AsyncPackagesResourceWithStreamingResponse,
)
-from .payments import (
- PaymentsResource,
- AsyncPaymentsResource,
- PaymentsResourceWithRawResponse,
- AsyncPaymentsResourceWithRawResponse,
- PaymentsResourceWithStreamingResponse,
- AsyncPaymentsResourceWithStreamingResponse,
-)
from .services import (
ServicesResource,
AsyncServicesResource,
@@ -222,12 +214,6 @@
"AsyncPackagesResourceWithRawResponse",
"PackagesResourceWithStreamingResponse",
"AsyncPackagesResourceWithStreamingResponse",
- "PaymentsResource",
- "AsyncPaymentsResource",
- "PaymentsResourceWithRawResponse",
- "AsyncPaymentsResourceWithRawResponse",
- "PaymentsResourceWithStreamingResponse",
- "AsyncPaymentsResourceWithStreamingResponse",
"SettingsResource",
"AsyncSettingsResource",
"SettingsResourceWithRawResponse",
diff --git a/src/metronome/resources/v1/contracts/contracts.py b/src/metronome/resources/v1/contracts/contracts.py
index a2b334919..a18ba1bb4 100644
--- a/src/metronome/resources/v1/contracts/contracts.py
+++ b/src/metronome/resources/v1/contracts/contracts.py
@@ -153,6 +153,7 @@ def create(
scheduled_charges: Iterable[contract_create_params.ScheduledCharge] | Omit = omit,
scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit,
spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit,
+ spend_trackers: Iterable[contract_create_params.SpendTracker] | Omit = omit,
subscriptions: Iterable[contract_create_params.Subscription] | Omit = omit,
total_contract_value: float | Omit = omit,
transition: contract_create_params.Transition | Omit = omit,
@@ -335,6 +336,9 @@ def create(
after a Contract has been created. If this field is omitted, charges will appear
on a separate invoice from usage charges.
+ spend_trackers: Spend trackers to attach to this contract. Aliases must be unique within a
+ contract.
+
subscriptions: Optional list of
[subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/)
to add to the contract.
@@ -385,6 +389,7 @@ def create(
"scheduled_charges": scheduled_charges,
"scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices,
"spend_threshold_configuration": spend_threshold_configuration,
+ "spend_trackers": spend_trackers,
"subscriptions": subscriptions,
"total_contract_value": total_contract_value,
"transition": transition,
@@ -1520,6 +1525,7 @@ async def create(
scheduled_charges: Iterable[contract_create_params.ScheduledCharge] | Omit = omit,
scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit,
spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit,
+ spend_trackers: Iterable[contract_create_params.SpendTracker] | Omit = omit,
subscriptions: Iterable[contract_create_params.Subscription] | Omit = omit,
total_contract_value: float | Omit = omit,
transition: contract_create_params.Transition | Omit = omit,
@@ -1702,6 +1708,9 @@ async def create(
after a Contract has been created. If this field is omitted, charges will appear
on a separate invoice from usage charges.
+ spend_trackers: Spend trackers to attach to this contract. Aliases must be unique within a
+ contract.
+
subscriptions: Optional list of
[subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/)
to add to the contract.
@@ -1752,6 +1761,7 @@ async def create(
"scheduled_charges": scheduled_charges,
"scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices,
"spend_threshold_configuration": spend_threshold_configuration,
+ "spend_trackers": spend_trackers,
"subscriptions": subscriptions,
"total_contract_value": total_contract_value,
"transition": transition,
diff --git a/src/metronome/resources/v1/packages.py b/src/metronome/resources/v1/packages.py
index e560f8818..ba9abd01c 100644
--- a/src/metronome/resources/v1/packages.py
+++ b/src/metronome/resources/v1/packages.py
@@ -81,6 +81,7 @@ def create(
scheduled_charges: Iterable[package_create_params.ScheduledCharge] | Omit = omit,
scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit,
spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit,
+ spend_trackers: Iterable[package_create_params.SpendTracker] | Omit = omit,
subscriptions: Iterable[package_create_params.Subscription] | Omit = omit,
uniqueness_key: str | Omit = omit,
usage_statement_schedule: package_create_params.UsageStatementSchedule | Omit = omit,
@@ -197,6 +198,7 @@ def create(
"scheduled_charges": scheduled_charges,
"scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices,
"spend_threshold_configuration": spend_threshold_configuration,
+ "spend_trackers": spend_trackers,
"subscriptions": subscriptions,
"uniqueness_key": uniqueness_key,
"usage_statement_schedule": usage_statement_schedule,
@@ -365,10 +367,9 @@ def list_contracts_on_package(
### **Usage guidelines:**
- Use the **`starting_at`**, **`covering_date`**,
- and **`include_archived`** parameters to filter the list of returned contracts.
- For example, to list only currently active contracts,
- pass **`covering_date`** equal to the current time.
+ Use the **`starting_at`**, **`covering_date`**, and **`include_archived`**
+ parameters to filter the list of returned contracts. For example, to list only
+ currently active contracts, pass **`covering_date`** equal to the current time.
Args:
limit: Max number of results that should be returned
@@ -464,6 +465,7 @@ async def create(
scheduled_charges: Iterable[package_create_params.ScheduledCharge] | Omit = omit,
scheduled_charges_on_usage_invoices: Literal["ALL"] | Omit = omit,
spend_threshold_configuration: SpendThresholdConfiguration | Omit = omit,
+ spend_trackers: Iterable[package_create_params.SpendTracker] | Omit = omit,
subscriptions: Iterable[package_create_params.Subscription] | Omit = omit,
uniqueness_key: str | Omit = omit,
usage_statement_schedule: package_create_params.UsageStatementSchedule | Omit = omit,
@@ -580,6 +582,7 @@ async def create(
"scheduled_charges": scheduled_charges,
"scheduled_charges_on_usage_invoices": scheduled_charges_on_usage_invoices,
"spend_threshold_configuration": spend_threshold_configuration,
+ "spend_trackers": spend_trackers,
"subscriptions": subscriptions,
"uniqueness_key": uniqueness_key,
"usage_statement_schedule": usage_statement_schedule,
@@ -748,10 +751,9 @@ def list_contracts_on_package(
### **Usage guidelines:**
- Use the **`starting_at`**, **`covering_date`**,
- and **`include_archived`** parameters to filter the list of returned contracts.
- For example, to list only currently active contracts,
- pass **`covering_date`** equal to the current time.
+ Use the **`starting_at`**, **`covering_date`**, and **`include_archived`**
+ parameters to filter the list of returned contracts. For example, to list only
+ currently active contracts, pass **`covering_date`** equal to the current time.
Args:
limit: Max number of results that should be returned
diff --git a/src/metronome/resources/v1/payments.py b/src/metronome/resources/v1/payments.py
deleted file mode 100644
index d53ed34f0..000000000
--- a/src/metronome/resources/v1/payments.py
+++ /dev/null
@@ -1,409 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import List
-
-import httpx
-
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
-from ..._compat import cached_property
-from ...types.v1 import payment_list_params, payment_cancel_params, payment_attempt_params
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...pagination import SyncBodyCursorPage, AsyncBodyCursorPage
-from ..._base_client import AsyncPaginator, make_request_options
-from ...types.v1.payment import Payment
-from ...types.v1.payment_status import PaymentStatus
-from ...types.v1.payment_cancel_response import PaymentCancelResponse
-from ...types.v1.payment_attempt_response import PaymentAttemptResponse
-
-__all__ = ["PaymentsResource", "AsyncPaymentsResource"]
-
-
-class PaymentsResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> PaymentsResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/Metronome-Industries/metronome-python#accessing-raw-response-data-eg-headers
- """
- return PaymentsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> PaymentsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/Metronome-Industries/metronome-python#with_streaming_response
- """
- return PaymentsResourceWithStreamingResponse(self)
-
- def list(
- self,
- *,
- customer_id: str,
- invoice_id: str,
- limit: int | Omit = omit,
- next_page: str | Omit = omit,
- statuses: List[PaymentStatus] | Omit = omit,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncBodyCursorPage[Payment]:
- """
- Fetch all payment attempts for the given invoice.
-
- Args:
- limit: The maximum number of payments to return. Defaults to 25.
-
- next_page: The next page token from a previous response.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._get_api_list(
- "/v1/payments/list",
- page=SyncBodyCursorPage[Payment],
- body=maybe_transform(
- {
- "customer_id": customer_id,
- "invoice_id": invoice_id,
- "limit": limit,
- "next_page": next_page,
- "statuses": statuses,
- },
- payment_list_params.PaymentListParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- model=Payment,
- method="post",
- )
-
- def attempt(
- self,
- *,
- customer_id: str,
- invoice_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaymentAttemptResponse:
- """
- Trigger a new attempt by canceling any existing attempts for this invoice and
- creating a new Payment. This will trigger another attempt to charge the
- Customer's configured Payment Gateway. Payment can only be attempted if all of
- the following are true:
-
- - The Metronome Invoice is finalized
- - PLG Invoicing is configured for the Customer
- - You cannot attempt payments for invoices that have already been `paid` or
- `voided`.
-
- Attempting to payment on an ineligible Invoice or Customer will result in a
- `400` response.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._post(
- "/v1/payments/attempt",
- body=maybe_transform(
- {
- "customer_id": customer_id,
- "invoice_id": invoice_id,
- },
- payment_attempt_params.PaymentAttemptParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=PaymentAttemptResponse,
- )
-
- def cancel(
- self,
- *,
- customer_id: str,
- invoice_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaymentCancelResponse:
- """
- Cancel an existing payment attempt for an invoice.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._post(
- "/v1/payments/cancel",
- body=maybe_transform(
- {
- "customer_id": customer_id,
- "invoice_id": invoice_id,
- },
- payment_cancel_params.PaymentCancelParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=PaymentCancelResponse,
- )
-
-
-class AsyncPaymentsResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncPaymentsResourceWithRawResponse:
- """
- This property can be used as a prefix for any HTTP method call to return
- the raw response object instead of the parsed content.
-
- For more information, see https://www.github.com/Metronome-Industries/metronome-python#accessing-raw-response-data-eg-headers
- """
- return AsyncPaymentsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncPaymentsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/Metronome-Industries/metronome-python#with_streaming_response
- """
- return AsyncPaymentsResourceWithStreamingResponse(self)
-
- def list(
- self,
- *,
- customer_id: str,
- invoice_id: str,
- limit: int | Omit = omit,
- next_page: str | Omit = omit,
- statuses: List[PaymentStatus] | Omit = omit,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[Payment, AsyncBodyCursorPage[Payment]]:
- """
- Fetch all payment attempts for the given invoice.
-
- Args:
- limit: The maximum number of payments to return. Defaults to 25.
-
- next_page: The next page token from a previous response.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return self._get_api_list(
- "/v1/payments/list",
- page=AsyncBodyCursorPage[Payment],
- body=maybe_transform(
- {
- "customer_id": customer_id,
- "invoice_id": invoice_id,
- "limit": limit,
- "next_page": next_page,
- "statuses": statuses,
- },
- payment_list_params.PaymentListParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- model=Payment,
- method="post",
- )
-
- async def attempt(
- self,
- *,
- customer_id: str,
- invoice_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaymentAttemptResponse:
- """
- Trigger a new attempt by canceling any existing attempts for this invoice and
- creating a new Payment. This will trigger another attempt to charge the
- Customer's configured Payment Gateway. Payment can only be attempted if all of
- the following are true:
-
- - The Metronome Invoice is finalized
- - PLG Invoicing is configured for the Customer
- - You cannot attempt payments for invoices that have already been `paid` or
- `voided`.
-
- Attempting to payment on an ineligible Invoice or Customer will result in a
- `400` response.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._post(
- "/v1/payments/attempt",
- body=await async_maybe_transform(
- {
- "customer_id": customer_id,
- "invoice_id": invoice_id,
- },
- payment_attempt_params.PaymentAttemptParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=PaymentAttemptResponse,
- )
-
- async def cancel(
- self,
- *,
- customer_id: str,
- invoice_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> PaymentCancelResponse:
- """
- Cancel an existing payment attempt for an invoice.
-
- Args:
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- return await self._post(
- "/v1/payments/cancel",
- body=await async_maybe_transform(
- {
- "customer_id": customer_id,
- "invoice_id": invoice_id,
- },
- payment_cancel_params.PaymentCancelParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=PaymentCancelResponse,
- )
-
-
-class PaymentsResourceWithRawResponse:
- def __init__(self, payments: PaymentsResource) -> None:
- self._payments = payments
-
- self.list = to_raw_response_wrapper(
- payments.list,
- )
- self.attempt = to_raw_response_wrapper(
- payments.attempt,
- )
- self.cancel = to_raw_response_wrapper(
- payments.cancel,
- )
-
-
-class AsyncPaymentsResourceWithRawResponse:
- def __init__(self, payments: AsyncPaymentsResource) -> None:
- self._payments = payments
-
- self.list = async_to_raw_response_wrapper(
- payments.list,
- )
- self.attempt = async_to_raw_response_wrapper(
- payments.attempt,
- )
- self.cancel = async_to_raw_response_wrapper(
- payments.cancel,
- )
-
-
-class PaymentsResourceWithStreamingResponse:
- def __init__(self, payments: PaymentsResource) -> None:
- self._payments = payments
-
- self.list = to_streamed_response_wrapper(
- payments.list,
- )
- self.attempt = to_streamed_response_wrapper(
- payments.attempt,
- )
- self.cancel = to_streamed_response_wrapper(
- payments.cancel,
- )
-
-
-class AsyncPaymentsResourceWithStreamingResponse:
- def __init__(self, payments: AsyncPaymentsResource) -> None:
- self._payments = payments
-
- self.list = async_to_streamed_response_wrapper(
- payments.list,
- )
- self.attempt = async_to_streamed_response_wrapper(
- payments.attempt,
- )
- self.cancel = async_to_streamed_response_wrapper(
- payments.cancel,
- )
diff --git a/src/metronome/resources/v1/v1.py b/src/metronome/resources/v1/v1.py
index b8d60cfaf..33b0cc629 100644
--- a/src/metronome/resources/v1/v1.py
+++ b/src/metronome/resources/v1/v1.py
@@ -42,14 +42,6 @@
PackagesResourceWithStreamingResponse,
AsyncPackagesResourceWithStreamingResponse,
)
-from .payments import (
- PaymentsResource,
- AsyncPaymentsResource,
- PaymentsResourceWithRawResponse,
- AsyncPaymentsResourceWithRawResponse,
- PaymentsResourceWithStreamingResponse,
- AsyncPaymentsResourceWithStreamingResponse,
-)
from .services import (
ServicesResource,
AsyncServicesResource,
@@ -226,10 +218,6 @@ def contracts(self) -> ContractsResource:
def packages(self) -> PackagesResource:
return PackagesResource(self._client)
- @cached_property
- def payments(self) -> PaymentsResource:
- return PaymentsResource(self._client)
-
@cached_property
def settings(self) -> SettingsResource:
"""
@@ -347,10 +335,6 @@ def contracts(self) -> AsyncContractsResource:
def packages(self) -> AsyncPackagesResource:
return AsyncPackagesResource(self._client)
- @cached_property
- def payments(self) -> AsyncPaymentsResource:
- return AsyncPaymentsResource(self._client)
-
@cached_property
def settings(self) -> AsyncSettingsResource:
"""
@@ -471,10 +455,6 @@ def contracts(self) -> ContractsResourceWithRawResponse:
def packages(self) -> PackagesResourceWithRawResponse:
return PackagesResourceWithRawResponse(self._v1.packages)
- @cached_property
- def payments(self) -> PaymentsResourceWithRawResponse:
- return PaymentsResourceWithRawResponse(self._v1.payments)
-
@cached_property
def settings(self) -> SettingsResourceWithRawResponse:
"""
@@ -576,10 +556,6 @@ def contracts(self) -> AsyncContractsResourceWithRawResponse:
def packages(self) -> AsyncPackagesResourceWithRawResponse:
return AsyncPackagesResourceWithRawResponse(self._v1.packages)
- @cached_property
- def payments(self) -> AsyncPaymentsResourceWithRawResponse:
- return AsyncPaymentsResourceWithRawResponse(self._v1.payments)
-
@cached_property
def settings(self) -> AsyncSettingsResourceWithRawResponse:
"""
@@ -681,10 +657,6 @@ def contracts(self) -> ContractsResourceWithStreamingResponse:
def packages(self) -> PackagesResourceWithStreamingResponse:
return PackagesResourceWithStreamingResponse(self._v1.packages)
- @cached_property
- def payments(self) -> PaymentsResourceWithStreamingResponse:
- return PaymentsResourceWithStreamingResponse(self._v1.payments)
-
@cached_property
def settings(self) -> SettingsResourceWithStreamingResponse:
"""
@@ -786,10 +758,6 @@ def contracts(self) -> AsyncContractsResourceWithStreamingResponse:
def packages(self) -> AsyncPackagesResourceWithStreamingResponse:
return AsyncPackagesResourceWithStreamingResponse(self._v1.packages)
- @cached_property
- def payments(self) -> AsyncPaymentsResourceWithStreamingResponse:
- return AsyncPaymentsResourceWithStreamingResponse(self._v1.payments)
-
@cached_property
def settings(self) -> AsyncSettingsResourceWithStreamingResponse:
"""
diff --git a/src/metronome/resources/v2/contracts.py b/src/metronome/resources/v2/contracts.py
index 2c1630c08..b8333eb73 100644
--- a/src/metronome/resources/v2/contracts.py
+++ b/src/metronome/resources/v2/contracts.py
@@ -225,11 +225,13 @@ def edit(
add_revenue_system_configuration_update: contract_edit_params.AddRevenueSystemConfigurationUpdate | Omit = omit,
add_scheduled_charges: Iterable[contract_edit_params.AddScheduledCharge] | Omit = omit,
add_spend_threshold_configuration: SpendThresholdConfigurationV2 | Omit = omit,
+ add_spend_trackers: Iterable[contract_edit_params.AddSpendTracker] | Omit = omit,
add_subscriptions: Iterable[contract_edit_params.AddSubscription] | Omit = omit,
allow_contract_ending_before_finalized_invoice: bool | Omit = omit,
archive_commits: Iterable[contract_edit_params.ArchiveCommit] | Omit = omit,
archive_credits: Iterable[contract_edit_params.ArchiveCredit] | Omit = omit,
archive_scheduled_charges: Iterable[contract_edit_params.ArchiveScheduledCharge] | Omit = omit,
+ archive_spend_trackers: SequenceNotStr[str] | Omit = omit,
remove_overrides: Iterable[contract_edit_params.RemoveOverride] | Omit = omit,
uniqueness_key: str | Omit = omit,
update_commits: Iterable[contract_edit_params.UpdateCommit] | Omit = omit,
@@ -290,6 +292,9 @@ def edit(
adding a revenue system configuration to a contract that does not already have
one.
+ add_spend_trackers: Spend trackers to add to this contract. Aliases must be unique within a
+ contract.
+
add_subscriptions: Optional list of
[subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/)
to add to the contract.
@@ -305,6 +310,8 @@ def edit(
archive_scheduled_charges: IDs of scheduled charges to archive
+ archive_spend_trackers: Aliases of spend trackers to archive.
+
remove_overrides: IDs of overrides to remove
uniqueness_key: Optional uniqueness key to prevent duplicate contract edits.
@@ -354,11 +361,13 @@ def edit(
"add_revenue_system_configuration_update": add_revenue_system_configuration_update,
"add_scheduled_charges": add_scheduled_charges,
"add_spend_threshold_configuration": add_spend_threshold_configuration,
+ "add_spend_trackers": add_spend_trackers,
"add_subscriptions": add_subscriptions,
"allow_contract_ending_before_finalized_invoice": allow_contract_ending_before_finalized_invoice,
"archive_commits": archive_commits,
"archive_credits": archive_credits,
"archive_scheduled_charges": archive_scheduled_charges,
+ "archive_spend_trackers": archive_spend_trackers,
"remove_overrides": remove_overrides,
"uniqueness_key": uniqueness_key,
"update_commits": update_commits,
@@ -837,11 +846,13 @@ async def edit(
add_revenue_system_configuration_update: contract_edit_params.AddRevenueSystemConfigurationUpdate | Omit = omit,
add_scheduled_charges: Iterable[contract_edit_params.AddScheduledCharge] | Omit = omit,
add_spend_threshold_configuration: SpendThresholdConfigurationV2 | Omit = omit,
+ add_spend_trackers: Iterable[contract_edit_params.AddSpendTracker] | Omit = omit,
add_subscriptions: Iterable[contract_edit_params.AddSubscription] | Omit = omit,
allow_contract_ending_before_finalized_invoice: bool | Omit = omit,
archive_commits: Iterable[contract_edit_params.ArchiveCommit] | Omit = omit,
archive_credits: Iterable[contract_edit_params.ArchiveCredit] | Omit = omit,
archive_scheduled_charges: Iterable[contract_edit_params.ArchiveScheduledCharge] | Omit = omit,
+ archive_spend_trackers: SequenceNotStr[str] | Omit = omit,
remove_overrides: Iterable[contract_edit_params.RemoveOverride] | Omit = omit,
uniqueness_key: str | Omit = omit,
update_commits: Iterable[contract_edit_params.UpdateCommit] | Omit = omit,
@@ -902,6 +913,9 @@ async def edit(
adding a revenue system configuration to a contract that does not already have
one.
+ add_spend_trackers: Spend trackers to add to this contract. Aliases must be unique within a
+ contract.
+
add_subscriptions: Optional list of
[subscriptions](https://docs.metronome.com/manage-product-access/create-subscription/)
to add to the contract.
@@ -917,6 +931,8 @@ async def edit(
archive_scheduled_charges: IDs of scheduled charges to archive
+ archive_spend_trackers: Aliases of spend trackers to archive.
+
remove_overrides: IDs of overrides to remove
uniqueness_key: Optional uniqueness key to prevent duplicate contract edits.
@@ -966,11 +982,13 @@ async def edit(
"add_revenue_system_configuration_update": add_revenue_system_configuration_update,
"add_scheduled_charges": add_scheduled_charges,
"add_spend_threshold_configuration": add_spend_threshold_configuration,
+ "add_spend_trackers": add_spend_trackers,
"add_subscriptions": add_subscriptions,
"allow_contract_ending_before_finalized_invoice": allow_contract_ending_before_finalized_invoice,
"archive_commits": archive_commits,
"archive_credits": archive_credits,
"archive_scheduled_charges": archive_scheduled_charges,
+ "archive_spend_trackers": archive_spend_trackers,
"remove_overrides": remove_overrides,
"uniqueness_key": uniqueness_key,
"update_commits": update_commits,
diff --git a/src/metronome/types/shared/commit.py b/src/metronome/types/shared/commit.py
index 7aae25236..301a6cee7 100644
--- a/src/metronome/types/shared/commit.py
+++ b/src/metronome/types/shared/commit.py
@@ -31,6 +31,7 @@
"LedgerPostpaidCommitManualLedgerEntry",
"LedgerPostpaidCommitExpirationLedgerEntry",
"RolledOverFrom",
+ "SpendTrackerAttributes",
"SubscriptionConfig",
"SubscriptionConfigApplySeatIncreaseConfig",
]
@@ -234,6 +235,16 @@ class RolledOverFrom(BaseModel):
contract_id: str
+class SpendTrackerAttributes(BaseModel):
+ """Optional attributes controlling how this commit interacts with spend trackers."""
+
+ counts_as_discounted: bool
+ """
+ If true, this commit is included in spend trackers with discounted set to
+ DISCOUNTED_ONLY
+ """
+
+
class SubscriptionConfigApplySeatIncreaseConfig(BaseModel):
is_prorated: bool
"""Indicates whether a mid-period seat increase should be prorated."""
@@ -355,6 +366,9 @@ class Commit(BaseModel):
specifiers to contribute to a commit's or credit's drawdown.
"""
+ spend_tracker_attributes: Optional[SpendTrackerAttributes] = None
+ """Optional attributes controlling how this commit interacts with spend trackers."""
+
subscription_config: Optional[SubscriptionConfig] = None
"""
The subscription configuration for this commit, if it was generated from a
diff --git a/src/metronome/types/shared/contract.py b/src/metronome/types/shared/contract.py
index 5a4f386ac..8641a1848 100644
--- a/src/metronome/types/shared/contract.py
+++ b/src/metronome/types/shared/contract.py
@@ -16,7 +16,15 @@
from .spend_threshold_configuration import SpendThresholdConfiguration
from .prepaid_balance_threshold_configuration import PrepaidBalanceThresholdConfiguration
-__all__ = ["Contract", "Amendment", "AmendmentResellerRoyalty", "CustomerBillingProviderConfiguration"]
+__all__ = [
+ "Contract",
+ "Amendment",
+ "AmendmentResellerRoyalty",
+ "CustomerBillingProviderConfiguration",
+ "SpendTracker",
+ "SpendTrackerApplicableSpendSpecifier",
+ "SpendTrackerAccumulatedSpend",
+]
class AmendmentResellerRoyalty(BaseModel):
@@ -104,6 +112,35 @@ class CustomerBillingProviderConfiguration(BaseModel):
"""
+class SpendTrackerApplicableSpendSpecifier(BaseModel):
+ sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]
+
+ spend_type: Literal["COMMIT_PURCHASE"]
+
+ discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None
+
+
+class SpendTrackerAccumulatedSpend(BaseModel):
+ amount: float
+
+ period_ending_before: datetime
+
+ period_starting_at: datetime
+
+
+class SpendTracker(BaseModel):
+ alias: str
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier]
+
+ credit_type_id: str
+
+ reset_frequency: Literal["BILLING_PERIOD"]
+
+ accumulated_spend: Optional[SpendTrackerAccumulatedSpend] = None
+
+
class Contract(BaseModel):
id: str
@@ -143,6 +180,9 @@ class Contract(BaseModel):
spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None
+ spend_trackers: Optional[List[SpendTracker]] = None
+ """Spend trackers attached to this contract."""
+
subscriptions: Optional[List[Subscription]] = None
"""List of subscriptions on the contract."""
diff --git a/src/metronome/types/shared/contract_v2.py b/src/metronome/types/shared/contract_v2.py
index 2da2efae6..e117360d5 100644
--- a/src/metronome/types/shared/contract_v2.py
+++ b/src/metronome/types/shared/contract_v2.py
@@ -41,6 +41,7 @@
"CommitLedgerPostpaidCommitManualLedgerEntry",
"CommitLedgerPostpaidCommitExpirationLedgerEntry",
"CommitRolledOverFrom",
+ "CommitSpendTrackerAttributes",
"Override",
"OverrideOverrideSpecifier",
"OverrideOverwriteRate",
@@ -82,6 +83,9 @@
"RecurringCreditContract",
"ResellerRoyalty",
"ResellerRoyaltySegment",
+ "SpendTracker",
+ "SpendTrackerApplicableSpendSpecifier",
+ "SpendTrackerAccumulatedSpend",
"Subscription",
"SubscriptionBillingPeriods",
"SubscriptionBillingPeriodsCurrent",
@@ -293,6 +297,16 @@ class CommitRolledOverFrom(BaseModel):
contract_id: str
+class CommitSpendTrackerAttributes(BaseModel):
+ """Optional attributes controlling how this commit interacts with spend trackers."""
+
+ counts_as_discounted: bool
+ """
+ If true, this commit is included in spend trackers with discounted set to
+ DISCOUNTED_ONLY
+ """
+
+
class Commit(BaseModel):
id: str
@@ -387,6 +401,9 @@ class Commit(BaseModel):
specifiers to contribute to a commit's or credit's drawdown.
"""
+ spend_tracker_attributes: Optional[CommitSpendTrackerAttributes] = None
+ """Optional attributes controlling how this commit interacts with spend trackers."""
+
subscription_config: Optional[RecurringCommitSubscriptionConfig] = None
"""Attach a subscription to the recurring commit/credit."""
@@ -1079,6 +1096,35 @@ class ResellerRoyalty(BaseModel):
segments: List[ResellerRoyaltySegment]
+class SpendTrackerApplicableSpendSpecifier(BaseModel):
+ sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]
+
+ spend_type: Literal["COMMIT_PURCHASE"]
+
+ discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None
+
+
+class SpendTrackerAccumulatedSpend(BaseModel):
+ amount: float
+
+ period_ending_before: datetime
+
+ period_starting_at: datetime
+
+
+class SpendTracker(BaseModel):
+ alias: str
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier]
+
+ credit_type_id: str
+
+ reset_frequency: Literal["BILLING_PERIOD"]
+
+ accumulated_spend: Optional[SpendTrackerAccumulatedSpend] = None
+
+
class SubscriptionBillingPeriodsCurrent(BaseModel):
ending_before: datetime
@@ -1288,6 +1334,9 @@ class ContractV2(BaseModel):
spend_threshold_configuration: Optional[SpendThresholdConfigurationV2] = None
+ spend_trackers: Optional[List[SpendTracker]] = None
+ """Spend trackers attached to this contract."""
+
subscriptions: Optional[List[Subscription]] = None
"""List of subscriptions on the contract."""
diff --git a/src/metronome/types/shared/contract_without_amendments.py b/src/metronome/types/shared/contract_without_amendments.py
index 5a92c019f..b16406ad3 100644
--- a/src/metronome/types/shared/contract_without_amendments.py
+++ b/src/metronome/types/shared/contract_without_amendments.py
@@ -35,6 +35,9 @@
"RecurringCreditProduct",
"RecurringCreditContract",
"ResellerRoyalty",
+ "SpendTracker",
+ "SpendTrackerApplicableSpendSpecifier",
+ "SpendTrackerAccumulatedSpend",
"UsageFilter",
"UsageFilterUpdate",
]
@@ -306,6 +309,35 @@ class ResellerRoyalty(BaseModel):
reseller_contract_value: Optional[float] = None
+class SpendTrackerApplicableSpendSpecifier(BaseModel):
+ sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]
+
+ spend_type: Literal["COMMIT_PURCHASE"]
+
+ discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None
+
+
+class SpendTrackerAccumulatedSpend(BaseModel):
+ amount: float
+
+ period_ending_before: datetime
+
+ period_starting_at: datetime
+
+
+class SpendTracker(BaseModel):
+ alias: str
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier]
+
+ credit_type_id: str
+
+ reset_frequency: Literal["BILLING_PERIOD"]
+
+ accumulated_spend: Optional[SpendTrackerAccumulatedSpend] = None
+
+
class UsageFilterUpdate(BaseModel):
group_key: str
@@ -387,6 +419,9 @@ class ContractWithoutAmendments(BaseModel):
spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None
+ spend_trackers: Optional[List[SpendTracker]] = None
+ """Spend trackers attached to this contract."""
+
total_contract_value: Optional[float] = None
"""This field's availability is dependent on your client's configuration."""
diff --git a/src/metronome/types/shared/prepaid_balance_threshold_configuration.py b/src/metronome/types/shared/prepaid_balance_threshold_configuration.py
index 776c0f479..b8bb84c42 100644
--- a/src/metronome/types/shared/prepaid_balance_threshold_configuration.py
+++ b/src/metronome/types/shared/prepaid_balance_threshold_configuration.py
@@ -1,13 +1,22 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import List, Optional
+from typing_extensions import Literal
from ..._models import BaseModel
from .payment_gate_config import PaymentGateConfig
from .base_threshold_commit import BaseThresholdCommit
from .commit_specifier_input import CommitSpecifierInput
-__all__ = ["PrepaidBalanceThresholdConfiguration", "Commit", "DiscountConfiguration"]
+__all__ = [
+ "PrepaidBalanceThresholdConfiguration",
+ "Commit",
+ "DiscountConfiguration",
+ "DiscountConfigurationCap",
+ "ThresholdBalanceSpecifier",
+ "ThresholdBalanceSpecifierExclude",
+ "ThresholdBalanceSpecifierExcludeCustomFieldFilter",
+]
class Commit(BaseThresholdCommit):
@@ -34,6 +43,18 @@ class Commit(BaseThresholdCommit):
"""
+class DiscountConfigurationCap(BaseModel):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
+
+
class DiscountConfiguration(BaseModel):
payment_fraction: float
"""
@@ -42,6 +63,32 @@ class DiscountConfiguration(BaseModel):
(a 15% discount).
"""
+ cap: Optional[DiscountConfigurationCap] = None
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
+
+class ThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel):
+ entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]
+
+ key: str
+
+ value: str
+
+
+class ThresholdBalanceSpecifierExclude(BaseModel):
+ custom_field_filters: List[ThresholdBalanceSpecifierExcludeCustomFieldFilter]
+ """
+ If provided, balances with all the custom fields will not be considered when
+ evaluating threshold billing
+ """
+
+
+class ThresholdBalanceSpecifier(BaseModel):
+ exclude: List[ThresholdBalanceSpecifierExclude]
+
class PrepaidBalanceThresholdConfiguration(BaseModel):
commit: Commit
@@ -72,3 +119,5 @@ class PrepaidBalanceThresholdConfiguration(BaseModel):
"""
discount_configuration: Optional[DiscountConfiguration] = None
+
+ threshold_balance_specifiers: Optional[List[ThresholdBalanceSpecifier]] = None
diff --git a/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py b/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py
index 8539dbf65..8402dfd29 100644
--- a/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py
+++ b/src/metronome/types/shared/prepaid_balance_threshold_configuration_v2.py
@@ -1,13 +1,22 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import List, Optional
+from typing_extensions import Literal
from ..._models import BaseModel
from .base_threshold_commit import BaseThresholdCommit
from .commit_specifier_input import CommitSpecifierInput
from .payment_gate_config_v2 import PaymentGateConfigV2
-__all__ = ["PrepaidBalanceThresholdConfigurationV2", "Commit", "DiscountConfiguration"]
+__all__ = [
+ "PrepaidBalanceThresholdConfigurationV2",
+ "Commit",
+ "DiscountConfiguration",
+ "DiscountConfigurationCap",
+ "ThresholdBalanceSpecifier",
+ "ThresholdBalanceSpecifierExclude",
+ "ThresholdBalanceSpecifierExcludeCustomFieldFilter",
+]
class Commit(BaseThresholdCommit):
@@ -36,6 +45,18 @@ class Commit(BaseThresholdCommit):
"""
+class DiscountConfigurationCap(BaseModel):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
+
+
class DiscountConfiguration(BaseModel):
payment_fraction: float
"""
@@ -44,6 +65,28 @@ class DiscountConfiguration(BaseModel):
(a 15% discount).
"""
+ cap: Optional[DiscountConfigurationCap] = None
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
+
+class ThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel):
+ entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]
+
+ key: str
+
+ value: str
+
+
+class ThresholdBalanceSpecifierExclude(BaseModel):
+ custom_field_filters: List[ThresholdBalanceSpecifierExcludeCustomFieldFilter]
+
+
+class ThresholdBalanceSpecifier(BaseModel):
+ exclude: List[ThresholdBalanceSpecifierExclude]
+
class PrepaidBalanceThresholdConfigurationV2(BaseModel):
commit: Commit
@@ -74,3 +117,5 @@ class PrepaidBalanceThresholdConfigurationV2(BaseModel):
"""
discount_configuration: Optional[DiscountConfiguration] = None
+
+ threshold_balance_specifiers: Optional[List[ThresholdBalanceSpecifier]] = None
diff --git a/src/metronome/types/shared/spend_threshold_configuration.py b/src/metronome/types/shared/spend_threshold_configuration.py
index ae78995e3..95935c490 100644
--- a/src/metronome/types/shared/spend_threshold_configuration.py
+++ b/src/metronome/types/shared/spend_threshold_configuration.py
@@ -6,7 +6,19 @@
from .payment_gate_config import PaymentGateConfig
from .base_threshold_commit import BaseThresholdCommit
-__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration"]
+__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration", "DiscountConfigurationCap"]
+
+
+class DiscountConfigurationCap(BaseModel):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
class DiscountConfiguration(BaseModel):
@@ -17,6 +29,12 @@ class DiscountConfiguration(BaseModel):
(a 15% discount).
"""
+ cap: Optional[DiscountConfigurationCap] = None
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
class SpendThresholdConfiguration(BaseModel):
commit: BaseThresholdCommit
diff --git a/src/metronome/types/shared/spend_threshold_configuration_v2.py b/src/metronome/types/shared/spend_threshold_configuration_v2.py
index 91816c963..fc3e94911 100644
--- a/src/metronome/types/shared/spend_threshold_configuration_v2.py
+++ b/src/metronome/types/shared/spend_threshold_configuration_v2.py
@@ -6,7 +6,19 @@
from .base_threshold_commit import BaseThresholdCommit
from .payment_gate_config_v2 import PaymentGateConfigV2
-__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration"]
+__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration", "DiscountConfigurationCap"]
+
+
+class DiscountConfigurationCap(BaseModel):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
class DiscountConfiguration(BaseModel):
@@ -17,6 +29,12 @@ class DiscountConfiguration(BaseModel):
(a 15% discount).
"""
+ cap: Optional[DiscountConfigurationCap] = None
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
class SpendThresholdConfigurationV2(BaseModel):
commit: BaseThresholdCommit
diff --git a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py
index 974698132..5da85c457 100644
--- a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py
+++ b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration.py
@@ -3,14 +3,22 @@
from __future__ import annotations
from typing import Iterable
-from typing_extensions import Required, TypedDict
+from typing_extensions import Literal, Required, TypedDict
from ..._types import SequenceNotStr
from .payment_gate_config import PaymentGateConfig
from .base_threshold_commit import BaseThresholdCommit
from .commit_specifier_input import CommitSpecifierInput
-__all__ = ["PrepaidBalanceThresholdConfiguration", "Commit", "DiscountConfiguration"]
+__all__ = [
+ "PrepaidBalanceThresholdConfiguration",
+ "Commit",
+ "DiscountConfiguration",
+ "DiscountConfigurationCap",
+ "ThresholdBalanceSpecifier",
+ "ThresholdBalanceSpecifierExclude",
+ "ThresholdBalanceSpecifierExcludeCustomFieldFilter",
+]
class Commit(BaseThresholdCommit, total=False):
@@ -37,6 +45,18 @@ class Commit(BaseThresholdCommit, total=False):
"""
+class DiscountConfigurationCap(TypedDict, total=False):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: Required[float]
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: Required[str]
+ """Alias of the spend tracker this cap is measured against."""
+
+
class DiscountConfiguration(TypedDict, total=False):
payment_fraction: Required[float]
"""
@@ -45,6 +65,32 @@ class DiscountConfiguration(TypedDict, total=False):
(a 15% discount).
"""
+ cap: DiscountConfigurationCap
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
+
+class ThresholdBalanceSpecifierExcludeCustomFieldFilter(TypedDict, total=False):
+ entity: Required[Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]]
+
+ key: Required[str]
+
+ value: Required[str]
+
+
+class ThresholdBalanceSpecifierExclude(TypedDict, total=False):
+ custom_field_filters: Required[Iterable[ThresholdBalanceSpecifierExcludeCustomFieldFilter]]
+ """
+ If provided, balances with all the custom fields will not be considered when
+ evaluating threshold billing
+ """
+
+
+class ThresholdBalanceSpecifier(TypedDict, total=False):
+ exclude: Required[Iterable[ThresholdBalanceSpecifierExclude]]
+
class PrepaidBalanceThresholdConfiguration(TypedDict, total=False):
commit: Required[Commit]
@@ -75,3 +121,5 @@ class PrepaidBalanceThresholdConfiguration(TypedDict, total=False):
"""
discount_configuration: DiscountConfiguration
+
+ threshold_balance_specifiers: Iterable[ThresholdBalanceSpecifier]
diff --git a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py
index 27c36c1fd..0230b6f7e 100644
--- a/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py
+++ b/src/metronome/types/shared_params/prepaid_balance_threshold_configuration_v2.py
@@ -3,14 +3,22 @@
from __future__ import annotations
from typing import Iterable
-from typing_extensions import Required, TypedDict
+from typing_extensions import Literal, Required, TypedDict
from ..._types import SequenceNotStr
from .base_threshold_commit import BaseThresholdCommit
from .commit_specifier_input import CommitSpecifierInput
from .payment_gate_config_v2 import PaymentGateConfigV2
-__all__ = ["PrepaidBalanceThresholdConfigurationV2", "Commit", "DiscountConfiguration"]
+__all__ = [
+ "PrepaidBalanceThresholdConfigurationV2",
+ "Commit",
+ "DiscountConfiguration",
+ "DiscountConfigurationCap",
+ "ThresholdBalanceSpecifier",
+ "ThresholdBalanceSpecifierExclude",
+ "ThresholdBalanceSpecifierExcludeCustomFieldFilter",
+]
class Commit(BaseThresholdCommit, total=False):
@@ -39,6 +47,18 @@ class Commit(BaseThresholdCommit, total=False):
"""
+class DiscountConfigurationCap(TypedDict, total=False):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: Required[float]
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: Required[str]
+ """Alias of the spend tracker this cap is measured against."""
+
+
class DiscountConfiguration(TypedDict, total=False):
payment_fraction: Required[float]
"""
@@ -47,6 +67,28 @@ class DiscountConfiguration(TypedDict, total=False):
(a 15% discount).
"""
+ cap: DiscountConfigurationCap
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
+
+class ThresholdBalanceSpecifierExcludeCustomFieldFilter(TypedDict, total=False):
+ entity: Required[Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]]
+
+ key: Required[str]
+
+ value: Required[str]
+
+
+class ThresholdBalanceSpecifierExclude(TypedDict, total=False):
+ custom_field_filters: Required[Iterable[ThresholdBalanceSpecifierExcludeCustomFieldFilter]]
+
+
+class ThresholdBalanceSpecifier(TypedDict, total=False):
+ exclude: Required[Iterable[ThresholdBalanceSpecifierExclude]]
+
class PrepaidBalanceThresholdConfigurationV2(TypedDict, total=False):
commit: Required[Commit]
@@ -77,3 +119,5 @@ class PrepaidBalanceThresholdConfigurationV2(TypedDict, total=False):
"""
discount_configuration: DiscountConfiguration
+
+ threshold_balance_specifiers: Iterable[ThresholdBalanceSpecifier]
diff --git a/src/metronome/types/shared_params/spend_threshold_configuration.py b/src/metronome/types/shared_params/spend_threshold_configuration.py
index 349a76d04..afa808498 100644
--- a/src/metronome/types/shared_params/spend_threshold_configuration.py
+++ b/src/metronome/types/shared_params/spend_threshold_configuration.py
@@ -7,7 +7,19 @@
from .payment_gate_config import PaymentGateConfig
from .base_threshold_commit import BaseThresholdCommit
-__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration"]
+__all__ = ["SpendThresholdConfiguration", "DiscountConfiguration", "DiscountConfigurationCap"]
+
+
+class DiscountConfigurationCap(TypedDict, total=False):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: Required[float]
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: Required[str]
+ """Alias of the spend tracker this cap is measured against."""
class DiscountConfiguration(TypedDict, total=False):
@@ -18,6 +30,12 @@ class DiscountConfiguration(TypedDict, total=False):
(a 15% discount).
"""
+ cap: DiscountConfigurationCap
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
class SpendThresholdConfiguration(TypedDict, total=False):
commit: Required[BaseThresholdCommit]
diff --git a/src/metronome/types/shared_params/spend_threshold_configuration_v2.py b/src/metronome/types/shared_params/spend_threshold_configuration_v2.py
index a577d4399..ce39da95d 100644
--- a/src/metronome/types/shared_params/spend_threshold_configuration_v2.py
+++ b/src/metronome/types/shared_params/spend_threshold_configuration_v2.py
@@ -7,7 +7,19 @@
from .base_threshold_commit import BaseThresholdCommit
from .payment_gate_config_v2 import PaymentGateConfigV2
-__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration"]
+__all__ = ["SpendThresholdConfigurationV2", "DiscountConfiguration", "DiscountConfigurationCap"]
+
+
+class DiscountConfigurationCap(TypedDict, total=False):
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated this much spend in the billing period.
+ """
+
+ amount: Required[float]
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: Required[str]
+ """Alias of the spend tracker this cap is measured against."""
class DiscountConfiguration(TypedDict, total=False):
@@ -18,6 +30,12 @@ class DiscountConfiguration(TypedDict, total=False):
(a 15% discount).
"""
+ cap: DiscountConfigurationCap
+ """
+ If provided, the discount stops applying once the spend tracker has accumulated
+ this much spend in the billing period.
+ """
+
class SpendThresholdConfigurationV2(TypedDict, total=False):
commit: Required[BaseThresholdCommit]
diff --git a/src/metronome/types/v1/__init__.py b/src/metronome/types/v1/__init__.py
index 3430b56ed..12b28d369 100644
--- a/src/metronome/types/v1/__init__.py
+++ b/src/metronome/types/v1/__init__.py
@@ -2,10 +2,8 @@
from __future__ import annotations
-from .payment import Payment as Payment
from .customer import Customer as Customer
from .plan_detail import PlanDetail as PlanDetail
-from .payment_status import PaymentStatus as PaymentStatus
from .customer_detail import CustomerDetail as CustomerDetail
from .plan_list_params import PlanListParams as PlanListParams
from .usage_list_params import UsageListParams as UsageListParams
@@ -14,7 +12,6 @@
from .credit_ledger_entry import CreditLedgerEntry as CreditLedgerEntry
from .invoice_void_params import InvoiceVoidParams as InvoiceVoidParams
from .package_list_params import PackageListParams as PackageListParams
-from .payment_list_params import PaymentListParams as PaymentListParams
from .usage_ingest_params import UsageIngestParams as UsageIngestParams
from .usage_list_response import UsageListResponse as UsageListResponse
from .usage_search_params import UsageSearchParams as UsageSearchParams
@@ -27,7 +24,6 @@
from .invoice_void_response import InvoiceVoidResponse as InvoiceVoidResponse
from .package_create_params import PackageCreateParams as PackageCreateParams
from .package_list_response import PackageListResponse as PackageListResponse
-from .payment_cancel_params import PaymentCancelParams as PaymentCancelParams
from .service_list_response import ServiceListResponse as ServiceListResponse
from .usage_search_response import UsageSearchResponse as UsageSearchResponse
from .alert_archive_response import AlertArchiveResponse as AlertArchiveResponse
@@ -35,14 +31,12 @@
from .contract_list_response import ContractListResponse as ContractListResponse
from .customer_create_params import CustomerCreateParams as CustomerCreateParams
from .package_archive_params import PackageArchiveParams as PackageArchiveParams
-from .payment_attempt_params import PaymentAttemptParams as PaymentAttemptParams
from .audit_log_list_response import AuditLogListResponse as AuditLogListResponse
from .contract_amend_response import ContractAmendResponse as ContractAmendResponse
from .contract_archive_params import ContractArchiveParams as ContractArchiveParams
from .customer_archive_params import CustomerArchiveParams as CustomerArchiveParams
from .package_create_response import PackageCreateResponse as PackageCreateResponse
from .package_retrieve_params import PackageRetrieveParams as PackageRetrieveParams
-from .payment_cancel_response import PaymentCancelResponse as PaymentCancelResponse
from .contract_create_response import ContractCreateResponse as ContractCreateResponse
from .contract_retrieve_params import ContractRetrieveParams as ContractRetrieveParams
from .credit_grant_edit_params import CreditGrantEditParams as CreditGrantEditParams
@@ -51,7 +45,6 @@
from .customer_create_response import CustomerCreateResponse as CustomerCreateResponse
from .customer_set_name_params import CustomerSetNameParams as CustomerSetNameParams
from .package_archive_response import PackageArchiveResponse as PackageArchiveResponse
-from .payment_attempt_response import PaymentAttemptResponse as PaymentAttemptResponse
from .plan_list_charges_params import PlanListChargesParams as PlanListChargesParams
from .pricing_unit_list_params import PricingUnitListParams as PricingUnitListParams
from .contract_archive_response import ContractArchiveResponse as ContractArchiveResponse
diff --git a/src/metronome/types/v1/contract_amend_params.py b/src/metronome/types/v1/contract_amend_params.py
index 0b32c3718..59c22ccb0 100644
--- a/src/metronome/types/v1/contract_amend_params.py
+++ b/src/metronome/types/v1/contract_amend_params.py
@@ -20,6 +20,7 @@
"CommitInvoiceSchedule",
"CommitInvoiceScheduleRecurringSchedule",
"CommitInvoiceScheduleScheduleItem",
+ "CommitSpendTrackerAttributes",
"Credit",
"CreditAccessSchedule",
"CreditAccessScheduleScheduleItem",
@@ -194,6 +195,16 @@ class CommitInvoiceSchedule(TypedDict, total=False):
"""Either provide amount or provide both unit_price and quantity."""
+class CommitSpendTrackerAttributes(TypedDict, total=False):
+ """Optional attributes for spend tracker integration. Immutable after creation."""
+
+ counts_as_discounted: Required[bool]
+ """
+ If true, this commit will be included in spend trackers with discounted set to
+ DISCOUNTED_ONLY
+ """
+
+
class Commit(TypedDict, total=False):
product_id: Required[str]
@@ -265,6 +276,9 @@ class Commit(TypedDict, total=False):
be used together with `applicable_product_ids` or `applicable_product_tags`.
"""
+ spend_tracker_attributes: CommitSpendTrackerAttributes
+ """Optional attributes for spend tracker integration. Immutable after creation."""
+
temporary_id: str
"""
A temporary ID for the commit that can be used to reference the commit for
diff --git a/src/metronome/types/v1/contract_create_params.py b/src/metronome/types/v1/contract_create_params.py
index 58ab3fc7a..9d9354ebf 100644
--- a/src/metronome/types/v1/contract_create_params.py
+++ b/src/metronome/types/v1/contract_create_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Dict, Union, Iterable, Optional
+from typing import Dict, List, Union, Iterable, Optional
from datetime import datetime
from typing_extensions import Literal, Required, Annotated, TypedDict
@@ -24,6 +24,7 @@
"CommitInvoiceSchedule",
"CommitInvoiceScheduleRecurringSchedule",
"CommitInvoiceScheduleScheduleItem",
+ "CommitSpendTrackerAttributes",
"Credit",
"CreditAccessSchedule",
"CreditAccessScheduleScheduleItem",
@@ -58,6 +59,8 @@
"ScheduledChargeSchedule",
"ScheduledChargeScheduleRecurringSchedule",
"ScheduledChargeScheduleScheduleItem",
+ "SpendTracker",
+ "SpendTrackerApplicableSpendSpecifier",
"Subscription",
"SubscriptionProration",
"SubscriptionSubscriptionRate",
@@ -167,6 +170,12 @@ class ContractCreateParams(TypedDict, total=False):
spend_threshold_configuration: SpendThresholdConfiguration
+ spend_trackers: Iterable[SpendTracker]
+ """Spend trackers to attach to this contract.
+
+ Aliases must be unique within a contract.
+ """
+
subscriptions: Iterable[Subscription]
"""
Optional list of
@@ -324,6 +333,16 @@ class CommitInvoiceSchedule(TypedDict, total=False):
"""Either provide amount or provide both unit_price and quantity."""
+class CommitSpendTrackerAttributes(TypedDict, total=False):
+ """Optional attributes for spend tracker integration. Immutable after creation."""
+
+ counts_as_discounted: Required[bool]
+ """
+ If true, this commit will be included in spend trackers with discounted set to
+ DISCOUNTED_ONLY
+ """
+
+
class Commit(TypedDict, total=False):
product_id: Required[str]
@@ -395,6 +414,9 @@ class Commit(TypedDict, total=False):
be used together with `applicable_product_ids` or `applicable_product_tags`.
"""
+ spend_tracker_attributes: CommitSpendTrackerAttributes
+ """Optional attributes for spend tracker integration. Immutable after creation."""
+
temporary_id: str
"""
A temporary ID for the commit that can be used to reference the commit for
@@ -1242,6 +1264,26 @@ class ScheduledCharge(TypedDict, total=False):
"""This field's availability is dependent on your client's configuration."""
+class SpendTrackerApplicableSpendSpecifier(TypedDict, total=False):
+ sources: Required[List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]]
+
+ spend_type: Required[Literal["COMMIT_PURCHASE"]]
+
+ discounted: Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]
+ """Filter by whether the spend was discounted. Defaults to ANY if omitted."""
+
+
+class SpendTracker(TypedDict, total=False):
+ alias: Required[str]
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: Required[Iterable[SpendTrackerApplicableSpendSpecifier]]
+
+ credit_type_id: Required[str]
+
+ reset_frequency: Required[Literal["BILLING_PERIOD"]]
+
+
class SubscriptionProration(TypedDict, total=False):
invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"]
"""
diff --git a/src/metronome/types/v1/contract_create_response.py b/src/metronome/types/v1/contract_create_response.py
index 4e97367b9..26bff00a5 100644
--- a/src/metronome/types/v1/contract_create_response.py
+++ b/src/metronome/types/v1/contract_create_response.py
@@ -1,10 +1,432 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from typing import Dict, List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
from ..._models import BaseModel
-from ..shared.id import ID
+from ..shared.commit import Commit
+from ..shared.credit import Credit
+from ..shared.override import Override
+from ..shared.subscription import Subscription
+from ..shared.commit_specifier import CommitSpecifier
+from ..shared.scheduled_charge import ScheduledCharge
+from ..shared.hierarchy_configuration import HierarchyConfiguration
+from ..shared.spend_threshold_configuration import SpendThresholdConfiguration
+from ..shared.commit_hierarchy_configuration import CommitHierarchyConfiguration
+from ..shared.recurring_commit_subscription_config import RecurringCommitSubscriptionConfig
+from ..shared.prepaid_balance_threshold_configuration import PrepaidBalanceThresholdConfiguration
+
+__all__ = [
+ "ContractCreateResponse",
+ "Data",
+ "DataContract",
+ "DataContractTransition",
+ "DataContractUsageFilter",
+ "DataContractUsageStatementSchedule",
+ "DataContractCustomerBillingProviderConfiguration",
+ "DataContractHasMore",
+ "DataContractRecurringCommit",
+ "DataContractRecurringCommitAccessAmount",
+ "DataContractRecurringCommitCommitDuration",
+ "DataContractRecurringCommitProduct",
+ "DataContractRecurringCommitContract",
+ "DataContractRecurringCommitInvoiceAmount",
+ "DataContractRecurringCredit",
+ "DataContractRecurringCreditAccessAmount",
+ "DataContractRecurringCreditCommitDuration",
+ "DataContractRecurringCreditProduct",
+ "DataContractRecurringCreditContract",
+]
+
+
+class DataContractTransition(BaseModel):
+ from_contract_id: str
+
+ to_contract_id: str
+
+ type: Literal["SUPERSEDE", "RENEWAL"]
+
+
+class DataContractUsageFilter(BaseModel):
+ group_key: str
+
+ group_values: List[str]
+
+ starting_at: datetime
+
+ ending_before: Optional[datetime] = None
+
+
+class DataContractUsageStatementSchedule(BaseModel):
+ billing_anchor_date: datetime
+ """Contract usage statements follow a selected cadence based on this date."""
+
+ frequency: Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]
+
+
+class DataContractCustomerBillingProviderConfiguration(BaseModel):
+ """The billing provider configuration associated with the contract."""
+
+ id: Optional[str] = None
+
+ billing_provider: Optional[
+ Literal[
+ "aws_marketplace",
+ "stripe",
+ "netsuite",
+ "custom",
+ "azure_marketplace",
+ "quickbooks_online",
+ "workday",
+ "gcp_marketplace",
+ "metronome",
+ ]
+ ] = None
+
+ delivery_method: Optional[Literal["direct_to_billing_provider", "aws_sqs", "tackle", "aws_sns"]] = None
+
+
+class DataContractHasMore(BaseModel):
+ """Indicates whether there are more items than the limit for this endpoint.
+
+ Use the respective list endpoints to get the full lists.
+ """
+
+ commits: bool
+ """Whether there are more commits on this contract than the limit for this
+ endpoint.
+
+ Use the /contracts/customerCommits/list endpoint to get the full list of
+ commits.
+ """
+
+ credits: bool
+ """Whether there are more credits on this contract than the limit for this
+ endpoint.
+
+ Use the /contracts/customerCredits/list endpoint to get the full list of
+ credits.
+ """
+
+
+class DataContractRecurringCommitAccessAmount(BaseModel):
+ """The amount of commit to grant."""
+
+ credit_type_id: str
+
+ unit_price: float
+
+ quantity: Optional[float] = None
+
+
+class DataContractRecurringCommitCommitDuration(BaseModel):
+ """The amount of time the created commits will be valid for"""
+
+ value: float
+
+ unit: Optional[Literal["PERIODS"]] = None
+
+
+class DataContractRecurringCommitProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataContractRecurringCommitContract(BaseModel):
+ id: str
+
+
+class DataContractRecurringCommitInvoiceAmount(BaseModel):
+ """The amount the customer should be billed for the commit. Not required."""
+
+ credit_type_id: str
+
+ quantity: float
+
+ unit_price: float
+
+
+class DataContractRecurringCommit(BaseModel):
+ id: str
+
+ access_amount: DataContractRecurringCommitAccessAmount
+ """The amount of commit to grant."""
+
+ commit_duration: DataContractRecurringCommitCommitDuration
+ """The amount of time the created commits will be valid for"""
+
+ priority: float
+ """Will be passed down to the individual commits"""
+
+ product: DataContractRecurringCommitProduct
+
+ rate_type: Literal["COMMIT_RATE", "LIST_RATE"]
+ """Whether the created commits will use the commit rate or list rate"""
+
+ starting_at: datetime
+ """Determines the start time for the first commit"""
+
+ applicable_product_ids: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ applicable_product_tags: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ contract: Optional[DataContractRecurringCommitContract] = None
+
+ description: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ ending_before: Optional[datetime] = None
+ """Determines when the contract will stop creating recurring commits. Optional"""
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for recurring commit/credit hierarchy access control"""
+
+ invoice_amount: Optional[DataContractRecurringCommitInvoiceAmount] = None
+ """The amount the customer should be billed for the commit. Not required."""
+
+ name: Optional[str] = None
+ """Displayed on invoices. Will be passed through to the individual commits"""
+
+ netsuite_sales_order_id: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None
+ """Determines whether the first and last commit will be prorated.
+
+ If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and
+ last commits).
+ """
+
+ recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None
+ """The frequency at which the recurring commits will be created.
+
+ If not provided: - The commits will be created on the usage invoice frequency.
+ If provided: - The period defined in the duration will correspond to this
+ frequency. - Commits will be created aligned with the recurring commit's
+ starting_at rather than the usage invoice dates.
+ """
+
+ rollover_fraction: Optional[float] = None
+ """Will be passed down to the individual commits.
+
+ This controls how much of an individual unexpired commit will roll over upon
+ contract transition. Must be between 0 and 1.
+ """
+
+ specifiers: Optional[List[CommitSpecifier]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown.
+ """
+
+ subscription_config: Optional[RecurringCommitSubscriptionConfig] = None
+ """Attach a subscription to the recurring commit/credit."""
+
+
+class DataContractRecurringCreditAccessAmount(BaseModel):
+ """The amount of commit to grant."""
+
+ credit_type_id: str
+
+ unit_price: float
+
+ quantity: Optional[float] = None
+
+
+class DataContractRecurringCreditCommitDuration(BaseModel):
+ """The amount of time the created commits will be valid for"""
+
+ value: float
+
+ unit: Optional[Literal["PERIODS"]] = None
+
+
+class DataContractRecurringCreditProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataContractRecurringCreditContract(BaseModel):
+ id: str
+
+
+class DataContractRecurringCredit(BaseModel):
+ id: str
+
+ access_amount: DataContractRecurringCreditAccessAmount
+ """The amount of commit to grant."""
+
+ commit_duration: DataContractRecurringCreditCommitDuration
+ """The amount of time the created commits will be valid for"""
+
+ priority: float
+ """Will be passed down to the individual commits"""
+
+ product: DataContractRecurringCreditProduct
+
+ rate_type: Literal["COMMIT_RATE", "LIST_RATE"]
+ """Whether the created commits will use the commit rate or list rate"""
+
+ starting_at: datetime
+ """Determines the start time for the first commit"""
+
+ applicable_product_ids: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ applicable_product_tags: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ contract: Optional[DataContractRecurringCreditContract] = None
+
+ description: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ ending_before: Optional[datetime] = None
+ """Determines when the contract will stop creating recurring commits. Optional"""
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for recurring commit/credit hierarchy access control"""
+
+ name: Optional[str] = None
+ """Displayed on invoices. Will be passed through to the individual commits"""
+
+ netsuite_sales_order_id: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None
+ """Determines whether the first and last commit will be prorated.
+
+ If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and
+ last commits).
+ """
+
+ recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None
+ """The frequency at which the recurring commits will be created.
+
+ If not provided: - The commits will be created on the usage invoice frequency.
+ If provided: - The period defined in the duration will correspond to this
+ frequency. - Commits will be created aligned with the recurring commit's
+ starting_at rather than the usage invoice dates.
+ """
+
+ rollover_fraction: Optional[float] = None
+ """Will be passed down to the individual commits.
+
+ This controls how much of an individual unexpired commit will roll over upon
+ contract transition. Must be between 0 and 1.
+ """
+
+ specifiers: Optional[List[CommitSpecifier]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown.
+ """
+
+ subscription_config: Optional[RecurringCommitSubscriptionConfig] = None
+ """Attach a subscription to the recurring commit/credit."""
+
+
+class DataContract(BaseModel):
+ """The created contract."""
+
+ id: str
+
+ commits: List[Commit]
+
+ created_at: datetime
+
+ created_by: str
+
+ customer_id: str
+
+ overrides: List[Override]
+
+ scheduled_charges: List[ScheduledCharge]
+
+ starting_at: datetime
+
+ transitions: List[DataContractTransition]
+
+ usage_filter: List[DataContractUsageFilter]
+
+ usage_statement_schedule: DataContractUsageStatementSchedule
+
+ credits: Optional[List[Credit]] = None
+
+ custom_fields: Optional[Dict[str, str]] = None
+ """Custom fields to be added eg. { "key1": "value1", "key2": "value2" }"""
+
+ customer_billing_provider_configuration: Optional[DataContractCustomerBillingProviderConfiguration] = None
+ """The billing provider configuration associated with the contract."""
+
+ ending_before: Optional[datetime] = None
+
+ has_more: Optional[DataContractHasMore] = None
+ """Indicates whether there are more items than the limit for this endpoint.
+
+ Use the respective list endpoints to get the full lists.
+ """
+
+ hierarchy_configuration: Optional[HierarchyConfiguration] = None
+ """
+ Either a **parent** configuration with a list of children or a **child**
+ configuration with a single parent.
+ """
+
+ multiplier_override_prioritization: Optional[Literal["LOWEST_MULTIPLIER", "EXPLICIT"]] = None
+ """
+ Defaults to LOWEST_MULTIPLIER, which applies the greatest discount to list
+ prices automatically. EXPLICIT prioritization requires specifying priorities for
+ each multiplier; the one with the lowest priority value will be prioritized
+ first.
+ """
+
+ name: Optional[str] = None
+
+ net_payment_terms_days: Optional[float] = None
+
+ package_id: Optional[str] = None
+ """ID of the package this contract was created from, if applicable."""
+
+ prepaid_balance_threshold_configuration: Optional[PrepaidBalanceThresholdConfiguration] = None
+
+ rate_card_id: Optional[str] = None
+
+ recurring_commits: Optional[List[DataContractRecurringCommit]] = None
+
+ recurring_credits: Optional[List[DataContractRecurringCredit]] = None
+
+ scheduled_charges_on_usage_invoices: Optional[Literal["ALL"]] = None
+ """
+ Determines which scheduled and commit charges to consolidate onto the Contract's
+ usage invoice. The charge's `timestamp` must match the usage invoice's
+ `ending_before` date for consolidation to occur. This field cannot be modified
+ after a Contract has been created. If this field is omitted, charges will appear
+ on a separate invoice from usage charges.
+ """
+
+ spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None
+
+ subscriptions: Optional[List[Subscription]] = None
+ """List of subscriptions on the contract."""
+
+ uniqueness_key: Optional[str] = None
+ """Optional uniqueness key to prevent duplicate contract creations."""
+
+
+class Data(BaseModel):
+ id: str
-__all__ = ["ContractCreateResponse"]
+ contract: Optional[DataContract] = None
+ """The created contract."""
class ContractCreateResponse(BaseModel):
- data: ID
+ data: Data
diff --git a/src/metronome/types/v1/package_create_params.py b/src/metronome/types/v1/package_create_params.py
index 240c57410..4817854a9 100644
--- a/src/metronome/types/v1/package_create_params.py
+++ b/src/metronome/types/v1/package_create_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Dict, Union, Iterable
+from typing import Dict, List, Union, Iterable
from datetime import datetime
from typing_extensions import Literal, Required, Annotated, TypedDict
@@ -55,6 +55,8 @@
"ScheduledChargeSchedule",
"ScheduledChargeScheduleScheduleItem",
"ScheduledChargeScheduleScheduleItemDateOffset",
+ "SpendTracker",
+ "SpendTrackerApplicableSpendSpecifier",
"Subscription",
"SubscriptionProration",
"SubscriptionSubscriptionRate",
@@ -128,6 +130,8 @@ class PackageCreateParams(TypedDict, total=False):
spend_threshold_configuration: SpendThresholdConfiguration
+ spend_trackers: Iterable[SpendTracker]
+
subscriptions: Iterable[Subscription]
uniqueness_key: str
@@ -912,6 +916,26 @@ class ScheduledCharge(TypedDict, total=False):
"""displayed on invoices"""
+class SpendTrackerApplicableSpendSpecifier(TypedDict, total=False):
+ sources: Required[List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]]
+
+ spend_type: Required[Literal["COMMIT_PURCHASE"]]
+
+ discounted: Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]
+ """Filter by whether the spend was discounted. Defaults to ANY if omitted."""
+
+
+class SpendTracker(TypedDict, total=False):
+ alias: Required[str]
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: Required[Iterable[SpendTrackerApplicableSpendSpecifier]]
+
+ credit_type_id: Required[str]
+
+ reset_frequency: Required[Literal["BILLING_PERIOD"]]
+
+
class SubscriptionProration(TypedDict, total=False):
invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"]
"""
diff --git a/src/metronome/types/v1/package_list_response.py b/src/metronome/types/v1/package_list_response.py
index 0953958a0..08620fee9 100644
--- a/src/metronome/types/v1/package_list_response.py
+++ b/src/metronome/types/v1/package_list_response.py
@@ -59,6 +59,8 @@
"RecurringCreditDuration",
"RecurringCreditSubscriptionConfig",
"RecurringCreditSubscriptionConfigApplySeatIncreaseConfig",
+ "SpendTracker",
+ "SpendTrackerApplicableSpendSpecifier",
"Subscription",
"SubscriptionProration",
"SubscriptionSubscriptionRate",
@@ -645,6 +647,25 @@ class RecurringCredit(BaseModel):
"""Attach a subscription to the recurring commit/credit."""
+class SpendTrackerApplicableSpendSpecifier(BaseModel):
+ sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]
+
+ spend_type: Literal["COMMIT_PURCHASE"]
+
+ discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None
+
+
+class SpendTracker(BaseModel):
+ alias: str
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: List[SpendTrackerApplicableSpendSpecifier]
+
+ credit_type_id: str
+
+ reset_frequency: Literal["BILLING_PERIOD"]
+
+
class SubscriptionProration(BaseModel):
invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"]
@@ -800,6 +821,8 @@ class PackageListResponse(BaseModel):
spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None
+ spend_trackers: Optional[List[SpendTracker]] = None
+
subscriptions: Optional[List[Subscription]] = None
uniqueness_key: Optional[str] = None
diff --git a/src/metronome/types/v1/package_retrieve_response.py b/src/metronome/types/v1/package_retrieve_response.py
index c6b5ca4c0..7d73c1721 100644
--- a/src/metronome/types/v1/package_retrieve_response.py
+++ b/src/metronome/types/v1/package_retrieve_response.py
@@ -60,6 +60,8 @@
"DataRecurringCreditDuration",
"DataRecurringCreditSubscriptionConfig",
"DataRecurringCreditSubscriptionConfigApplySeatIncreaseConfig",
+ "DataSpendTracker",
+ "DataSpendTrackerApplicableSpendSpecifier",
"DataSubscription",
"DataSubscriptionProration",
"DataSubscriptionSubscriptionRate",
@@ -646,6 +648,25 @@ class DataRecurringCredit(BaseModel):
"""Attach a subscription to the recurring commit/credit."""
+class DataSpendTrackerApplicableSpendSpecifier(BaseModel):
+ sources: List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]
+
+ spend_type: Literal["COMMIT_PURCHASE"]
+
+ discounted: Optional[Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]] = None
+
+
+class DataSpendTracker(BaseModel):
+ alias: str
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: List[DataSpendTrackerApplicableSpendSpecifier]
+
+ credit_type_id: str
+
+ reset_frequency: Literal["BILLING_PERIOD"]
+
+
class DataSubscriptionProration(BaseModel):
invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"]
@@ -801,6 +822,8 @@ class Data(BaseModel):
spend_threshold_configuration: Optional[SpendThresholdConfiguration] = None
+ spend_trackers: Optional[List[DataSpendTracker]] = None
+
subscriptions: Optional[List[DataSubscription]] = None
uniqueness_key: Optional[str] = None
diff --git a/src/metronome/types/v1/payment.py b/src/metronome/types/v1/payment.py
deleted file mode 100644
index ce3aab66a..000000000
--- a/src/metronome/types/v1/payment.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-from .payment_status import PaymentStatus
-from ..shared.credit_type_data import CreditTypeData
-
-__all__ = ["Payment", "PaymentGateway", "PaymentGatewayStripe", "PaymentGatewayStripeError", "RevenueSystemPayment"]
-
-
-class PaymentGatewayStripeError(BaseModel):
- code: Optional[str] = None
-
- decline_code: Optional[str] = None
-
- type: Optional[str] = None
-
-
-class PaymentGatewayStripe(BaseModel):
- payment_intent_id: str
-
- error: Optional[PaymentGatewayStripeError] = None
-
- payment_method_id: Optional[str] = None
-
-
-class PaymentGateway(BaseModel):
- stripe: PaymentGatewayStripe
-
- type: Literal["stripe"]
-
-
-class RevenueSystemPayment(BaseModel):
- revenue_system_provider: str
-
- sync_status: str
-
- error_message: Optional[str] = None
- """The error message from the revenue system, if available."""
-
- revenue_system_external_payment_id: Optional[str] = None
-
-
-class Payment(BaseModel):
- id: str
-
- amount: Optional[float] = None
-
- amount_paid: Optional[float] = None
-
- contract_id: Optional[str] = None
-
- created_at: Optional[datetime] = None
-
- customer_id: Optional[str] = None
-
- error_message: Optional[str] = None
-
- fiat_credit_type: Optional[CreditTypeData] = None
-
- invoice_id: Optional[str] = None
-
- payment_gateway: Optional[PaymentGateway] = None
-
- revenue_system_payments: Optional[List[RevenueSystemPayment]] = None
-
- status: Optional[PaymentStatus] = None
-
- updated_at: Optional[datetime] = None
diff --git a/src/metronome/types/v1/payment_attempt_params.py b/src/metronome/types/v1/payment_attempt_params.py
deleted file mode 100644
index 1579e3a16..000000000
--- a/src/metronome/types/v1/payment_attempt_params.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["PaymentAttemptParams"]
-
-
-class PaymentAttemptParams(TypedDict, total=False):
- customer_id: Required[str]
-
- invoice_id: Required[str]
diff --git a/src/metronome/types/v1/payment_attempt_response.py b/src/metronome/types/v1/payment_attempt_response.py
deleted file mode 100644
index 52c45c158..000000000
--- a/src/metronome/types/v1/payment_attempt_response.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .payment import Payment
-from ..._models import BaseModel
-
-__all__ = ["PaymentAttemptResponse"]
-
-
-class PaymentAttemptResponse(BaseModel):
- data: Payment
diff --git a/src/metronome/types/v1/payment_cancel_params.py b/src/metronome/types/v1/payment_cancel_params.py
deleted file mode 100644
index b3666f14d..000000000
--- a/src/metronome/types/v1/payment_cancel_params.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["PaymentCancelParams"]
-
-
-class PaymentCancelParams(TypedDict, total=False):
- customer_id: Required[str]
-
- invoice_id: Required[str]
diff --git a/src/metronome/types/v1/payment_cancel_response.py b/src/metronome/types/v1/payment_cancel_response.py
deleted file mode 100644
index 12305d77b..000000000
--- a/src/metronome/types/v1/payment_cancel_response.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .payment import Payment
-from ..._models import BaseModel
-
-__all__ = ["PaymentCancelResponse"]
-
-
-class PaymentCancelResponse(BaseModel):
- data: Payment
diff --git a/src/metronome/types/v1/payment_list_params.py b/src/metronome/types/v1/payment_list_params.py
deleted file mode 100644
index e9a9fe8ea..000000000
--- a/src/metronome/types/v1/payment_list_params.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import List
-from typing_extensions import Required, TypedDict
-
-from .payment_status import PaymentStatus
-
-__all__ = ["PaymentListParams"]
-
-
-class PaymentListParams(TypedDict, total=False):
- customer_id: Required[str]
-
- invoice_id: Required[str]
-
- limit: int
- """The maximum number of payments to return. Defaults to 25."""
-
- next_page: str
- """The next page token from a previous response."""
-
- statuses: List[PaymentStatus]
diff --git a/src/metronome/types/v1/payment_status.py b/src/metronome/types/v1/payment_status.py
deleted file mode 100644
index f348de544..000000000
--- a/src/metronome/types/v1/payment_status.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing_extensions import Literal, TypeAlias
-
-__all__ = ["PaymentStatus"]
-
-PaymentStatus: TypeAlias = Literal["pending", "requires_intervention", "paid", "canceled"]
diff --git a/src/metronome/types/v2/contract_edit_params.py b/src/metronome/types/v2/contract_edit_params.py
index 2eed1710e..caa52466e 100644
--- a/src/metronome/types/v2/contract_edit_params.py
+++ b/src/metronome/types/v2/contract_edit_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Dict, Union, Iterable, Optional
+from typing import Dict, List, Union, Iterable, Optional
from datetime import datetime
from typing_extensions import Literal, Required, Annotated, TypedDict
@@ -30,6 +30,7 @@
"AddCommitPaymentGateConfig",
"AddCommitPaymentGateConfigPrecalculatedTaxConfig",
"AddCommitPaymentGateConfigStripeConfig",
+ "AddCommitSpendTrackerAttributes",
"AddCredit",
"AddCreditAccessSchedule",
"AddCreditAccessScheduleScheduleItem",
@@ -63,6 +64,8 @@
"AddScheduledChargeSchedule",
"AddScheduledChargeScheduleRecurringSchedule",
"AddScheduledChargeScheduleScheduleItem",
+ "AddSpendTracker",
+ "AddSpendTrackerApplicableSpendSpecifier",
"AddSubscription",
"AddSubscriptionProration",
"AddSubscriptionSubscriptionRate",
@@ -88,6 +91,10 @@
"UpdatePrepaidBalanceThresholdConfiguration",
"UpdatePrepaidBalanceThresholdConfigurationCommit",
"UpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration",
+ "UpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap",
+ "UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier",
+ "UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude",
+ "UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter",
"UpdateRecurringCommit",
"UpdateRecurringCommitAccessAmount",
"UpdateRecurringCommitInvoiceAmount",
@@ -100,6 +107,7 @@
"UpdateScheduledChargeInvoiceScheduleUpdateScheduleItem",
"UpdateSpendThresholdConfiguration",
"UpdateSpendThresholdConfigurationDiscountConfiguration",
+ "UpdateSpendThresholdConfigurationDiscountConfigurationCap",
"UpdateSubscription",
"UpdateSubscriptionQuantityManagementModeUpdate",
"UpdateSubscriptionQuantityManagementModeUpdateSeatConfig",
@@ -156,6 +164,12 @@ class ContractEditParams(TypedDict, total=False):
add_spend_threshold_configuration: SpendThresholdConfigurationV2
+ add_spend_trackers: Iterable[AddSpendTracker]
+ """Spend trackers to add to this contract.
+
+ Aliases must be unique within a contract.
+ """
+
add_subscriptions: Iterable[AddSubscription]
"""
Optional list of
@@ -180,6 +194,9 @@ class ContractEditParams(TypedDict, total=False):
archive_scheduled_charges: Iterable[ArchiveScheduledCharge]
"""IDs of scheduled charges to archive"""
+ archive_spend_trackers: SequenceNotStr[str]
+ """Aliases of spend trackers to archive."""
+
remove_overrides: Iterable[RemoveOverride]
"""IDs of overrides to remove"""
@@ -451,6 +468,16 @@ class AddCommitPaymentGateConfig(TypedDict, total=False):
"""
+class AddCommitSpendTrackerAttributes(TypedDict, total=False):
+ """Optional attributes for spend tracker integration. Immutable after creation."""
+
+ counts_as_discounted: Required[bool]
+ """
+ If true, this commit will be included in spend trackers with discounted set to
+ DISCOUNTED_ONLY
+ """
+
+
class AddCommit(TypedDict, total=False):
product_id: Required[str]
@@ -527,6 +554,9 @@ class AddCommit(TypedDict, total=False):
body of `specifiers`.
"""
+ spend_tracker_attributes: AddCommitSpendTrackerAttributes
+ """Optional attributes for spend tracker integration. Immutable after creation."""
+
temporary_id: str
"""
A temporary ID for the commit that can be used to reference the commit for
@@ -1323,6 +1353,26 @@ class AddScheduledCharge(TypedDict, total=False):
"""This field's availability is dependent on your client's configuration."""
+class AddSpendTrackerApplicableSpendSpecifier(TypedDict, total=False):
+ sources: Required[List[Literal["THRESHOLD_RECHARGE", "MANUAL"]]]
+
+ spend_type: Required[Literal["COMMIT_PURCHASE"]]
+
+ discounted: Literal["ANY", "DISCOUNTED_ONLY", "UNDISCOUNTED_ONLY"]
+ """Filter by whether the spend was discounted. Defaults to ANY if omitted."""
+
+
+class AddSpendTracker(TypedDict, total=False):
+ alias: Required[str]
+ """Human-readable identifier, unique per contract."""
+
+ applicable_spend_specifiers: Required[Iterable[AddSpendTrackerApplicableSpendSpecifier]]
+
+ credit_type_id: Required[str]
+
+ reset_frequency: Required[Literal["BILLING_PERIOD"]]
+
+
class AddSubscriptionProration(TypedDict, total=False):
invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"]
"""
@@ -1643,7 +1693,20 @@ class UpdatePrepaidBalanceThresholdConfigurationCommit(UpdateBaseThresholdCommit
"""
+class UpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap(TypedDict, total=False):
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ amount: Required[float]
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: Required[str]
+ """Alias of the spend tracker this cap is measured against."""
+
+
class UpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(TypedDict, total=False):
+ cap: Optional[UpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap]
+ """Update the discount cap. Set to null to remove an existing cap."""
+
payment_fraction: Optional[float]
"""
The fraction of the original amount that the customer pays after applying the
@@ -1652,6 +1715,26 @@ class UpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(TypedDict,
"""
+class UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter(
+ TypedDict, total=False
+):
+ entity: Required[Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]]
+
+ key: Required[str]
+
+ value: Required[str]
+
+
+class UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude(TypedDict, total=False):
+ custom_field_filters: Required[
+ Iterable[UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter]
+ ]
+
+
+class UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier(TypedDict, total=False):
+ exclude: Required[Iterable[UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude]]
+
+
class UpdatePrepaidBalanceThresholdConfiguration(TypedDict, total=False):
commit: UpdatePrepaidBalanceThresholdConfigurationCommit
@@ -1682,6 +1765,10 @@ class UpdatePrepaidBalanceThresholdConfiguration(TypedDict, total=False):
be initiated.
"""
+ threshold_balance_specifiers: Optional[
+ Iterable[UpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier]
+ ]
+
class UpdateRecurringCommitAccessAmount(TypedDict, total=False):
quantity: float
@@ -1773,7 +1860,20 @@ class UpdateScheduledCharge(TypedDict, total=False):
netsuite_sales_order_id: Optional[str]
+class UpdateSpendThresholdConfigurationDiscountConfigurationCap(TypedDict, total=False):
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ amount: Required[float]
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: Required[str]
+ """Alias of the spend tracker this cap is measured against."""
+
+
class UpdateSpendThresholdConfigurationDiscountConfiguration(TypedDict, total=False):
+ cap: Optional[UpdateSpendThresholdConfigurationDiscountConfigurationCap]
+ """Update the discount cap. Set to null to remove an existing cap."""
+
payment_fraction: Optional[float]
"""
The fraction of the original amount that the customer pays after applying the
diff --git a/src/metronome/types/v2/contract_edit_response.py b/src/metronome/types/v2/contract_edit_response.py
index c6d671161..843ed332f 100644
--- a/src/metronome/types/v2/contract_edit_response.py
+++ b/src/metronome/types/v2/contract_edit_response.py
@@ -1,10 +1,1475 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from typing import Dict, List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
from ..._models import BaseModel
-from ..shared.id import ID
+from ..shared.tier import Tier
+from ..shared.discount import Discount
+from ..shared.pro_service import ProService
+from ..shared.override_tier import OverrideTier
+from ..shared.commit_specifier import CommitSpecifier
+from ..shared.credit_type_data import CreditTypeData
+from ..shared.schedule_duration import ScheduleDuration
+from ..shared.commit_specifier_input import CommitSpecifierInput
+from ..shared.payment_gate_config_v2 import PaymentGateConfigV2
+from ..shared.schedule_point_in_time import SchedulePointInTime
+from ..shared.update_base_threshold_commit import UpdateBaseThresholdCommit
+from ..shared.commit_hierarchy_configuration import CommitHierarchyConfiguration
+from ..shared.spend_threshold_configuration_v2 import SpendThresholdConfigurationV2
+from ..shared.recurring_commit_subscription_config import RecurringCommitSubscriptionConfig
+from ..shared.prepaid_balance_threshold_configuration_v2 import PrepaidBalanceThresholdConfigurationV2
+
+__all__ = [
+ "ContractEditResponse",
+ "Data",
+ "DataEdit",
+ "DataEditAddCommit",
+ "DataEditAddCommitProduct",
+ "DataEditAddCommitInvoiceSchedule",
+ "DataEditAddCommitInvoiceScheduleScheduleItem",
+ "DataEditAddCredit",
+ "DataEditAddCreditProduct",
+ "DataEditAddOverride",
+ "DataEditAddOverrideOverrideSpecifier",
+ "DataEditAddOverrideOverwriteRate",
+ "DataEditAddOverrideProduct",
+ "DataEditAddRecurringCommit",
+ "DataEditAddRecurringCommitAccessAmount",
+ "DataEditAddRecurringCommitCommitDuration",
+ "DataEditAddRecurringCommitProduct",
+ "DataEditAddRecurringCommitContract",
+ "DataEditAddRecurringCommitInvoiceAmount",
+ "DataEditAddRecurringCredit",
+ "DataEditAddRecurringCreditAccessAmount",
+ "DataEditAddRecurringCreditCommitDuration",
+ "DataEditAddRecurringCreditProduct",
+ "DataEditAddRecurringCreditContract",
+ "DataEditAddResellerRoyalty",
+ "DataEditAddScheduledCharge",
+ "DataEditAddScheduledChargeProduct",
+ "DataEditAddSubscription",
+ "DataEditAddSubscriptionBillingPeriods",
+ "DataEditAddSubscriptionBillingPeriodsCurrent",
+ "DataEditAddSubscriptionBillingPeriodsNext",
+ "DataEditAddSubscriptionBillingPeriodsPrevious",
+ "DataEditAddSubscriptionProration",
+ "DataEditAddSubscriptionQuantitySchedule",
+ "DataEditAddSubscriptionSubscriptionRate",
+ "DataEditAddSubscriptionSubscriptionRateProduct",
+ "DataEditAddSubscriptionSeatConfig",
+ "DataEditAddUsageFilter",
+ "DataEditArchiveCommit",
+ "DataEditArchiveCredit",
+ "DataEditArchiveScheduledCharge",
+ "DataEditRemoveOverride",
+ "DataEditUpdateCommit",
+ "DataEditUpdateCommitAccessSchedule",
+ "DataEditUpdateCommitAccessScheduleAddScheduleItem",
+ "DataEditUpdateCommitAccessScheduleRemoveScheduleItem",
+ "DataEditUpdateCommitAccessScheduleUpdateScheduleItem",
+ "DataEditUpdateCommitInvoiceSchedule",
+ "DataEditUpdateCommitInvoiceScheduleAddScheduleItem",
+ "DataEditUpdateCommitInvoiceScheduleRemoveScheduleItem",
+ "DataEditUpdateCommitInvoiceScheduleUpdateScheduleItem",
+ "DataEditUpdateCredit",
+ "DataEditUpdateCreditAccessSchedule",
+ "DataEditUpdateCreditAccessScheduleAddScheduleItem",
+ "DataEditUpdateCreditAccessScheduleRemoveScheduleItem",
+ "DataEditUpdateCreditAccessScheduleUpdateScheduleItem",
+ "DataEditUpdateDiscount",
+ "DataEditUpdateDiscountSchedule",
+ "DataEditUpdateDiscountScheduleRecurringSchedule",
+ "DataEditUpdateDiscountScheduleScheduleItem",
+ "DataEditUpdatePrepaidBalanceThresholdConfiguration",
+ "DataEditUpdatePrepaidBalanceThresholdConfigurationCommit",
+ "DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration",
+ "DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap",
+ "DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier",
+ "DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude",
+ "DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter",
+ "DataEditUpdateRecurringCommit",
+ "DataEditUpdateRecurringCommitAccessAmount",
+ "DataEditUpdateRecurringCommitInvoiceAmount",
+ "DataEditUpdateRecurringCredit",
+ "DataEditUpdateRecurringCreditAccessAmount",
+ "DataEditUpdateRefundInvoice",
+ "DataEditUpdateScheduledCharge",
+ "DataEditUpdateScheduledChargeInvoiceSchedule",
+ "DataEditUpdateScheduledChargeInvoiceScheduleAddScheduleItem",
+ "DataEditUpdateScheduledChargeInvoiceScheduleRemoveScheduleItem",
+ "DataEditUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem",
+ "DataEditUpdateSpendThresholdConfiguration",
+ "DataEditUpdateSpendThresholdConfigurationDiscountConfiguration",
+ "DataEditUpdateSpendThresholdConfigurationDiscountConfigurationCap",
+ "DataEditUpdateSubscription",
+ "DataEditUpdateSubscriptionQuantityUpdate",
+ "DataEditUpdateSubscriptionSeatUpdates",
+ "DataEditUpdateSubscriptionSeatUpdatesAddSeatID",
+ "DataEditUpdateSubscriptionSeatUpdatesAddUnassignedSeat",
+ "DataEditUpdateSubscriptionSeatUpdatesRemoveSeatID",
+ "DataEditUpdateSubscriptionSeatUpdatesRemoveUnassignedSeat",
+]
+
+
+class DataEditAddCommitProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataEditAddCommitInvoiceScheduleScheduleItem(BaseModel):
+ id: str
+
+ timestamp: datetime
+
+ amount: Optional[float] = None
+
+ invoice_id: Optional[str] = None
+
+ quantity: Optional[float] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditAddCommitInvoiceSchedule(BaseModel):
+ """The schedule that the customer will be invoiced for this commit."""
+
+ credit_type: Optional[CreditTypeData] = None
+
+ do_not_invoice: Optional[bool] = None
+ """If true, this schedule will not generate an invoice."""
+
+ schedule_items: Optional[List[DataEditAddCommitInvoiceScheduleScheduleItem]] = None
+
+
+class DataEditAddCommit(BaseModel):
+ id: str
+
+ product: DataEditAddCommitProduct
+
+ type: Literal["PREPAID", "POSTPAID"]
+
+ access_schedule: Optional[ScheduleDuration] = None
+ """
+ The schedule that the customer will gain access to the credits purposed with
+ this commit.
+ """
+
+ applicable_product_ids: Optional[List[str]] = None
+
+ applicable_product_tags: Optional[List[str]] = None
+
+ description: Optional[str] = None
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for commit hierarchy access control"""
+
+ invoice_schedule: Optional[DataEditAddCommitInvoiceSchedule] = None
+ """The schedule that the customer will be invoiced for this commit."""
+
+ name: Optional[str] = None
+
+ netsuite_sales_order_id: Optional[str] = None
+ """This field's availability is dependent on your client's configuration."""
+
+ priority: Optional[float] = None
+ """
+ If multiple credits or commits are applicable, the one with the lower priority
+ will apply first.
+ """
+
+ rate_type: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None
+
+ rollover_fraction: Optional[float] = None
+
+ salesforce_opportunity_id: Optional[str] = None
+ """This field's availability is dependent on your client's configuration."""
+
+ specifiers: Optional[List[CommitSpecifierInput]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown. This field cannot
+ be used together with `applicable_product_ids` or `applicable_product_tags`.
+ Instead, to target usage by product or product tag, pass those values in the
+ body of `specifiers`.
+ """
+
+
+class DataEditAddCreditProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataEditAddCredit(BaseModel):
+ id: str
+
+ product: DataEditAddCreditProduct
+
+ type: Literal["CREDIT"]
+
+ access_schedule: Optional[ScheduleDuration] = None
+ """The schedule that the customer will gain access to the credits."""
+
+ applicable_product_ids: Optional[List[str]] = None
+
+ applicable_product_tags: Optional[List[str]] = None
+
+ description: Optional[str] = None
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for recurring credit hierarchy access control"""
+
+ name: Optional[str] = None
+
+ netsuite_sales_order_id: Optional[str] = None
+ """This field's availability is dependent on your client's configuration."""
+
+ priority: Optional[float] = None
+ """
+ If multiple credits or commits are applicable, the one with the lower priority
+ will apply first.
+ """
+
+ rate_type: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None
+
+ rollover_fraction: Optional[float] = None
+
+ salesforce_opportunity_id: Optional[str] = None
+ """This field's availability is dependent on your client's configuration."""
+
+ specifiers: Optional[List[CommitSpecifierInput]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown. This field cannot
+ be used together with `applicable_product_ids` or `applicable_product_tags`.
+ Instead, to target usage by product or product tag, pass those values in the
+ body of `specifiers`.
+ """
+
+
+class DataEditAddOverrideOverrideSpecifier(BaseModel):
+ billing_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None
+
+ commit_ids: Optional[List[str]] = None
+
+ presentation_group_values: Optional[Dict[str, Optional[str]]] = None
+
+ pricing_group_values: Optional[Dict[str, str]] = None
+
+ product_id: Optional[str] = None
+
+ product_tags: Optional[List[str]] = None
+
+ recurring_commit_ids: Optional[List[str]] = None
+
+
+class DataEditAddOverrideOverwriteRate(BaseModel):
+ rate_type: Literal["FLAT", "PERCENTAGE", "SUBSCRIPTION", "TIERED", "TIERED_PERCENTAGE", "CUSTOM"]
+
+ credit_type: Optional[CreditTypeData] = None
+
+ custom_rate: Optional[Dict[str, object]] = None
+ """Only set for CUSTOM rate_type.
+
+ This field is interpreted by custom rate processors.
+ """
+
+ is_prorated: Optional[bool] = None
+ """Default proration configuration.
+
+ Only valid for SUBSCRIPTION rate_type. Must be set to true.
+ """
+
+ price: Optional[float] = None
+ """Default price.
+
+ For FLAT rate_type, this must be >=0. For PERCENTAGE rate_type, this is a
+ decimal fraction, e.g. use 0.1 for 10%; this must be >=0 and <=1.
+ """
+
+ quantity: Optional[float] = None
+ """Default quantity. For SUBSCRIPTION rate_type, this must be >=0."""
+
+ tiers: Optional[List[Tier]] = None
+ """Only set for TIERED rate_type."""
+
+
+class DataEditAddOverrideProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataEditAddOverride(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ starting_at: datetime
+
+ applicable_product_tags: Optional[List[str]] = None
+
+ ending_before: Optional[datetime] = None
+
+ entitled: Optional[bool] = None
+
+ is_commit_specific: Optional[bool] = None
+
+ multiplier: Optional[float] = None
+
+ override_specifiers: Optional[List[DataEditAddOverrideOverrideSpecifier]] = None
+
+ override_tiers: Optional[List[OverrideTier]] = None
+
+ overwrite_rate: Optional[DataEditAddOverrideOverwriteRate] = None
+
+ priority: Optional[float] = None
+
+ product: Optional[DataEditAddOverrideProduct] = None
+
+ target: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None
+
+ type: Optional[Literal["OVERWRITE", "MULTIPLIER", "TIERED"]] = None
+
+
+class DataEditAddRecurringCommitAccessAmount(BaseModel):
+ """The amount of commit to grant."""
+
+ credit_type_id: str
+
+ unit_price: float
+
+ quantity: Optional[float] = None
+
+
+class DataEditAddRecurringCommitCommitDuration(BaseModel):
+ """The amount of time the created commits will be valid for"""
+
+ value: float
+
+ unit: Optional[Literal["PERIODS"]] = None
+
+
+class DataEditAddRecurringCommitProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataEditAddRecurringCommitContract(BaseModel):
+ id: str
+
+
+class DataEditAddRecurringCommitInvoiceAmount(BaseModel):
+ """The amount the customer should be billed for the commit. Not required."""
+
+ credit_type_id: str
+
+ quantity: float
+
+ unit_price: float
+
+
+class DataEditAddRecurringCommit(BaseModel):
+ id: str
+
+ access_amount: DataEditAddRecurringCommitAccessAmount
+ """The amount of commit to grant."""
+
+ commit_duration: DataEditAddRecurringCommitCommitDuration
+ """The amount of time the created commits will be valid for"""
+
+ priority: float
+ """Will be passed down to the individual commits"""
+
+ product: DataEditAddRecurringCommitProduct
+
+ rate_type: Literal["COMMIT_RATE", "LIST_RATE"]
+ """Whether the created commits will use the commit rate or list rate"""
+
+ starting_at: datetime
+ """Determines the start time for the first commit"""
+
+ applicable_product_ids: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ applicable_product_tags: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ contract: Optional[DataEditAddRecurringCommitContract] = None
+
+ description: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ ending_before: Optional[datetime] = None
+ """Determines when the contract will stop creating recurring commits. Optional"""
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for recurring credit hierarchy access control"""
+
+ invoice_amount: Optional[DataEditAddRecurringCommitInvoiceAmount] = None
+ """The amount the customer should be billed for the commit. Not required."""
+
+ name: Optional[str] = None
+ """Displayed on invoices. Will be passed through to the individual commits"""
+
+ netsuite_sales_order_id: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None
+ """Determines whether the first and last commit will be prorated.
+
+ If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and
+ last commits).
+ """
+
+ recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None
+ """The frequency at which the recurring commits will be created.
+
+ If not provided: - The commits will be created on the usage invoice frequency.
+ If provided: - The period defined in the duration will correspond to this
+ frequency. - Commits will be created aligned with the recurring commit's
+ starting_at rather than the usage invoice dates.
+ """
+
+ rollover_fraction: Optional[float] = None
+ """Will be passed down to the individual commits.
+
+ This controls how much of an individual unexpired commit will roll over upon
+ contract transition. Must be between 0 and 1.
+ """
+
+ specifiers: Optional[List[CommitSpecifier]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown.
+ """
+
+ subscription_config: Optional[RecurringCommitSubscriptionConfig] = None
+ """Attach a subscription to the recurring commit/credit."""
+
+
+class DataEditAddRecurringCreditAccessAmount(BaseModel):
+ """The amount of commit to grant."""
+
+ credit_type_id: str
+
+ unit_price: float
+
+ quantity: Optional[float] = None
+
+
+class DataEditAddRecurringCreditCommitDuration(BaseModel):
+ """The amount of time the created commits will be valid for"""
+
+ value: float
+
+ unit: Optional[Literal["PERIODS"]] = None
+
+
+class DataEditAddRecurringCreditProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataEditAddRecurringCreditContract(BaseModel):
+ id: str
+
+
+class DataEditAddRecurringCredit(BaseModel):
+ id: str
+
+ access_amount: DataEditAddRecurringCreditAccessAmount
+ """The amount of commit to grant."""
+
+ commit_duration: DataEditAddRecurringCreditCommitDuration
+ """The amount of time the created commits will be valid for"""
+
+ priority: float
+ """Will be passed down to the individual commits"""
+
+ product: DataEditAddRecurringCreditProduct
+
+ rate_type: Literal["COMMIT_RATE", "LIST_RATE"]
+ """Whether the created commits will use the commit rate or list rate"""
+
+ starting_at: datetime
+ """Determines the start time for the first commit"""
+
+ applicable_product_ids: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ applicable_product_tags: Optional[List[str]] = None
+ """Will be passed down to the individual commits"""
+
+ contract: Optional[DataEditAddRecurringCreditContract] = None
+
+ description: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ ending_before: Optional[datetime] = None
+ """Determines when the contract will stop creating recurring commits. Optional"""
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for recurring credit hierarchy access control"""
+
+ name: Optional[str] = None
+ """Displayed on invoices. Will be passed through to the individual commits"""
+
+ netsuite_sales_order_id: Optional[str] = None
+ """Will be passed down to the individual commits"""
+
+ proration: Optional[Literal["NONE", "FIRST", "LAST", "FIRST_AND_LAST"]] = None
+ """Determines whether the first and last commit will be prorated.
+
+ If not provided, the default is FIRST_AND_LAST (i.e. prorate both the first and
+ last commits).
+ """
+
+ recurrence_frequency: Optional[Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]] = None
+ """The frequency at which the recurring commits will be created.
+
+ If not provided: - The commits will be created on the usage invoice frequency.
+ If provided: - The period defined in the duration will correspond to this
+ frequency. - Commits will be created aligned with the recurring commit's
+ starting_at rather than the usage invoice dates.
+ """
+
+ rollover_fraction: Optional[float] = None
+ """Will be passed down to the individual commits.
+
+ This controls how much of an individual unexpired commit will roll over upon
+ contract transition. Must be between 0 and 1.
+ """
+
+ specifiers: Optional[List[CommitSpecifier]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown.
+ """
+
+ subscription_config: Optional[RecurringCommitSubscriptionConfig] = None
+ """Attach a subscription to the recurring commit/credit."""
+
+
+class DataEditAddResellerRoyalty(BaseModel):
+ reseller_type: Literal["AWS", "AWS_PRO_SERVICE", "GCP", "GCP_PRO_SERVICE"]
+
+ applicable_product_ids: Optional[List[str]] = None
+
+ applicable_product_tags: Optional[List[str]] = None
+
+ aws_account_number: Optional[str] = None
+
+ aws_offer_id: Optional[str] = None
+
+ aws_payer_reference_id: Optional[str] = None
+
+ ending_before: Optional[datetime] = None
+
+ fraction: Optional[float] = None
+
+ gcp_account_id: Optional[str] = None
+
+ gcp_offer_id: Optional[str] = None
+
+ netsuite_reseller_id: Optional[str] = None
+
+ reseller_contract_value: Optional[float] = None
+
+ starting_at: Optional[datetime] = None
+
+
+class DataEditAddScheduledChargeProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataEditAddScheduledCharge(BaseModel):
+ id: str
+
+ product: DataEditAddScheduledChargeProduct
+
+ schedule: SchedulePointInTime
+
+ name: Optional[str] = None
+ """displayed on invoices"""
+
+ netsuite_sales_order_id: Optional[str] = None
+ """This field's availability is dependent on your client's configuration."""
+
+
+class DataEditAddSubscriptionBillingPeriodsCurrent(BaseModel):
+ ending_before: datetime
+
+ starting_at: datetime
+
+
+class DataEditAddSubscriptionBillingPeriodsNext(BaseModel):
+ ending_before: datetime
+
+ starting_at: datetime
+
+
+class DataEditAddSubscriptionBillingPeriodsPrevious(BaseModel):
+ ending_before: datetime
+
+ starting_at: datetime
+
+
+class DataEditAddSubscriptionBillingPeriods(BaseModel):
+ """Previous, current, and next billing periods for the subscription."""
+
+ current: Optional[DataEditAddSubscriptionBillingPeriodsCurrent] = None
+
+ next: Optional[DataEditAddSubscriptionBillingPeriodsNext] = None
+
+ previous: Optional[DataEditAddSubscriptionBillingPeriodsPrevious] = None
+
+
+class DataEditAddSubscriptionProration(BaseModel):
+ invoice_behavior: Literal["BILL_IMMEDIATELY", "BILL_ON_NEXT_COLLECTION_DATE"]
+
+ is_prorated: bool
+
+
+class DataEditAddSubscriptionQuantitySchedule(BaseModel):
+ quantity: float
+
+ starting_at: datetime
+
+ ending_before: Optional[datetime] = None
+
+
+class DataEditAddSubscriptionSubscriptionRateProduct(BaseModel):
+ id: str
+
+ name: str
+
+
+class DataEditAddSubscriptionSubscriptionRate(BaseModel):
+ billing_frequency: Literal["MONTHLY", "QUARTERLY", "ANNUAL", "WEEKLY"]
+
+ product: DataEditAddSubscriptionSubscriptionRateProduct
+
+
+class DataEditAddSubscriptionSeatConfig(BaseModel):
+ seat_group_key: str
+ """
+ The property name, sent on usage events, that identifies the seat ID associated
+ with the usage event. For example, the property name might be seat_id or
+ user_id. The property must be set as a group key on billable metrics and a
+ presentation/pricing group key on contract products. This allows linked
+ recurring credits with an allocation per seat to be consumed by only one seat's
+ usage.
+ """
+
+
+class DataEditAddSubscription(BaseModel):
+ billing_periods: DataEditAddSubscriptionBillingPeriods
+ """Previous, current, and next billing periods for the subscription."""
+
+ collection_schedule: Literal["ADVANCE", "ARREARS"]
+
+ proration: DataEditAddSubscriptionProration
+
+ quantity_management_mode: Literal["SEAT_BASED", "QUANTITY_ONLY"]
+ """Determines how the subscription's quantity is controlled.
+
+ Defaults to QUANTITY_ONLY. **QUANTITY_ONLY**: The subscription quantity is
+ specified directly on the subscription. `initial_quantity` must be provided with
+ this option. Compatible with recurring commits/credits that use POOLED
+ allocation. **SEAT_BASED**: Use when you want to pass specific seat identifiers
+ (e.g. add user_123) to increment and decrement a subscription quantity, rather
+ than directly providing the quantity. You must use a **SEAT_BASED** subscription
+ to use a linked recurring credit with an allocation per seat. `seat_config` must
+ be provided with this option.
+ """
+
+ quantity_schedule: List[DataEditAddSubscriptionQuantitySchedule]
+ """List of quantity schedule items for the subscription.
+
+ Only includes the current quantity and future quantity changes.
+ """
+
+ starting_at: datetime
+
+ subscription_rate: DataEditAddSubscriptionSubscriptionRate
+
+ id: Optional[str] = None
+
+ custom_fields: Optional[Dict[str, str]] = None
+ """Custom fields to be added eg. { "key1": "value1", "key2": "value2" }"""
+
+ description: Optional[str] = None
+
+ ending_before: Optional[datetime] = None
+
+ fiat_credit_type_id: Optional[str] = None
+
+ name: Optional[str] = None
+
+ seat_config: Optional[DataEditAddSubscriptionSeatConfig] = None
+
+
+class DataEditAddUsageFilter(BaseModel):
+ group_key: str
+
+ group_values: List[str]
+
+ starting_at: datetime
+ """
+ This will match contract starting_at value if usage filter is active from the
+ beginning of the contract.
+ """
+
+ ending_before: Optional[datetime] = None
+ """
+ This will match contract ending_before value if usage filter is active until the
+ end of the contract. It will be undefined if the contract is open-ended.
+ """
+
+
+class DataEditArchiveCommit(BaseModel):
+ id: str
+
+
+class DataEditArchiveCredit(BaseModel):
+ id: str
+
+
+class DataEditArchiveScheduledCharge(BaseModel):
+ id: str
+
+
+class DataEditRemoveOverride(BaseModel):
+ id: str
+
+
+class DataEditUpdateCommitAccessScheduleAddScheduleItem(BaseModel):
+ amount: float
+
+ ending_before: datetime
+ """RFC 3339 timestamp (exclusive)"""
+
+ starting_at: datetime
+ """RFC 3339 timestamp (inclusive)"""
+
+
+class DataEditUpdateCommitAccessScheduleRemoveScheduleItem(BaseModel):
+ id: str
+
+
+class DataEditUpdateCommitAccessScheduleUpdateScheduleItem(BaseModel):
+ id: str
+
+ amount: Optional[float] = None
+
+ ending_before: Optional[datetime] = None
+ """RFC 3339 timestamp (exclusive)"""
+
+ starting_at: Optional[datetime] = None
+ """RFC 3339 timestamp (inclusive)"""
+
+
+class DataEditUpdateCommitAccessSchedule(BaseModel):
+ add_schedule_items: Optional[List[DataEditUpdateCommitAccessScheduleAddScheduleItem]] = None
+
+ remove_schedule_items: Optional[List[DataEditUpdateCommitAccessScheduleRemoveScheduleItem]] = None
+
+ update_schedule_items: Optional[List[DataEditUpdateCommitAccessScheduleUpdateScheduleItem]] = None
+
+
+class DataEditUpdateCommitInvoiceScheduleAddScheduleItem(BaseModel):
+ timestamp: datetime
+
+ amount: Optional[float] = None
+
+ quantity: Optional[float] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditUpdateCommitInvoiceScheduleRemoveScheduleItem(BaseModel):
+ id: str
+
+
+class DataEditUpdateCommitInvoiceScheduleUpdateScheduleItem(BaseModel):
+ id: str
+
+ amount: Optional[float] = None
+
+ quantity: Optional[float] = None
+
+ timestamp: Optional[datetime] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditUpdateCommitInvoiceSchedule(BaseModel):
+ add_schedule_items: Optional[List[DataEditUpdateCommitInvoiceScheduleAddScheduleItem]] = None
+
+ remove_schedule_items: Optional[List[DataEditUpdateCommitInvoiceScheduleRemoveScheduleItem]] = None
+
+ update_schedule_items: Optional[List[DataEditUpdateCommitInvoiceScheduleUpdateScheduleItem]] = None
+
+
+class DataEditUpdateCommit(BaseModel):
+ id: str
+
+ access_schedule: Optional[DataEditUpdateCommitAccessSchedule] = None
+
+ applicable_product_ids: Optional[List[str]] = None
+ """Which products the commit applies to.
+
+ If applicable_product_ids, applicable_product_tags or specifiers are not
+ provided, the commit applies to all products.
+ """
+
+ applicable_product_tags: Optional[List[str]] = None
+ """Which tags the commit applies to.
+
+ If applicable_product_ids, applicable_product_tags or specifiers are not
+ provided, the commit applies to all products.
+ """
+
+ description: Optional[str] = None
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for commit hierarchy access control"""
+
+ invoice_schedule: Optional[DataEditUpdateCommitInvoiceSchedule] = None
+
+ name: Optional[str] = None
+
+ netsuite_sales_order_id: Optional[str] = None
+
+ priority: Optional[float] = None
+ """
+ If multiple commits are applicable, the one with the lower priority will apply
+ first.
+ """
+
+ product_id: Optional[str] = None
+
+ rate_type: Optional[Literal["COMMIT_RATE", "LIST_RATE"]] = None
+ """If set, the commit's rate type was updated to the specified value."""
+
+ rollover_fraction: Optional[float] = None
+
+ specifiers: Optional[List[CommitSpecifierInput]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown. This field cannot
+ be used together with `applicable_product_ids` or `applicable_product_tags`.
+ Instead, to target usage by product or product tag, pass those values in the
+ body of `specifiers`.
+ """
+
+
+class DataEditUpdateCreditAccessScheduleAddScheduleItem(BaseModel):
+ amount: float
+
+ ending_before: datetime
+ """RFC 3339 timestamp (exclusive)"""
+
+ starting_at: datetime
+ """RFC 3339 timestamp (inclusive)"""
+
+
+class DataEditUpdateCreditAccessScheduleRemoveScheduleItem(BaseModel):
+ id: str
+
+
+class DataEditUpdateCreditAccessScheduleUpdateScheduleItem(BaseModel):
+ id: str
+
+ amount: Optional[float] = None
+
+ ending_before: Optional[datetime] = None
+ """RFC 3339 timestamp (exclusive)"""
+
+ starting_at: Optional[datetime] = None
+ """RFC 3339 timestamp (inclusive)"""
+
+
+class DataEditUpdateCreditAccessSchedule(BaseModel):
+ add_schedule_items: Optional[List[DataEditUpdateCreditAccessScheduleAddScheduleItem]] = None
+
+ remove_schedule_items: Optional[List[DataEditUpdateCreditAccessScheduleRemoveScheduleItem]] = None
+
+ update_schedule_items: Optional[List[DataEditUpdateCreditAccessScheduleUpdateScheduleItem]] = None
+
+
+class DataEditUpdateCredit(BaseModel):
+ id: str
+
+ access_schedule: Optional[DataEditUpdateCreditAccessSchedule] = None
+
+ applicable_product_ids: Optional[List[str]] = None
+ """Which products the credit applies to.
+
+ If applicable_product_ids, applicable_product_tags or specifiers are not
+ provided, the credit applies to all products.
+ """
+
+ applicable_product_tags: Optional[List[str]] = None
+ """Which tags the credit applies to.
+
+ If applicable_product_ids, applicable_product_tags or specifiers are not
+ provided, the credit applies to all products.
+ """
+
+ description: Optional[str] = None
+
+ hierarchy_configuration: Optional[CommitHierarchyConfiguration] = None
+ """Optional configuration for credit hierarchy access control"""
+
+ name: Optional[str] = None
+
+ netsuite_sales_order_id: Optional[str] = None
+
+ priority: Optional[float] = None
+ """
+ If multiple credits are applicable, the one with the lower priority will apply
+ first.
+ """
+
+ product_id: Optional[str] = None
+
+ rate_type: Optional[Literal["LIST_RATE", "COMMIT_RATE"]] = None
+ """If set, the credit's rate type was updated to the specified value."""
+
+ rollover_fraction: Optional[float] = None
+
+ specifiers: Optional[List[CommitSpecifierInput]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown. This field cannot
+ be used together with `applicable_product_ids` or `applicable_product_tags`.
+ Instead, to target usage by product or product tag, pass those values in the
+ body of `specifiers`.
+ """
+
+
+class DataEditUpdateDiscountScheduleRecurringSchedule(BaseModel):
+ """Enter the unit price and quantity for the charge or instead only send the amount.
+
+ If amount is sent, the unit price is assumed to be the amount and quantity is inferred to be 1.
+ """
+
+ amount_distribution: Literal["DIVIDED", "DIVIDED_ROUNDED", "EACH"]
+
+ ending_before: datetime
+ """RFC 3339 timestamp (exclusive)."""
+
+ frequency: Literal["MONTHLY", "QUARTERLY", "SEMI_ANNUAL", "ANNUAL", "WEEKLY"]
+
+ starting_at: datetime
+ """RFC 3339 timestamp (inclusive)."""
+
+ amount: Optional[float] = None
+ """Amount for the charge.
+
+ Can be provided instead of unit_price and quantity. If amount is sent, the
+ unit_price is assumed to be the amount and quantity is inferred to be 1.
+ """
+
+ quantity: Optional[float] = None
+ """Quantity for the charge.
+
+ Will be multiplied by unit_price to determine the amount and must be specified
+ with unit_price. If specified amount cannot be provided.
+ """
+
+ unit_price: Optional[float] = None
+ """Unit price for the charge.
+
+ Will be multiplied by quantity to determine the amount and must be specified
+ with quantity. If specified amount cannot be provided.
+ """
+
+
+class DataEditUpdateDiscountScheduleScheduleItem(BaseModel):
+ timestamp: datetime
+ """timestamp of the scheduled event"""
+
+ amount: Optional[float] = None
+ """Amount for the charge.
+
+ Can be provided instead of unit_price and quantity. If amount is sent, the
+ unit_price is assumed to be the amount and quantity is inferred to be 1.
+ """
+
+ quantity: Optional[float] = None
+ """Quantity for the charge.
+
+ Will be multiplied by unit_price to determine the amount and must be specified
+ with unit_price. If specified amount cannot be provided.
+ """
+
+ unit_price: Optional[float] = None
+ """Unit price for the charge.
+
+ Will be multiplied by quantity to determine the amount and must be specified
+ with quantity. If specified amount cannot be provided.
+ """
+
+
+class DataEditUpdateDiscountSchedule(BaseModel):
+ """Must provide either schedule_items or recurring_schedule."""
+
+ credit_type_id: Optional[str] = None
+ """Defaults to USD (cents) if not passed."""
+
+ do_not_invoice: Optional[bool] = None
+ """This field is only applicable to commit invoice schedules.
+
+ If true, this schedule will not generate an invoice.
+ """
+
+ recurring_schedule: Optional[DataEditUpdateDiscountScheduleRecurringSchedule] = None
+ """Enter the unit price and quantity for the charge or instead only send the
+ amount.
+
+ If amount is sent, the unit price is assumed to be the amount and quantity is
+ inferred to be 1.
+ """
+
+ schedule_items: Optional[List[DataEditUpdateDiscountScheduleScheduleItem]] = None
+ """Either provide amount or provide both unit_price and quantity."""
+
+
+class DataEditUpdateDiscount(BaseModel):
+ id: str
+
+ custom_fields: Optional[Dict[str, str]] = None
+ """Custom fields to be added eg. { "key1": "value1", "key2": "value2" }"""
+
+ name: Optional[str] = None
+
+ netsuite_sales_order_id: Optional[str] = None
+
+ schedule: Optional[DataEditUpdateDiscountSchedule] = None
+ """Must provide either schedule_items or recurring_schedule."""
+
+
+class DataEditUpdatePrepaidBalanceThresholdConfigurationCommit(UpdateBaseThresholdCommit):
+ applicable_product_ids: Optional[List[str]] = None
+ """Which products the threshold commit applies to.
+
+ If both applicable_product_ids and applicable_product_tags are not provided, the
+ commit applies to all products.
+ """
+
+ applicable_product_tags: Optional[List[str]] = None
+ """Which tags the threshold commit applies to.
+
+ If both applicable_product_ids and applicable_product_tags are not provided, the
+ commit applies to all products.
+ """
+
+ specifiers: Optional[List[CommitSpecifierInput]] = None
+ """
+ List of filters that determine what kind of customer usage draws down a commit
+ or credit. A customer's usage needs to meet the condition of at least one of the
+ specifiers to contribute to a commit's or credit's drawdown. This field cannot
+ be used together with `applicable_product_ids` or `applicable_product_tags`.
+ Instead, to target usage by product or product tag, pass those values in the
+ body of `specifiers`.
+ """
+
+
+class DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap(BaseModel):
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
+
+
+class DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(BaseModel):
+ cap: Optional[DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap] = None
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ payment_fraction: Optional[float] = None
+ """
+ The fraction of the original amount that the customer pays after applying the
+ discount. Set to null to remove the discount fraction. For example, 0.85 means
+ the customer pays 85% of the original amount (a 15% discount).
+ """
+
+
+class DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel):
+ entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]
+
+ key: str
+
+ value: str
+
+
+class DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude(BaseModel):
+ custom_field_filters: List[
+ DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter
+ ]
+
+
+class DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier(BaseModel):
+ exclude: List[DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude]
+
+
+class DataEditUpdatePrepaidBalanceThresholdConfiguration(BaseModel):
+ commit: Optional[DataEditUpdatePrepaidBalanceThresholdConfigurationCommit] = None
+
+ custom_credit_type_id: Optional[str] = None
+ """
+ If provided, the threshold, recharge-to amount, and the resulting threshold
+ commit amount will be in terms of this credit type instead of the fiat currency.
+ """
+
+ discount_configuration: Optional[DataEditUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration] = None
+
+ is_enabled: Optional[bool] = None
+ """
+ When set to false, the contract will not be evaluated against the
+ threshold_amount. Toggling to true will result an immediate evaluation,
+ regardless of prior state.
+ """
+
+ payment_gate_config: Optional[PaymentGateConfigV2] = None
+
+ recharge_to_amount: Optional[float] = None
+ """Specify the amount the balance should be recharged to."""
+
+ threshold_amount: Optional[float] = None
+ """Specify the threshold amount for the contract.
+
+ Each time the contract's balance lowers to this amount, a threshold charge will
+ be initiated.
+ """
+
+ threshold_balance_specifiers: Optional[
+ List[DataEditUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier]
+ ] = None
+
+
+class DataEditUpdateRecurringCommitAccessAmount(BaseModel):
+ quantity: Optional[float] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditUpdateRecurringCommitInvoiceAmount(BaseModel):
+ quantity: Optional[float] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditUpdateRecurringCommit(BaseModel):
+ id: str
+
+ access_amount: Optional[DataEditUpdateRecurringCommitAccessAmount] = None
+
+ ending_before: Optional[datetime] = None
+
+ invoice_amount: Optional[DataEditUpdateRecurringCommitInvoiceAmount] = None
+
+ rate_type: Optional[Literal["LIST_RATE", "COMMIT_RATE"]] = None
+
+
+class DataEditUpdateRecurringCreditAccessAmount(BaseModel):
+ quantity: Optional[float] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditUpdateRecurringCredit(BaseModel):
+ id: str
+
+ access_amount: Optional[DataEditUpdateRecurringCreditAccessAmount] = None
+
+ ending_before: Optional[datetime] = None
+
+ rate_type: Optional[Literal["LIST_RATE", "COMMIT_RATE"]] = None
+
+
+class DataEditUpdateRefundInvoice(BaseModel):
+ date: datetime
+
+ invoice_id: str
+
+
+class DataEditUpdateScheduledChargeInvoiceScheduleAddScheduleItem(BaseModel):
+ timestamp: datetime
+
+ amount: Optional[float] = None
+
+ quantity: Optional[float] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditUpdateScheduledChargeInvoiceScheduleRemoveScheduleItem(BaseModel):
+ id: str
+
+
+class DataEditUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem(BaseModel):
+ id: str
+
+ amount: Optional[float] = None
+
+ quantity: Optional[float] = None
+
+ timestamp: Optional[datetime] = None
+
+ unit_price: Optional[float] = None
+
+
+class DataEditUpdateScheduledChargeInvoiceSchedule(BaseModel):
+ add_schedule_items: Optional[List[DataEditUpdateScheduledChargeInvoiceScheduleAddScheduleItem]] = None
+
+ remove_schedule_items: Optional[List[DataEditUpdateScheduledChargeInvoiceScheduleRemoveScheduleItem]] = None
+
+ update_schedule_items: Optional[List[DataEditUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem]] = None
+
+
+class DataEditUpdateScheduledCharge(BaseModel):
+ id: str
+
+ invoice_schedule: Optional[DataEditUpdateScheduledChargeInvoiceSchedule] = None
+
+ name: Optional[str] = None
+
+ netsuite_sales_order_id: Optional[str] = None
+
+
+class DataEditUpdateSpendThresholdConfigurationDiscountConfigurationCap(BaseModel):
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
+
+
+class DataEditUpdateSpendThresholdConfigurationDiscountConfiguration(BaseModel):
+ cap: Optional[DataEditUpdateSpendThresholdConfigurationDiscountConfigurationCap] = None
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ payment_fraction: Optional[float] = None
+ """
+ The fraction of the original amount that the customer pays after applying the
+ discount. Set to null to remove the discount fraction. For example, 0.85 means
+ the customer pays 85% of the original amount (a 15% discount).
+ """
+
+
+class DataEditUpdateSpendThresholdConfiguration(BaseModel):
+ commit: Optional[UpdateBaseThresholdCommit] = None
+
+ discount_configuration: Optional[DataEditUpdateSpendThresholdConfigurationDiscountConfiguration] = None
+
+ is_enabled: Optional[bool] = None
+ """
+ When set to false, the contract will not be evaluated against the
+ threshold_amount. Toggling to true will result an immediate evaluation,
+ regardless of prior state.
+ """
+
+ payment_gate_config: Optional[PaymentGateConfigV2] = None
+
+ threshold_amount: Optional[float] = None
+ """Specify the threshold amount for the contract.
+
+ Each time the contract's usage hits this amount, a threshold charge will be
+ initiated.
+ """
+
+
+class DataEditUpdateSubscriptionQuantityUpdate(BaseModel):
+ starting_at: datetime
+
+ quantity: Optional[float] = None
+
+ quantity_delta: Optional[float] = None
+
+
+class DataEditUpdateSubscriptionSeatUpdatesAddSeatID(BaseModel):
+ seat_ids: List[str]
+
+ starting_at: datetime
+ """Assigned seats will be added/removed starting at this date."""
+
+
+class DataEditUpdateSubscriptionSeatUpdatesAddUnassignedSeat(BaseModel):
+ quantity: float
+ """
+ The number of unassigned seats on the subscription will increase/decrease by
+ this delta. Must be greater than 0.
+ """
+
+ starting_at: datetime
+ """Unassigned seats will be updated starting at this date."""
+
+
+class DataEditUpdateSubscriptionSeatUpdatesRemoveSeatID(BaseModel):
+ seat_ids: List[str]
+
+ starting_at: datetime
+ """Assigned seats will be added/removed starting at this date."""
+
+
+class DataEditUpdateSubscriptionSeatUpdatesRemoveUnassignedSeat(BaseModel):
+ quantity: float
+ """
+ The number of unassigned seats on the subscription will increase/decrease by
+ this delta. Must be greater than 0.
+ """
+
+ starting_at: datetime
+ """Unassigned seats will be updated starting at this date."""
+
+
+class DataEditUpdateSubscriptionSeatUpdates(BaseModel):
+ """Manage subscription seats for subscriptions in SEAT_BASED mode."""
+
+ add_seat_ids: Optional[List[DataEditUpdateSubscriptionSeatUpdatesAddSeatID]] = None
+ """Adds seat IDs to the subscription.
+
+ If there are unassigned seats, the new seat IDs will fill these unassigned seats
+ and not increase the total subscription quantity. Otherwise, if there are more
+ new seat IDs than unassigned seats, the total subscription quantity will
+ increase.
+ """
+
+ add_unassigned_seats: Optional[List[DataEditUpdateSubscriptionSeatUpdatesAddUnassignedSeat]] = None
+ """Adds unassigned seats to the subscription.
+
+ This will increase the total subscription quantity.
+ """
+
+ remove_seat_ids: Optional[List[DataEditUpdateSubscriptionSeatUpdatesRemoveSeatID]] = None
+ """Removes seat IDs from the subscription, if possible.
+
+ If a seat ID is removed, the total subscription quantity will decrease.
+ Otherwise, if the seat ID is not found on the subscription, this is a no-op.
+ """
+
+ remove_unassigned_seats: Optional[List[DataEditUpdateSubscriptionSeatUpdatesRemoveUnassignedSeat]] = None
+ """Removes unassigned seats from the subscription.
+
+ This will decrease the total subscription quantity if there are are unassigned
+ seats.
+ """
+
+
+class DataEditUpdateSubscription(BaseModel):
+ id: str
+
+ ending_before: Optional[datetime] = None
+
+ quantity_updates: Optional[List[DataEditUpdateSubscriptionQuantityUpdate]] = None
+
+ seat_updates: Optional[DataEditUpdateSubscriptionSeatUpdates] = None
+ """Manage subscription seats for subscriptions in SEAT_BASED mode."""
+
+
+class DataEdit(BaseModel):
+ id: str
+
+ add_commits: Optional[List[DataEditAddCommit]] = None
+
+ add_credits: Optional[List[DataEditAddCredit]] = None
+
+ add_discounts: Optional[List[Discount]] = None
+
+ add_overrides: Optional[List[DataEditAddOverride]] = None
+
+ add_prepaid_balance_threshold_configuration: Optional[PrepaidBalanceThresholdConfigurationV2] = None
+
+ add_pro_services: Optional[List[ProService]] = None
+
+ add_recurring_commits: Optional[List[DataEditAddRecurringCommit]] = None
+
+ add_recurring_credits: Optional[List[DataEditAddRecurringCredit]] = None
+
+ add_reseller_royalties: Optional[List[DataEditAddResellerRoyalty]] = None
+
+ add_scheduled_charges: Optional[List[DataEditAddScheduledCharge]] = None
+
+ add_spend_threshold_configuration: Optional[SpendThresholdConfigurationV2] = None
+
+ add_subscriptions: Optional[List[DataEditAddSubscription]] = None
+ """List of subscriptions on the contract."""
+
+ add_usage_filters: Optional[List[DataEditAddUsageFilter]] = None
+
+ archive_commits: Optional[List[DataEditArchiveCommit]] = None
+
+ archive_credits: Optional[List[DataEditArchiveCredit]] = None
+
+ archive_scheduled_charges: Optional[List[DataEditArchiveScheduledCharge]] = None
+
+ remove_overrides: Optional[List[DataEditRemoveOverride]] = None
+
+ timestamp: Optional[datetime] = None
+
+ uniqueness_key: Optional[str] = None
+ """Prevents the creation of duplicates.
+
+ If a request to create a record is made with a previously used uniqueness key, a
+ new record will not be created and the request will fail with a 409 error.
+ """
+
+ update_commits: Optional[List[DataEditUpdateCommit]] = None
+
+ update_contract_end_date: Optional[datetime] = None
+
+ update_contract_name: Optional[str] = None
+ """Value to update the contract name to.
+
+ If not provided, the contract name will remain unchanged.
+ """
+
+ update_credits: Optional[List[DataEditUpdateCredit]] = None
+
+ update_discounts: Optional[List[DataEditUpdateDiscount]] = None
+
+ update_prepaid_balance_threshold_configuration: Optional[DataEditUpdatePrepaidBalanceThresholdConfiguration] = None
+
+ update_recurring_commits: Optional[List[DataEditUpdateRecurringCommit]] = None
+
+ update_recurring_credits: Optional[List[DataEditUpdateRecurringCredit]] = None
+
+ update_refund_invoices: Optional[List[DataEditUpdateRefundInvoice]] = None
+
+ update_scheduled_charges: Optional[List[DataEditUpdateScheduledCharge]] = None
+
+ update_spend_threshold_configuration: Optional[DataEditUpdateSpendThresholdConfiguration] = None
+
+ update_subscriptions: Optional[List[DataEditUpdateSubscription]] = None
+ """Optional list of subscriptions to update."""
+
+
+class Data(BaseModel):
+ id: str
-__all__ = ["ContractEditResponse"]
+ edit: Optional[DataEdit] = None
class ContractEditResponse(BaseModel):
- data: ID
+ data: Data
diff --git a/src/metronome/types/v2/contract_get_edit_history_response.py b/src/metronome/types/v2/contract_get_edit_history_response.py
index ebb37fb35..a2f598079 100644
--- a/src/metronome/types/v2/contract_get_edit_history_response.py
+++ b/src/metronome/types/v2/contract_get_edit_history_response.py
@@ -84,6 +84,10 @@
"DataUpdatePrepaidBalanceThresholdConfiguration",
"DataUpdatePrepaidBalanceThresholdConfigurationCommit",
"DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration",
+ "DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap",
+ "DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier",
+ "DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude",
+ "DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter",
"DataUpdateRecurringCommit",
"DataUpdateRecurringCommitAccessAmount",
"DataUpdateRecurringCommitInvoiceAmount",
@@ -97,6 +101,7 @@
"DataUpdateScheduledChargeInvoiceScheduleUpdateScheduleItem",
"DataUpdateSpendThresholdConfiguration",
"DataUpdateSpendThresholdConfigurationDiscountConfiguration",
+ "DataUpdateSpendThresholdConfigurationDiscountConfigurationCap",
"DataUpdateSubscription",
"DataUpdateSubscriptionQuantityUpdate",
"DataUpdateSubscriptionSeatUpdates",
@@ -1085,7 +1090,20 @@ class DataUpdatePrepaidBalanceThresholdConfigurationCommit(UpdateBaseThresholdCo
"""
+class DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap(BaseModel):
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
+
+
class DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(BaseModel):
+ cap: Optional[DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfigurationCap] = None
+ """Update the discount cap. Set to null to remove an existing cap."""
+
payment_fraction: Optional[float] = None
"""
The fraction of the original amount that the customer pays after applying the
@@ -1094,6 +1112,24 @@ class DataUpdatePrepaidBalanceThresholdConfigurationDiscountConfiguration(BaseMo
"""
+class DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter(BaseModel):
+ entity: Literal["Commit", "ContractCredit", "ContractCreditOrCommit"]
+
+ key: str
+
+ value: str
+
+
+class DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude(BaseModel):
+ custom_field_filters: List[
+ DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExcludeCustomFieldFilter
+ ]
+
+
+class DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier(BaseModel):
+ exclude: List[DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifierExclude]
+
+
class DataUpdatePrepaidBalanceThresholdConfiguration(BaseModel):
commit: Optional[DataUpdatePrepaidBalanceThresholdConfigurationCommit] = None
@@ -1124,6 +1160,10 @@ class DataUpdatePrepaidBalanceThresholdConfiguration(BaseModel):
be initiated.
"""
+ threshold_balance_specifiers: Optional[
+ List[DataUpdatePrepaidBalanceThresholdConfigurationThresholdBalanceSpecifier]
+ ] = None
+
class DataUpdateRecurringCommitAccessAmount(BaseModel):
quantity: Optional[float] = None
@@ -1215,7 +1255,20 @@ class DataUpdateScheduledCharge(BaseModel):
netsuite_sales_order_id: Optional[str] = None
+class DataUpdateSpendThresholdConfigurationDiscountConfigurationCap(BaseModel):
+ """Update the discount cap. Set to null to remove an existing cap."""
+
+ amount: float
+ """Accumulated spend ceiling above which the discount stops applying."""
+
+ spend_tracker_alias: str
+ """Alias of the spend tracker this cap is measured against."""
+
+
class DataUpdateSpendThresholdConfigurationDiscountConfiguration(BaseModel):
+ cap: Optional[DataUpdateSpendThresholdConfigurationDiscountConfigurationCap] = None
+ """Update the discount cap. Set to null to remove an existing cap."""
+
payment_fraction: Optional[float] = None
"""
The fraction of the original amount that the customer pays after applying the
diff --git a/tests/api_resources/v1/test_contracts.py b/tests/api_resources/v1/test_contracts.py
index 7e0205e88..11ae3f1c5 100644
--- a/tests/api_resources/v1/test_contracts.py
+++ b/tests/api_resources/v1/test_contracts.py
@@ -105,6 +105,7 @@ def test_method_create_with_all_params(self, client: Metronome) -> None:
"product_tags": ["string"],
}
],
+ "spend_tracker_attributes": {"counts_as_discounted": True},
"temporary_id": "temporary_id",
}
],
@@ -265,7 +266,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None:
"recharge_to_amount": 0,
"threshold_amount": 0,
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
professional_services=[
{
@@ -445,8 +467,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None:
"tax_type": "NONE",
},
"threshold_amount": 0,
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
},
+ spend_trackers=[
+ {
+ "alias": "alias",
+ "applicable_spend_specifiers": [
+ {
+ "sources": ["THRESHOLD_RECHARGE"],
+ "spend_type": "COMMIT_PURCHASE",
+ "discounted": "ANY",
+ }
+ ],
+ "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "reset_frequency": "BILLING_PERIOD",
+ }
+ ],
subscriptions=[
{
"collection_schedule": "ADVANCE",
@@ -733,6 +775,7 @@ def test_method_amend_with_all_params(self, client: Metronome) -> None:
"product_tags": ["string"],
}
],
+ "spend_tracker_attributes": {"counts_as_discounted": True},
"temporary_id": "temporary_id",
}
],
@@ -1532,6 +1575,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome)
"product_tags": ["string"],
}
],
+ "spend_tracker_attributes": {"counts_as_discounted": True},
"temporary_id": "temporary_id",
}
],
@@ -1692,7 +1736,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome)
"recharge_to_amount": 0,
"threshold_amount": 0,
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
professional_services=[
{
@@ -1872,8 +1937,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome)
"tax_type": "NONE",
},
"threshold_amount": 0,
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
},
+ spend_trackers=[
+ {
+ "alias": "alias",
+ "applicable_spend_specifiers": [
+ {
+ "sources": ["THRESHOLD_RECHARGE"],
+ "spend_type": "COMMIT_PURCHASE",
+ "discounted": "ANY",
+ }
+ ],
+ "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "reset_frequency": "BILLING_PERIOD",
+ }
+ ],
subscriptions=[
{
"collection_schedule": "ADVANCE",
@@ -2160,6 +2245,7 @@ async def test_method_amend_with_all_params(self, async_client: AsyncMetronome)
"product_tags": ["string"],
}
],
+ "spend_tracker_attributes": {"counts_as_discounted": True},
"temporary_id": "temporary_id",
}
],
diff --git a/tests/api_resources/v1/test_packages.py b/tests/api_resources/v1/test_packages.py
index 91a5625e7..b78c6ed4d 100644
--- a/tests/api_resources/v1/test_packages.py
+++ b/tests/api_resources/v1/test_packages.py
@@ -223,7 +223,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None:
"recharge_to_amount": 0,
"threshold_amount": 0,
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
rate_card_alias="rate_card_alias",
rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc",
@@ -364,8 +385,28 @@ def test_method_create_with_all_params(self, client: Metronome) -> None:
"tax_type": "NONE",
},
"threshold_amount": 0,
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
},
+ spend_trackers=[
+ {
+ "alias": "alias",
+ "applicable_spend_specifiers": [
+ {
+ "sources": ["THRESHOLD_RECHARGE"],
+ "spend_type": "COMMIT_PURCHASE",
+ "discounted": "ANY",
+ }
+ ],
+ "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "reset_frequency": "BILLING_PERIOD",
+ }
+ ],
subscriptions=[
{
"collection_schedule": "ADVANCE",
@@ -776,7 +817,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome)
"recharge_to_amount": 0,
"threshold_amount": 0,
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
rate_card_alias="rate_card_alias",
rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc",
@@ -917,8 +979,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncMetronome)
"tax_type": "NONE",
},
"threshold_amount": 0,
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
},
+ spend_trackers=[
+ {
+ "alias": "alias",
+ "applicable_spend_specifiers": [
+ {
+ "sources": ["THRESHOLD_RECHARGE"],
+ "spend_type": "COMMIT_PURCHASE",
+ "discounted": "ANY",
+ }
+ ],
+ "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "reset_frequency": "BILLING_PERIOD",
+ }
+ ],
subscriptions=[
{
"collection_schedule": "ADVANCE",
diff --git a/tests/api_resources/v1/test_payments.py b/tests/api_resources/v1/test_payments.py
deleted file mode 100644
index a2285538c..000000000
--- a/tests/api_resources/v1/test_payments.py
+++ /dev/null
@@ -1,255 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from metronome import Metronome, AsyncMetronome
-from tests.utils import assert_matches_type
-from metronome.types.v1 import (
- Payment,
- PaymentCancelResponse,
- PaymentAttemptResponse,
-)
-from metronome.pagination import SyncBodyCursorPage, AsyncBodyCursorPage
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestPayments:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_list(self, client: Metronome) -> None:
- payment = client.v1.payments.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
- assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Metronome) -> None:
- payment = client.v1.payments.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- limit=1,
- next_page="next_page",
- statuses=["pending", "requires_intervention"],
- )
- assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Metronome) -> None:
- response = client.v1.payments.with_raw_response.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- payment = response.parse()
- assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Metronome) -> None:
- with client.v1.payments.with_streaming_response.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- payment = response.parse()
- assert_matches_type(SyncBodyCursorPage[Payment], payment, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_attempt(self, client: Metronome) -> None:
- payment = client.v1.payments.attempt(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
- assert_matches_type(PaymentAttemptResponse, payment, path=["response"])
-
- @parametrize
- def test_raw_response_attempt(self, client: Metronome) -> None:
- response = client.v1.payments.with_raw_response.attempt(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- payment = response.parse()
- assert_matches_type(PaymentAttemptResponse, payment, path=["response"])
-
- @parametrize
- def test_streaming_response_attempt(self, client: Metronome) -> None:
- with client.v1.payments.with_streaming_response.attempt(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- payment = response.parse()
- assert_matches_type(PaymentAttemptResponse, payment, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_cancel(self, client: Metronome) -> None:
- payment = client.v1.payments.cancel(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
- assert_matches_type(PaymentCancelResponse, payment, path=["response"])
-
- @parametrize
- def test_raw_response_cancel(self, client: Metronome) -> None:
- response = client.v1.payments.with_raw_response.cancel(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- payment = response.parse()
- assert_matches_type(PaymentCancelResponse, payment, path=["response"])
-
- @parametrize
- def test_streaming_response_cancel(self, client: Metronome) -> None:
- with client.v1.payments.with_streaming_response.cancel(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- payment = response.parse()
- assert_matches_type(PaymentCancelResponse, payment, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncPayments:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncMetronome) -> None:
- payment = await async_client.v1.payments.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
- assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncMetronome) -> None:
- payment = await async_client.v1.payments.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- limit=1,
- next_page="next_page",
- statuses=["pending", "requires_intervention"],
- )
- assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncMetronome) -> None:
- response = await async_client.v1.payments.with_raw_response.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- payment = await response.parse()
- assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncMetronome) -> None:
- async with async_client.v1.payments.with_streaming_response.list(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- payment = await response.parse()
- assert_matches_type(AsyncBodyCursorPage[Payment], payment, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_attempt(self, async_client: AsyncMetronome) -> None:
- payment = await async_client.v1.payments.attempt(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
- assert_matches_type(PaymentAttemptResponse, payment, path=["response"])
-
- @parametrize
- async def test_raw_response_attempt(self, async_client: AsyncMetronome) -> None:
- response = await async_client.v1.payments.with_raw_response.attempt(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- payment = await response.parse()
- assert_matches_type(PaymentAttemptResponse, payment, path=["response"])
-
- @parametrize
- async def test_streaming_response_attempt(self, async_client: AsyncMetronome) -> None:
- async with async_client.v1.payments.with_streaming_response.attempt(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- payment = await response.parse()
- assert_matches_type(PaymentAttemptResponse, payment, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_cancel(self, async_client: AsyncMetronome) -> None:
- payment = await async_client.v1.payments.cancel(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
- assert_matches_type(PaymentCancelResponse, payment, path=["response"])
-
- @parametrize
- async def test_raw_response_cancel(self, async_client: AsyncMetronome) -> None:
- response = await async_client.v1.payments.with_raw_response.cancel(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- payment = await response.parse()
- assert_matches_type(PaymentCancelResponse, payment, path=["response"])
-
- @parametrize
- async def test_streaming_response_cancel(self, async_client: AsyncMetronome) -> None:
- async with async_client.v1.payments.with_streaming_response.cancel(
- customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d",
- invoice_id="6162d87b-e5db-4a33-b7f2-76ce6ead4e85",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- payment = await response.parse()
- assert_matches_type(PaymentCancelResponse, payment, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/v2/test_contracts.py b/tests/api_resources/v2/test_contracts.py
index 765e06fd4..96cc07cdb 100644
--- a/tests/api_resources/v2/test_contracts.py
+++ b/tests/api_resources/v2/test_contracts.py
@@ -201,6 +201,7 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None:
"product_tags": ["string"],
}
],
+ "spend_tracker_attributes": {"counts_as_discounted": True},
"temporary_id": "temporary_id",
}
],
@@ -344,7 +345,28 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None:
"recharge_to_amount": 0,
"threshold_amount": 0,
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
add_professional_services=[
{
@@ -523,8 +545,28 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None:
"tax_type": "NONE",
},
"threshold_amount": 0,
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
},
+ add_spend_trackers=[
+ {
+ "alias": "alias",
+ "applicable_spend_specifiers": [
+ {
+ "sources": ["THRESHOLD_RECHARGE"],
+ "spend_type": "COMMIT_PURCHASE",
+ "discounted": "ANY",
+ }
+ ],
+ "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "reset_frequency": "BILLING_PERIOD",
+ }
+ ],
add_subscriptions=[
{
"collection_schedule": "ADVANCE",
@@ -555,6 +597,7 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None:
archive_commits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
archive_credits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
archive_scheduled_charges=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
+ archive_spend_trackers=["string"],
remove_overrides=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
uniqueness_key="x",
update_commits=[
@@ -664,7 +707,13 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None:
],
},
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ "payment_fraction": 0,
+ },
"is_enabled": True,
"payment_gate_config": {
"payment_gate_type": "NONE",
@@ -680,6 +729,21 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None:
},
"recharge_to_amount": 0,
"threshold_amount": 0,
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
update_recurring_commits=[
{
@@ -740,7 +804,13 @@ def test_method_edit_with_all_params(self, client: Metronome) -> None:
"priority": 0,
"product_id": "product_id",
},
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ "payment_fraction": 0,
+ },
"is_enabled": True,
"payment_gate_config": {
"payment_gate_type": "NONE",
@@ -1217,6 +1287,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) -
"product_tags": ["string"],
}
],
+ "spend_tracker_attributes": {"counts_as_discounted": True},
"temporary_id": "temporary_id",
}
],
@@ -1360,7 +1431,28 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) -
"recharge_to_amount": 0,
"threshold_amount": 0,
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
add_professional_services=[
{
@@ -1539,8 +1631,28 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) -
"tax_type": "NONE",
},
"threshold_amount": 0,
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "payment_fraction": 0,
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ },
},
+ add_spend_trackers=[
+ {
+ "alias": "alias",
+ "applicable_spend_specifiers": [
+ {
+ "sources": ["THRESHOLD_RECHARGE"],
+ "spend_type": "COMMIT_PURCHASE",
+ "discounted": "ANY",
+ }
+ ],
+ "credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "reset_frequency": "BILLING_PERIOD",
+ }
+ ],
add_subscriptions=[
{
"collection_schedule": "ADVANCE",
@@ -1571,6 +1683,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) -
archive_commits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
archive_credits=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
archive_scheduled_charges=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
+ archive_spend_trackers=["string"],
remove_overrides=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}],
uniqueness_key="x",
update_commits=[
@@ -1680,7 +1793,13 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) -
],
},
"custom_credit_type_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ "payment_fraction": 0,
+ },
"is_enabled": True,
"payment_gate_config": {
"payment_gate_type": "NONE",
@@ -1696,6 +1815,21 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) -
},
"recharge_to_amount": 0,
"threshold_amount": 0,
+ "threshold_balance_specifiers": [
+ {
+ "exclude": [
+ {
+ "custom_field_filters": [
+ {
+ "entity": "Commit",
+ "key": "key",
+ "value": "value",
+ }
+ ]
+ }
+ ]
+ }
+ ],
},
update_recurring_commits=[
{
@@ -1756,7 +1890,13 @@ async def test_method_edit_with_all_params(self, async_client: AsyncMetronome) -
"priority": 0,
"product_id": "product_id",
},
- "discount_configuration": {"payment_fraction": 0},
+ "discount_configuration": {
+ "cap": {
+ "amount": 0,
+ "spend_tracker_alias": "spend_tracker_alias",
+ },
+ "payment_fraction": 0,
+ },
"is_enabled": True,
"payment_gate_config": {
"payment_gate_type": "NONE",