diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2ee47b6d..4ddd2d14 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,12 +1,14 @@
name: CI
on:
push:
- branches-ignore:
- - 'generated'
- - 'codegen/**'
- - 'integrated/**'
- - 'stl-preview-head/**'
- - 'stl-preview-base/**'
+ branches:
+ - '**'
+ - '!integrated/**'
+ - '!stl-preview-head/**'
+ - '!stl-preview-base/**'
+ - '!generated'
+ - '!codegen/**'
+ - 'codegen/stl/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
@@ -17,7 +19,7 @@ jobs:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/orb-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6
@@ -36,7 +38,7 @@ jobs:
run: ./scripts/lint
build:
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
timeout-minutes: 10
name: build
permissions:
@@ -61,14 +63,18 @@ jobs:
run: rye build
- name: Get GitHub OIDC Token
- if: github.repository == 'stainless-sdks/orb-python'
+ if: |-
+ github.repository == 'stainless-sdks/orb-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());
- name: Upload tarball
- if: github.repository == 'stainless-sdks/orb-python'
+ if: |-
+ github.repository == 'stainless-sdks/orb-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
diff --git a/.gitignore b/.gitignore
index 95ceb189..3824f4c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.prism.log
+.stdy.log
_dev
__pycache__
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index c3d8acd5..331e8361 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.55.0"
+ ".": "4.56.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index c80eee48..345cd65b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 139
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-c92fb451e13f157b3735f188acc8d57aa3adfbaac1683645e1ba4f432dd7a4f8.yml
-openapi_spec_hash: dbcd87ecfbd3976eb3b99ec6f9fbc606
-config_hash: 3279841440b02d4e8303c961d6983492
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb/orb-7f97a69f22372b818e8d24a72f6020bcf2f0c6d6b3ad07abb8395c87ec4a72ee.yml
+openapi_spec_hash: a6261e730c54d08ad36f1b946e663fc3
+config_hash: c01c1191b1cd696c7ca855ff6d28a8df
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6c03365a..42415419 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,79 @@
# Changelog
+## 4.56.0 (2026-05-08)
+
+Full Changelog: [v4.55.0...v4.56.0](https://github.com/orbcorp/orb-python/compare/v4.55.0...v4.56.0)
+
+### Features
+
+* **api:** api update ([420a0ee](https://github.com/orbcorp/orb-python/commit/420a0ee33bf090fbbab838ce83f0a84f9c043407))
+* **api:** api update ([71340f6](https://github.com/orbcorp/orb-python/commit/71340f6025d41322701c9aa59ae9ff52d783428e))
+* **api:** api update ([6450ca8](https://github.com/orbcorp/orb-python/commit/6450ca894f18893714bde57ed1b2841deef556ab))
+* **api:** api update ([d11987d](https://github.com/orbcorp/orb-python/commit/d11987d6a51e91b50bbd1a5b551fed1747bd42b6))
+* **api:** api update ([f5bfd3c](https://github.com/orbcorp/orb-python/commit/f5bfd3c2c346af87b457b62726d8e117ba3e0f23))
+* **api:** api update ([3b0e75f](https://github.com/orbcorp/orb-python/commit/3b0e75fcfff160299f9229116ed1a267f2d0b44c))
+* **api:** api update ([de414ba](https://github.com/orbcorp/orb-python/commit/de414ba5ad025dd149eb8fde15767aca928b289d))
+* **api:** api update ([5a1e185](https://github.com/orbcorp/orb-python/commit/5a1e185f488ee90547d11f4178d25e6382447823))
+* **api:** api update ([3c67098](https://github.com/orbcorp/orb-python/commit/3c67098dbbfb806a14bfe65f83930b1f594d873a))
+* **api:** api update ([4e3652d](https://github.com/orbcorp/orb-python/commit/4e3652dfaec77221b4907179784aaf88e1ff2d67))
+* **api:** api update ([931c0f4](https://github.com/orbcorp/orb-python/commit/931c0f421c553981b7c0326a0c721e7cc5fa53f3))
+* **api:** api update ([8c1ffda](https://github.com/orbcorp/orb-python/commit/8c1ffda41e28f9f3dad2b64363dc3e6d8b8e57b2))
+* **api:** api update ([deda5e1](https://github.com/orbcorp/orb-python/commit/deda5e1a4c4412e91ad61f038b5c9e17d3072a22))
+* **api:** api update ([425bac4](https://github.com/orbcorp/orb-python/commit/425bac4cc3a9df0085fad215bf5c66d108008d67))
+* **api:** api update ([cd1cd23](https://github.com/orbcorp/orb-python/commit/cd1cd2396264bbc01c71c6ba7e2dc937ee1b5928))
+* **api:** api update ([6b4583e](https://github.com/orbcorp/orb-python/commit/6b4583ede27c6245a828b670301e1bf37cf708a7))
+* **api:** api update ([b676980](https://github.com/orbcorp/orb-python/commit/b6769806d684451bd19d037fd80132e4a0de5930))
+* **api:** api update ([19af3f7](https://github.com/orbcorp/orb-python/commit/19af3f7d6238fb95b66cf2229e5095a0f2bb0df1))
+* **api:** api update ([3686dc6](https://github.com/orbcorp/orb-python/commit/3686dc6ec326e564578f5ab13c7d258d41de8def))
+* **api:** api update ([2fbc2b1](https://github.com/orbcorp/orb-python/commit/2fbc2b14d46648f4ef4ea57ead9cd08b444211b1))
+* **internal:** implement indices array format for query and form serialization ([b78355c](https://github.com/orbcorp/orb-python/commit/b78355cef870adb25c8c6995362c1bef24ca78d1))
+* support setting headers via env ([2366135](https://github.com/orbcorp/orb-python/commit/2366135b23351d39f2da94f68e2649436ab6c4b7))
+
+
+### Bug Fixes
+
+* **client:** add missing f-string prefix in file type error message ([67ca8a4](https://github.com/orbcorp/orb-python/commit/67ca8a4ce63933b112cd3188b720bfa13cf177b5))
+* **client:** preserve hardcoded query params when merging with user params ([a87a1f8](https://github.com/orbcorp/orb-python/commit/a87a1f812952e2aaf62d34539abe40d3fe3b8778))
+* **deps:** bump minimum typing-extensions version ([93f9afe](https://github.com/orbcorp/orb-python/commit/93f9afed7c1b6c5aa432e78bac43107a4b7f2df1))
+* ensure file data are only sent as 1 parameter ([e478a4e](https://github.com/orbcorp/orb-python/commit/e478a4e612a3cf3f4ac6162cb0f965938fe06856))
+* **pydantic:** do not pass `by_alias` unless set ([06cedae](https://github.com/orbcorp/orb-python/commit/06cedaebd513685daa42d203346112a8ac4c792a))
+* sanitize endpoint path params ([a7e8834](https://github.com/orbcorp/orb-python/commit/a7e88347c865c3daa237efaedbb824cf04a5d3b2))
+* use correct field name format for multipart file arrays ([62c31ad](https://github.com/orbcorp/orb-python/commit/62c31ad3426daf3df4ac7c1af8813f6ac4b30103))
+
+
+### Performance Improvements
+
+* **client:** optimize file structure copying in multipart requests ([b9feeba](https://github.com/orbcorp/orb-python/commit/b9feeba9110ee8bc347368a1f277b2f2c75f5955))
+
+
+### Chores
+
+* **ci:** skip lint on metadata-only changes ([16d7746](https://github.com/orbcorp/orb-python/commit/16d77465cdd71d193002e3d977f926a856b8a693))
+* **ci:** skip uploading artifacts on stainless-internal branches ([a2813c8](https://github.com/orbcorp/orb-python/commit/a2813c8575727ecbd2582b251095ed70a9b75613))
+* **docs:** add missing descriptions ([1bb4db8](https://github.com/orbcorp/orb-python/commit/1bb4db815a18a056aa19366c6622a66935d59577))
+* **internal:** add request options to SSE classes ([9110978](https://github.com/orbcorp/orb-python/commit/9110978adab2229b2eff3f3dfeb3ce6df2f5305e))
+* **internal:** make `test_proxy_environment_variables` more resilient ([e567054](https://github.com/orbcorp/orb-python/commit/e56705443f6920ad4b6eb750a5cd0488d8a119f3))
+* **internal:** make `test_proxy_environment_variables` more resilient to env ([a2da977](https://github.com/orbcorp/orb-python/commit/a2da97718dd34551d38475738e3fd701cc8e2fbe))
+* **internal:** more robust bootstrap script ([eaaf738](https://github.com/orbcorp/orb-python/commit/eaaf7380236110ea5ddacd9bc49eaaff895b3fab))
+* **internal:** reformat pyproject.toml ([e022f45](https://github.com/orbcorp/orb-python/commit/e022f4563ac868f55d5f7a3baa66773295446a97))
+* **internal:** tweak CI branches ([c5ab3b4](https://github.com/orbcorp/orb-python/commit/c5ab3b47348d6b75866c9e3e3ff6cc185e3cd1c8))
+* **internal:** update gitignore ([e2316ae](https://github.com/orbcorp/orb-python/commit/e2316aee6077ef333f4ae35fd759e3ef0a8d4343))
+* **test:** do not count install time for mock server timeout ([888e2ca](https://github.com/orbcorp/orb-python/commit/888e2ca02a4fd7cb2294bf0ce1af4b8cee014809))
+* **tests:** bump steady to v0.19.4 ([dba860e](https://github.com/orbcorp/orb-python/commit/dba860e1955d0964daee83d2f4eae6030df1e802))
+* **tests:** bump steady to v0.19.5 ([0918804](https://github.com/orbcorp/orb-python/commit/09188043849d27914198fd370b525ab9353cb174))
+* **tests:** bump steady to v0.19.6 ([f37e5be](https://github.com/orbcorp/orb-python/commit/f37e5be1bdad7d3f627f2a5f1a7e97fa590dc3c3))
+* **tests:** bump steady to v0.19.7 ([403afe2](https://github.com/orbcorp/orb-python/commit/403afe25fbed8a923ec2bbcf5b7ab4deb16bfaef))
+* **tests:** bump steady to v0.20.1 ([a15890c](https://github.com/orbcorp/orb-python/commit/a15890cea8a677e9f3fa1d63cb13411ec39896d4))
+* **tests:** bump steady to v0.20.2 ([1b0c906](https://github.com/orbcorp/orb-python/commit/1b0c906c63dd56858f8c45293e6089abcb6f0060))
+* **tests:** bump steady to v0.22.1 ([cbbf427](https://github.com/orbcorp/orb-python/commit/cbbf42715e0f53d2e9fd5f720b11c0333738ae3e))
+* **tests:** update mock server to steady ([97a3d8f](https://github.com/orbcorp/orb-python/commit/97a3d8ff2b9ffe7810864b7146fbe9dab0909aa5))
+* update mock server docs ([0f016de](https://github.com/orbcorp/orb-python/commit/0f016de052ebb429752c7ffdc4ca061c19562469))
+
+
+### Documentation
+
+* improve examples ([de8f18b](https://github.com/orbcorp/orb-python/commit/de8f18b0efd5c11bb5a62078ada084dc8b81bd46))
+
## 4.55.0 (2026-02-12)
Full Changelog: [v4.54.0...v4.55.0](https://github.com/orbcorp/orb-python/compare/v4.54.0...v4.55.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ea9f566f..13aed782 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -85,11 +85,10 @@ $ pip install ./path-to-wheel-file.whl
## Running tests
-Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
+Most tests require you to [set up a mock server](https://github.com/dgellow/steady) against the OpenAPI spec to run the tests.
```sh
-# you will need npm installed
-$ npx prism mock path/to/your/openapi.yml
+$ ./scripts/mock
```
```sh
diff --git a/api.md b/api.md
index b50a14f4..37c8c3c8 100644
--- a/api.md
+++ b/api.md
@@ -408,7 +408,7 @@ Methods:
- client.invoices.issue_summary(invoice_id, \*\*params) -> InvoiceIssueSummaryResponse
- client.invoices.list_summary(\*\*params) -> SyncPage[InvoiceListSummaryResponse]
- client.invoices.mark_paid(invoice_id, \*\*params) -> Invoice
-- client.invoices.pay(invoice_id) -> Invoice
+- client.invoices.pay(invoice_id, \*\*params) -> Invoice
- client.invoices.void(invoice_id) -> Invoice
# Items
diff --git a/pyproject.toml b/pyproject.toml
index 0f0bbaa4..9135d7d3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "orb-billing"
-version = "4.55.0"
+version = "4.56.0"
description = "The official Python library for the orb API"
dynamic = ["readme"]
license = "Apache-2.0"
@@ -11,7 +11,7 @@ authors = [
dependencies = [
"httpx>=0.23.0, <1",
"pydantic>=1.9.0, <3",
- "typing-extensions>=4.10, <5",
+ "typing-extensions>=4.14, <5",
"anyio>=3.5.0, <5",
"distro>=1.7.0, <2",
"sniffio",
@@ -168,7 +168,7 @@ show_error_codes = true
#
# We also exclude our `tests` as mypy doesn't always infer
# types correctly and Pyright will still catch any type errors.
-exclude = ['src/orb/_files.py', '_dev/.*.py', 'tests/.*']
+exclude = ["src/orb/_files.py", "_dev/.*.py", "tests/.*"]
strict_equality = true
implicit_reexport = true
diff --git a/scripts/bootstrap b/scripts/bootstrap
index b430fee3..fe8451e4 100755
--- a/scripts/bootstrap
+++ b/scripts/bootstrap
@@ -4,7 +4,7 @@ set -e
cd "$(dirname "$0")/.."
-if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then
+if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then
brew bundle check >/dev/null 2>&1 || {
echo -n "==> Install Homebrew dependencies? (y/N): "
read -r response
diff --git a/scripts/mock b/scripts/mock
index 0b28f6ea..04d29019 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -19,23 +19,34 @@ fi
echo "==> Starting mock server with URL ${URL}"
-# Run prism mock on the given spec
+# Run steady mock on the given spec
if [ "$1" == "--daemon" ]; then
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
+ # Pre-install the package so the download doesn't eat into the startup timeout
+ npm exec --package=@stdy/cli@0.22.1 -- steady --version
- # Wait for server to come online
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
+
+ # Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
- while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
+ attempts=0
+ while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do
+ if ! kill -0 $! 2>/dev/null; then
+ echo
+ cat .stdy.log
+ exit 1
+ fi
+ attempts=$((attempts + 1))
+ if [ "$attempts" -ge 300 ]; then
+ echo
+ echo "Timed out waiting for Steady server to start"
+ cat .stdy.log
+ exit 1
+ fi
echo -n "."
sleep 0.1
done
- if grep -q "✖ fatal" ".prism.log"; then
- cat .prism.log
- exit 1
- fi
-
echo
else
- npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
diff --git a/scripts/test b/scripts/test
index dbeda2d2..7b05e44f 100755
--- a/scripts/test
+++ b/scripts/test
@@ -9,8 +9,8 @@ GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
-function prism_is_running() {
- curl --silent "http://localhost:4010" >/dev/null 2>&1
+function steady_is_running() {
+ curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1
}
kill_server_on_port() {
@@ -25,7 +25,7 @@ function is_overriding_api_base_url() {
[ -n "$TEST_API_BASE_URL" ]
}
-if ! is_overriding_api_base_url && ! prism_is_running ; then
+if ! is_overriding_api_base_url && ! steady_is_running ; then
# When we exit this script, make sure to kill the background mock server process
trap 'kill_server_on_port 4010' EXIT
@@ -36,19 +36,19 @@ fi
if is_overriding_api_base_url ; then
echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}"
echo
-elif ! prism_is_running ; then
- echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server"
+elif ! steady_is_running ; then
+ echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Steady server"
echo -e "running against your OpenAPI spec."
echo
echo -e "To run the server, pass in the path or url of your OpenAPI"
- echo -e "spec to the prism command:"
+ echo -e "spec to the steady command:"
echo
- echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
+ echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo
exit 1
else
- echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}"
+ echo -e "${GREEN}✔ Mock steady server is running with your OpenAPI spec${NC}"
echo
fi
diff --git a/src/orb/_base_client.py b/src/orb/_base_client.py
index 80ec2d78..86fbf71c 100644
--- a/src/orb/_base_client.py
+++ b/src/orb/_base_client.py
@@ -541,6 +541,10 @@ def _build_request(
files = cast(HttpxRequestFiles, ForceMultipartDict())
prepared_url = self._prepare_url(options.url)
+ # preserve hard-coded query params from the url
+ if params and prepared_url.query:
+ params = {**dict(prepared_url.params.items()), **params}
+ prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0])
if "_" in prepared_url.host:
# work around https://github.com/encode/httpx/discussions/2880
kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")}
diff --git a/src/orb/_client.py b/src/orb/_client.py
index d1f4078c..441fec66 100644
--- a/src/orb/_client.py
+++ b/src/orb/_client.py
@@ -22,6 +22,7 @@
from ._utils import (
is_given,
is_mapping,
+ is_mapping_t,
get_async_library,
)
from ._compat import cached_property
@@ -135,6 +136,15 @@ def __init__(
if base_url is None:
base_url = f"https://api.withorb.com/v1"
+ custom_headers_env = os.environ.get("ORB_CUSTOM_HEADERS")
+ if custom_headers_env is not None:
+ parsed: dict[str, str] = {}
+ for line in custom_headers_env.split("\n"):
+ colon = line.find(":")
+ if colon >= 0:
+ parsed[line[:colon].strip()] = line[colon + 1 :].strip()
+ default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})}
+
super().__init__(
version=__version__,
base_url=base_url,
@@ -156,66 +166,134 @@ def top_level(self) -> TopLevel:
@cached_property
def beta(self) -> Beta:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.beta import Beta
return Beta(self)
@cached_property
def coupons(self) -> Coupons:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
from .resources.coupons import Coupons
return Coupons(self)
@cached_property
def credit_notes(self) -> CreditNotes:
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
from .resources.credit_notes import CreditNotes
return CreditNotes(self)
@cached_property
def customers(self) -> Customers:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
from .resources.customers import Customers
return Customers(self)
@cached_property
def events(self) -> Events:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
from .resources.events import Events
return Events(self)
@cached_property
def invoice_line_items(self) -> InvoiceLineItems:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoice_line_items import InvoiceLineItems
return InvoiceLineItems(self)
@cached_property
def invoices(self) -> Invoices:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoices import Invoices
return Invoices(self)
@cached_property
def items(self) -> Items:
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
from .resources.items import Items
return Items(self)
@cached_property
def metrics(self) -> Metrics:
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
from .resources.metrics import Metrics
return Metrics(self)
@cached_property
def plans(self) -> Plans:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.plans import Plans
return Plans(self)
@cached_property
def prices(self) -> Prices:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
from .resources.prices import Prices
return Prices(self)
@@ -228,6 +306,12 @@ def subscriptions(self) -> Subscriptions:
@cached_property
def alerts(self) -> Alerts:
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
from .resources.alerts import Alerts
return Alerts(self)
@@ -252,12 +336,19 @@ def webhooks(self) -> webhooks.Webhooks:
@cached_property
def credit_blocks(self) -> CreditBlocks:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
from .resources.credit_blocks import CreditBlocks
return CreditBlocks(self)
@cached_property
def license_types(self) -> LicenseTypes:
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
from .resources.license_types import LicenseTypes
return LicenseTypes(self)
@@ -483,6 +574,15 @@ def __init__(
if base_url is None:
base_url = f"https://api.withorb.com/v1"
+ custom_headers_env = os.environ.get("ORB_CUSTOM_HEADERS")
+ if custom_headers_env is not None:
+ parsed: dict[str, str] = {}
+ for line in custom_headers_env.split("\n"):
+ colon = line.find(":")
+ if colon >= 0:
+ parsed[line[:colon].strip()] = line[colon + 1 :].strip()
+ default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})}
+
super().__init__(
version=__version__,
base_url=base_url,
@@ -504,66 +604,134 @@ def top_level(self) -> AsyncTopLevel:
@cached_property
def beta(self) -> AsyncBeta:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.beta import AsyncBeta
return AsyncBeta(self)
@cached_property
def coupons(self) -> AsyncCoupons:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
from .resources.coupons import AsyncCoupons
return AsyncCoupons(self)
@cached_property
def credit_notes(self) -> AsyncCreditNotes:
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
from .resources.credit_notes import AsyncCreditNotes
return AsyncCreditNotes(self)
@cached_property
def customers(self) -> AsyncCustomers:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
from .resources.customers import AsyncCustomers
return AsyncCustomers(self)
@cached_property
def events(self) -> AsyncEvents:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
from .resources.events import AsyncEvents
return AsyncEvents(self)
@cached_property
def invoice_line_items(self) -> AsyncInvoiceLineItems:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoice_line_items import AsyncInvoiceLineItems
return AsyncInvoiceLineItems(self)
@cached_property
def invoices(self) -> AsyncInvoices:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoices import AsyncInvoices
return AsyncInvoices(self)
@cached_property
def items(self) -> AsyncItems:
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
from .resources.items import AsyncItems
return AsyncItems(self)
@cached_property
def metrics(self) -> AsyncMetrics:
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
from .resources.metrics import AsyncMetrics
return AsyncMetrics(self)
@cached_property
def plans(self) -> AsyncPlans:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.plans import AsyncPlans
return AsyncPlans(self)
@cached_property
def prices(self) -> AsyncPrices:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
from .resources.prices import AsyncPrices
return AsyncPrices(self)
@@ -576,6 +744,12 @@ def subscriptions(self) -> AsyncSubscriptions:
@cached_property
def alerts(self) -> AsyncAlerts:
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
from .resources.alerts import AsyncAlerts
return AsyncAlerts(self)
@@ -600,12 +774,19 @@ def webhooks(self) -> webhooks.AsyncWebhooks:
@cached_property
def credit_blocks(self) -> AsyncCreditBlocks:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
from .resources.credit_blocks import AsyncCreditBlocks
return AsyncCreditBlocks(self)
@cached_property
def license_types(self) -> AsyncLicenseTypes:
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
from .resources.license_types import AsyncLicenseTypes
return AsyncLicenseTypes(self)
@@ -793,66 +974,134 @@ def top_level(self) -> top_level.TopLevelWithRawResponse:
@cached_property
def beta(self) -> beta.BetaWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.beta import BetaWithRawResponse
return BetaWithRawResponse(self._client.beta)
@cached_property
def coupons(self) -> coupons.CouponsWithRawResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
from .resources.coupons import CouponsWithRawResponse
return CouponsWithRawResponse(self._client.coupons)
@cached_property
def credit_notes(self) -> credit_notes.CreditNotesWithRawResponse:
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
from .resources.credit_notes import CreditNotesWithRawResponse
return CreditNotesWithRawResponse(self._client.credit_notes)
@cached_property
def customers(self) -> customers.CustomersWithRawResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
from .resources.customers import CustomersWithRawResponse
return CustomersWithRawResponse(self._client.customers)
@cached_property
def events(self) -> events.EventsWithRawResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
from .resources.events import EventsWithRawResponse
return EventsWithRawResponse(self._client.events)
@cached_property
def invoice_line_items(self) -> invoice_line_items.InvoiceLineItemsWithRawResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoice_line_items import InvoiceLineItemsWithRawResponse
return InvoiceLineItemsWithRawResponse(self._client.invoice_line_items)
@cached_property
def invoices(self) -> invoices.InvoicesWithRawResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoices import InvoicesWithRawResponse
return InvoicesWithRawResponse(self._client.invoices)
@cached_property
def items(self) -> items.ItemsWithRawResponse:
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
from .resources.items import ItemsWithRawResponse
return ItemsWithRawResponse(self._client.items)
@cached_property
def metrics(self) -> metrics.MetricsWithRawResponse:
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
from .resources.metrics import MetricsWithRawResponse
return MetricsWithRawResponse(self._client.metrics)
@cached_property
def plans(self) -> plans.PlansWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.plans import PlansWithRawResponse
return PlansWithRawResponse(self._client.plans)
@cached_property
def prices(self) -> prices.PricesWithRawResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
from .resources.prices import PricesWithRawResponse
return PricesWithRawResponse(self._client.prices)
@@ -865,6 +1114,12 @@ def subscriptions(self) -> subscriptions.SubscriptionsWithRawResponse:
@cached_property
def alerts(self) -> alerts.AlertsWithRawResponse:
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
from .resources.alerts import AlertsWithRawResponse
return AlertsWithRawResponse(self._client.alerts)
@@ -883,12 +1138,19 @@ def subscription_changes(self) -> subscription_changes.SubscriptionChangesWithRa
@cached_property
def credit_blocks(self) -> credit_blocks.CreditBlocksWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
from .resources.credit_blocks import CreditBlocksWithRawResponse
return CreditBlocksWithRawResponse(self._client.credit_blocks)
@cached_property
def license_types(self) -> license_types.LicenseTypesWithRawResponse:
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
from .resources.license_types import LicenseTypesWithRawResponse
return LicenseTypesWithRawResponse(self._client.license_types)
@@ -914,66 +1176,134 @@ def top_level(self) -> top_level.AsyncTopLevelWithRawResponse:
@cached_property
def beta(self) -> beta.AsyncBetaWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.beta import AsyncBetaWithRawResponse
return AsyncBetaWithRawResponse(self._client.beta)
@cached_property
def coupons(self) -> coupons.AsyncCouponsWithRawResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
from .resources.coupons import AsyncCouponsWithRawResponse
return AsyncCouponsWithRawResponse(self._client.coupons)
@cached_property
def credit_notes(self) -> credit_notes.AsyncCreditNotesWithRawResponse:
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
from .resources.credit_notes import AsyncCreditNotesWithRawResponse
return AsyncCreditNotesWithRawResponse(self._client.credit_notes)
@cached_property
def customers(self) -> customers.AsyncCustomersWithRawResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
from .resources.customers import AsyncCustomersWithRawResponse
return AsyncCustomersWithRawResponse(self._client.customers)
@cached_property
def events(self) -> events.AsyncEventsWithRawResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
from .resources.events import AsyncEventsWithRawResponse
return AsyncEventsWithRawResponse(self._client.events)
@cached_property
def invoice_line_items(self) -> invoice_line_items.AsyncInvoiceLineItemsWithRawResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoice_line_items import AsyncInvoiceLineItemsWithRawResponse
return AsyncInvoiceLineItemsWithRawResponse(self._client.invoice_line_items)
@cached_property
def invoices(self) -> invoices.AsyncInvoicesWithRawResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoices import AsyncInvoicesWithRawResponse
return AsyncInvoicesWithRawResponse(self._client.invoices)
@cached_property
def items(self) -> items.AsyncItemsWithRawResponse:
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
from .resources.items import AsyncItemsWithRawResponse
return AsyncItemsWithRawResponse(self._client.items)
@cached_property
def metrics(self) -> metrics.AsyncMetricsWithRawResponse:
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
from .resources.metrics import AsyncMetricsWithRawResponse
return AsyncMetricsWithRawResponse(self._client.metrics)
@cached_property
def plans(self) -> plans.AsyncPlansWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.plans import AsyncPlansWithRawResponse
return AsyncPlansWithRawResponse(self._client.plans)
@cached_property
def prices(self) -> prices.AsyncPricesWithRawResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
from .resources.prices import AsyncPricesWithRawResponse
return AsyncPricesWithRawResponse(self._client.prices)
@@ -986,6 +1316,12 @@ def subscriptions(self) -> subscriptions.AsyncSubscriptionsWithRawResponse:
@cached_property
def alerts(self) -> alerts.AsyncAlertsWithRawResponse:
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
from .resources.alerts import AsyncAlertsWithRawResponse
return AsyncAlertsWithRawResponse(self._client.alerts)
@@ -1004,12 +1340,19 @@ def subscription_changes(self) -> subscription_changes.AsyncSubscriptionChangesW
@cached_property
def credit_blocks(self) -> credit_blocks.AsyncCreditBlocksWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
from .resources.credit_blocks import AsyncCreditBlocksWithRawResponse
return AsyncCreditBlocksWithRawResponse(self._client.credit_blocks)
@cached_property
def license_types(self) -> license_types.AsyncLicenseTypesWithRawResponse:
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
from .resources.license_types import AsyncLicenseTypesWithRawResponse
return AsyncLicenseTypesWithRawResponse(self._client.license_types)
@@ -1035,66 +1378,134 @@ def top_level(self) -> top_level.TopLevelWithStreamingResponse:
@cached_property
def beta(self) -> beta.BetaWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.beta import BetaWithStreamingResponse
return BetaWithStreamingResponse(self._client.beta)
@cached_property
def coupons(self) -> coupons.CouponsWithStreamingResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
from .resources.coupons import CouponsWithStreamingResponse
return CouponsWithStreamingResponse(self._client.coupons)
@cached_property
def credit_notes(self) -> credit_notes.CreditNotesWithStreamingResponse:
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
from .resources.credit_notes import CreditNotesWithStreamingResponse
return CreditNotesWithStreamingResponse(self._client.credit_notes)
@cached_property
def customers(self) -> customers.CustomersWithStreamingResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
from .resources.customers import CustomersWithStreamingResponse
return CustomersWithStreamingResponse(self._client.customers)
@cached_property
def events(self) -> events.EventsWithStreamingResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
from .resources.events import EventsWithStreamingResponse
return EventsWithStreamingResponse(self._client.events)
@cached_property
def invoice_line_items(self) -> invoice_line_items.InvoiceLineItemsWithStreamingResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoice_line_items import InvoiceLineItemsWithStreamingResponse
return InvoiceLineItemsWithStreamingResponse(self._client.invoice_line_items)
@cached_property
def invoices(self) -> invoices.InvoicesWithStreamingResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoices import InvoicesWithStreamingResponse
return InvoicesWithStreamingResponse(self._client.invoices)
@cached_property
def items(self) -> items.ItemsWithStreamingResponse:
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
from .resources.items import ItemsWithStreamingResponse
return ItemsWithStreamingResponse(self._client.items)
@cached_property
def metrics(self) -> metrics.MetricsWithStreamingResponse:
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
from .resources.metrics import MetricsWithStreamingResponse
return MetricsWithStreamingResponse(self._client.metrics)
@cached_property
def plans(self) -> plans.PlansWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.plans import PlansWithStreamingResponse
return PlansWithStreamingResponse(self._client.plans)
@cached_property
def prices(self) -> prices.PricesWithStreamingResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
from .resources.prices import PricesWithStreamingResponse
return PricesWithStreamingResponse(self._client.prices)
@@ -1107,6 +1518,12 @@ def subscriptions(self) -> subscriptions.SubscriptionsWithStreamingResponse:
@cached_property
def alerts(self) -> alerts.AlertsWithStreamingResponse:
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
from .resources.alerts import AlertsWithStreamingResponse
return AlertsWithStreamingResponse(self._client.alerts)
@@ -1125,12 +1542,19 @@ def subscription_changes(self) -> subscription_changes.SubscriptionChangesWithSt
@cached_property
def credit_blocks(self) -> credit_blocks.CreditBlocksWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
from .resources.credit_blocks import CreditBlocksWithStreamingResponse
return CreditBlocksWithStreamingResponse(self._client.credit_blocks)
@cached_property
def license_types(self) -> license_types.LicenseTypesWithStreamingResponse:
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
from .resources.license_types import LicenseTypesWithStreamingResponse
return LicenseTypesWithStreamingResponse(self._client.license_types)
@@ -1156,66 +1580,134 @@ def top_level(self) -> top_level.AsyncTopLevelWithStreamingResponse:
@cached_property
def beta(self) -> beta.AsyncBetaWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.beta import AsyncBetaWithStreamingResponse
return AsyncBetaWithStreamingResponse(self._client.beta)
@cached_property
def coupons(self) -> coupons.AsyncCouponsWithStreamingResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
from .resources.coupons import AsyncCouponsWithStreamingResponse
return AsyncCouponsWithStreamingResponse(self._client.coupons)
@cached_property
def credit_notes(self) -> credit_notes.AsyncCreditNotesWithStreamingResponse:
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
from .resources.credit_notes import AsyncCreditNotesWithStreamingResponse
return AsyncCreditNotesWithStreamingResponse(self._client.credit_notes)
@cached_property
def customers(self) -> customers.AsyncCustomersWithStreamingResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
from .resources.customers import AsyncCustomersWithStreamingResponse
return AsyncCustomersWithStreamingResponse(self._client.customers)
@cached_property
def events(self) -> events.AsyncEventsWithStreamingResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
from .resources.events import AsyncEventsWithStreamingResponse
return AsyncEventsWithStreamingResponse(self._client.events)
@cached_property
def invoice_line_items(self) -> invoice_line_items.AsyncInvoiceLineItemsWithStreamingResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoice_line_items import AsyncInvoiceLineItemsWithStreamingResponse
return AsyncInvoiceLineItemsWithStreamingResponse(self._client.invoice_line_items)
@cached_property
def invoices(self) -> invoices.AsyncInvoicesWithStreamingResponse:
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
from .resources.invoices import AsyncInvoicesWithStreamingResponse
return AsyncInvoicesWithStreamingResponse(self._client.invoices)
@cached_property
def items(self) -> items.AsyncItemsWithStreamingResponse:
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
from .resources.items import AsyncItemsWithStreamingResponse
return AsyncItemsWithStreamingResponse(self._client.items)
@cached_property
def metrics(self) -> metrics.AsyncMetricsWithStreamingResponse:
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
from .resources.metrics import AsyncMetricsWithStreamingResponse
return AsyncMetricsWithStreamingResponse(self._client.metrics)
@cached_property
def plans(self) -> plans.AsyncPlansWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
from .resources.plans import AsyncPlansWithStreamingResponse
return AsyncPlansWithStreamingResponse(self._client.plans)
@cached_property
def prices(self) -> prices.AsyncPricesWithStreamingResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
from .resources.prices import AsyncPricesWithStreamingResponse
return AsyncPricesWithStreamingResponse(self._client.prices)
@@ -1228,6 +1720,12 @@ def subscriptions(self) -> subscriptions.AsyncSubscriptionsWithStreamingResponse
@cached_property
def alerts(self) -> alerts.AsyncAlertsWithStreamingResponse:
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
from .resources.alerts import AsyncAlertsWithStreamingResponse
return AsyncAlertsWithStreamingResponse(self._client.alerts)
@@ -1246,12 +1744,19 @@ def subscription_changes(self) -> subscription_changes.AsyncSubscriptionChangesW
@cached_property
def credit_blocks(self) -> credit_blocks.AsyncCreditBlocksWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
from .resources.credit_blocks import AsyncCreditBlocksWithStreamingResponse
return AsyncCreditBlocksWithStreamingResponse(self._client.credit_blocks)
@cached_property
def license_types(self) -> license_types.AsyncLicenseTypesWithStreamingResponse:
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
from .resources.license_types import AsyncLicenseTypesWithStreamingResponse
return AsyncLicenseTypesWithStreamingResponse(self._client.license_types)
diff --git a/src/orb/_compat.py b/src/orb/_compat.py
index 786ff42a..e6690a4f 100644
--- a/src/orb/_compat.py
+++ b/src/orb/_compat.py
@@ -2,7 +2,7 @@
from typing import TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, cast, overload
from datetime import date, datetime
-from typing_extensions import Self, Literal
+from typing_extensions import Self, Literal, TypedDict
import pydantic
from pydantic.fields import FieldInfo
@@ -131,6 +131,10 @@ def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str:
return model.model_dump_json(indent=indent)
+class _ModelDumpKwargs(TypedDict, total=False):
+ by_alias: bool
+
+
def model_dump(
model: pydantic.BaseModel,
*,
@@ -142,6 +146,9 @@ def model_dump(
by_alias: bool | None = None,
) -> dict[str, Any]:
if (not PYDANTIC_V1) or hasattr(model, "model_dump"):
+ kwargs: _ModelDumpKwargs = {}
+ if by_alias is not None:
+ kwargs["by_alias"] = by_alias
return model.model_dump(
mode=mode,
exclude=exclude,
@@ -149,7 +156,7 @@ def model_dump(
exclude_defaults=exclude_defaults,
# warnings are not supported in Pydantic v1
warnings=True if PYDANTIC_V1 else warnings,
- by_alias=by_alias,
+ **kwargs,
)
return cast(
"dict[str, Any]",
diff --git a/src/orb/_files.py b/src/orb/_files.py
index cc14c14f..76da9e08 100644
--- a/src/orb/_files.py
+++ b/src/orb/_files.py
@@ -3,8 +3,8 @@
import io
import os
import pathlib
-from typing import overload
-from typing_extensions import TypeGuard
+from typing import Sequence, cast, overload
+from typing_extensions import TypeVar, TypeGuard
import anyio
@@ -17,7 +17,9 @@
HttpxFileContent,
HttpxRequestFiles,
)
-from ._utils import is_tuple_t, is_mapping_t, is_sequence_t
+from ._utils import is_list, is_mapping, is_tuple_t, is_mapping_t, is_sequence_t
+
+_T = TypeVar("_T")
def is_base64_file_input(obj: object) -> TypeGuard[Base64FileInput]:
@@ -97,7 +99,7 @@ async def async_to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles
elif is_sequence_t(files):
files = [(key, await _async_transform_file(file)) for key, file in files]
else:
- raise TypeError("Unexpected file type input {type(files)}, expected mapping or sequence")
+ raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence")
return files
@@ -121,3 +123,51 @@ async def async_read_file_content(file: FileContent) -> HttpxFileContent:
return await anyio.Path(file).read_bytes()
return file
+
+
+def deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]]) -> _T:
+ """Copy only the containers along the given paths.
+
+ Used to guard against mutation by extract_files without copying the entire structure.
+ Only dicts and lists that lie on a path are copied; everything else
+ is returned by reference.
+
+ For example, given paths=[["foo", "files", "file"]] and the structure:
+ {
+ "foo": {
+ "bar": {"baz": {}},
+ "files": {"file": }
+ }
+ }
+ The root dict, "foo", and "files" are copied (they lie on the path).
+ "bar" and "baz" are returned by reference (off the path).
+ """
+ return _deepcopy_with_paths(item, paths, 0)
+
+
+def _deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]], index: int) -> _T:
+ if not paths:
+ return item
+ if is_mapping(item):
+ key_to_paths: dict[str, list[Sequence[str]]] = {}
+ for path in paths:
+ if index < len(path):
+ key_to_paths.setdefault(path[index], []).append(path)
+
+ # if no path continues through this mapping, it won't be mutated and copying it is redundant
+ if not key_to_paths:
+ return item
+
+ result = dict(item)
+ for key, subpaths in key_to_paths.items():
+ if key in result:
+ result[key] = _deepcopy_with_paths(result[key], subpaths, index + 1)
+ return cast(_T, result)
+ if is_list(item):
+ array_paths = [path for path in paths if index < len(path) and path[index] == ""]
+
+ # if no path expects a list here, nothing will be mutated inside it - return by reference
+ if not array_paths:
+ return cast(_T, item)
+ return cast(_T, [_deepcopy_with_paths(entry, array_paths, index + 1) for entry in item])
+ return item
diff --git a/src/orb/_legacy_response.py b/src/orb/_legacy_response.py
index 96cbe8bd..a78dda22 100644
--- a/src/orb/_legacy_response.py
+++ b/src/orb/_legacy_response.py
@@ -214,6 +214,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -224,6 +225,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=extract_stream_chunk_type(self._stream_cls),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -237,6 +239,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=cast_to,
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
diff --git a/src/orb/_qs.py b/src/orb/_qs.py
index ada6fd3f..4127c19c 100644
--- a/src/orb/_qs.py
+++ b/src/orb/_qs.py
@@ -2,17 +2,13 @@
from typing import Any, List, Tuple, Union, Mapping, TypeVar
from urllib.parse import parse_qs, urlencode
-from typing_extensions import Literal, get_args
+from typing_extensions import get_args
-from ._types import NotGiven, not_given
+from ._types import NotGiven, ArrayFormat, NestedFormat, not_given
from ._utils import flatten
_T = TypeVar("_T")
-
-ArrayFormat = Literal["comma", "repeat", "indices", "brackets"]
-NestedFormat = Literal["dots", "brackets"]
-
PrimitiveData = Union[str, int, float, bool, None]
# this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"]
# https://github.com/microsoft/pyright/issues/3555
@@ -101,7 +97,10 @@ def _stringify_item(
items.extend(self._stringify_item(key, item, opts))
return items
elif array_format == "indices":
- raise NotImplementedError("The array indices format is not supported yet")
+ items = []
+ for i, item in enumerate(value):
+ items.extend(self._stringify_item(f"{key}[{i}]", item, opts))
+ return items
elif array_format == "brackets":
items = []
key = key + "[]"
diff --git a/src/orb/_response.py b/src/orb/_response.py
index 2e125354..d8a81963 100644
--- a/src/orb/_response.py
+++ b/src/orb/_response.py
@@ -152,6 +152,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -162,6 +163,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=extract_stream_chunk_type(self._stream_cls),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -175,6 +177,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=cast_to,
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
diff --git a/src/orb/_streaming.py b/src/orb/_streaming.py
index 943d03ab..321fe6aa 100644
--- a/src/orb/_streaming.py
+++ b/src/orb/_streaming.py
@@ -4,7 +4,7 @@
import json
import inspect
from types import TracebackType
-from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, AsyncIterator, cast
+from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, Optional, AsyncIterator, cast
from typing_extensions import Self, Protocol, TypeGuard, override, get_origin, runtime_checkable
import httpx
@@ -13,6 +13,7 @@
if TYPE_CHECKING:
from ._client import Orb, AsyncOrb
+ from ._models import FinalRequestOptions
_T = TypeVar("_T")
@@ -22,7 +23,7 @@ class Stream(Generic[_T]):
"""Provides the core interface to iterate over a synchronous stream response."""
response: httpx.Response
-
+ _options: Optional[FinalRequestOptions] = None
_decoder: SSEBytesDecoder
def __init__(
@@ -31,10 +32,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: Orb,
+ options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
+ self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()
@@ -85,7 +88,7 @@ class AsyncStream(Generic[_T]):
"""Provides the core interface to iterate over an asynchronous stream response."""
response: httpx.Response
-
+ _options: Optional[FinalRequestOptions] = None
_decoder: SSEDecoder | SSEBytesDecoder
def __init__(
@@ -94,10 +97,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: AsyncOrb,
+ options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
+ self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()
diff --git a/src/orb/_types.py b/src/orb/_types.py
index 76df2189..514f1d7a 100644
--- a/src/orb/_types.py
+++ b/src/orb/_types.py
@@ -48,6 +48,9 @@
ModelT = TypeVar("ModelT", bound=pydantic.BaseModel)
_T = TypeVar("_T")
+ArrayFormat = Literal["comma", "repeat", "indices", "brackets"]
+NestedFormat = Literal["dots", "brackets"]
+
# Approximates httpx internal ProxiesTypes and RequestFiles types
# while adding support for `PathLike` instances
diff --git a/src/orb/_utils/__init__.py b/src/orb/_utils/__init__.py
index dc64e29a..1c090e51 100644
--- a/src/orb/_utils/__init__.py
+++ b/src/orb/_utils/__init__.py
@@ -1,3 +1,4 @@
+from ._path import path_template as path_template
from ._sync import asyncify as asyncify
from ._proxy import LazyProxy as LazyProxy
from ._utils import (
@@ -23,7 +24,6 @@
coerce_integer as coerce_integer,
file_from_path as file_from_path,
strip_not_given as strip_not_given,
- deepcopy_minimal as deepcopy_minimal,
get_async_library as get_async_library,
maybe_coerce_float as maybe_coerce_float,
get_required_header as get_required_header,
diff --git a/src/orb/_utils/_path.py b/src/orb/_utils/_path.py
new file mode 100644
index 00000000..4d6e1e4c
--- /dev/null
+++ b/src/orb/_utils/_path.py
@@ -0,0 +1,127 @@
+from __future__ import annotations
+
+import re
+from typing import (
+ Any,
+ Mapping,
+ Callable,
+)
+from urllib.parse import quote
+
+# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E).
+_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$")
+
+_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
+
+
+def _quote_path_segment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI path segment.
+
+ Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
+ """
+ # quote() already treats unreserved characters (letters, digits, and -._~)
+ # as safe, so we only need to add sub-delims, ':', and '@'.
+ # Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted.
+ return quote(value, safe="!$&'()*+,;=:@")
+
+
+def _quote_query_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI query string.
+
+ Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
+ """
+ return quote(value, safe="!$'()*+,;:@/?")
+
+
+def _quote_fragment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI fragment.
+
+ Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
+ """
+ return quote(value, safe="!$&'()*+,;=:@/?")
+
+
+def _interpolate(
+ template: str,
+ values: Mapping[str, Any],
+ quoter: Callable[[str], str],
+) -> str:
+ """Replace {name} placeholders in `template`, quoting each value with `quoter`.
+
+ Placeholder names are looked up in `values`.
+
+ Raises:
+ KeyError: If a placeholder is not found in `values`.
+ """
+ # re.split with a capturing group returns alternating
+ # [text, name, text, name, ..., text] elements.
+ parts = _PLACEHOLDER_RE.split(template)
+
+ for i in range(1, len(parts), 2):
+ name = parts[i]
+ if name not in values:
+ raise KeyError(f"a value for placeholder {{{name}}} was not provided")
+ val = values[name]
+ if val is None:
+ parts[i] = "null"
+ elif isinstance(val, bool):
+ parts[i] = "true" if val else "false"
+ else:
+ parts[i] = quoter(str(values[name]))
+
+ return "".join(parts)
+
+
+def path_template(template: str, /, **kwargs: Any) -> str:
+ """Interpolate {name} placeholders in `template` from keyword arguments.
+
+ Args:
+ template: The template string containing {name} placeholders.
+ **kwargs: Keyword arguments to interpolate into the template.
+
+ Returns:
+ The template with placeholders interpolated and percent-encoded.
+
+ Safe characters for percent-encoding are dependent on the URI component.
+ Placeholders in path and fragment portions are percent-encoded where the `segment`
+ and `fragment` sets from RFC 3986 respectively are considered safe.
+ Placeholders in the query portion are percent-encoded where the `query` set from
+ RFC 3986 §3.3 is considered safe except for = and & characters.
+
+ Raises:
+ KeyError: If a placeholder is not found in `kwargs`.
+ ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments).
+ """
+ # Split the template into path, query, and fragment portions.
+ fragment_template: str | None = None
+ query_template: str | None = None
+
+ rest = template
+ if "#" in rest:
+ rest, fragment_template = rest.split("#", 1)
+ if "?" in rest:
+ rest, query_template = rest.split("?", 1)
+ path_template = rest
+
+ # Interpolate each portion with the appropriate quoting rules.
+ path_result = _interpolate(path_template, kwargs, _quote_path_segment_part)
+
+ # Reject dot-segments (. and ..) in the final assembled path. The check
+ # runs after interpolation so that adjacent placeholders or a mix of static
+ # text and placeholders that together form a dot-segment are caught.
+ # Also reject percent-encoded dot-segments to protect against incorrectly
+ # implemented normalization in servers/proxies.
+ for segment in path_result.split("/"):
+ if _DOT_SEGMENT_RE.match(segment):
+ raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed")
+
+ result = path_result
+ if query_template is not None:
+ result += "?" + _interpolate(query_template, kwargs, _quote_query_part)
+ if fragment_template is not None:
+ result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part)
+
+ return result
diff --git a/src/orb/_utils/_utils.py b/src/orb/_utils/_utils.py
index eec7f4a1..199cd231 100644
--- a/src/orb/_utils/_utils.py
+++ b/src/orb/_utils/_utils.py
@@ -17,11 +17,11 @@
)
from pathlib import Path
from datetime import date, datetime
-from typing_extensions import TypeGuard
+from typing_extensions import TypeGuard, get_args
import sniffio
-from .._types import Omit, NotGiven, FileTypes, HeadersLike
+from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike
_T = TypeVar("_T")
_TupleT = TypeVar("_TupleT", bound=Tuple[object, ...])
@@ -40,25 +40,45 @@ def extract_files(
query: Mapping[str, object],
*,
paths: Sequence[Sequence[str]],
+ array_format: ArrayFormat = "brackets",
) -> list[tuple[str, FileTypes]]:
"""Recursively extract files from the given dictionary based on specified paths.
A path may look like this ['foo', 'files', '', 'data'].
+ ``array_format`` controls how ```` segments contribute to the emitted
+ field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and
+ ``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``).
+
Note: this mutates the given dictionary.
"""
files: list[tuple[str, FileTypes]] = []
for path in paths:
- files.extend(_extract_items(query, path, index=0, flattened_key=None))
+ files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format))
return files
+def _array_suffix(array_format: ArrayFormat, array_index: int) -> str:
+ if array_format == "brackets":
+ return "[]"
+ if array_format == "indices":
+ return f"[{array_index}]"
+ if array_format == "repeat" or array_format == "comma":
+ # Both repeat the bare field name for each file part; there is no
+ # meaningful way to comma-join binary parts.
+ return ""
+ raise NotImplementedError(
+ f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}"
+ )
+
+
def _extract_items(
obj: object,
path: Sequence[str],
*,
index: int,
flattened_key: str | None,
+ array_format: ArrayFormat,
) -> list[tuple[str, FileTypes]]:
try:
key = path[index]
@@ -75,9 +95,11 @@ def _extract_items(
if is_list(obj):
files: list[tuple[str, FileTypes]] = []
- for entry in obj:
- assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "")
- files.append((flattened_key + "[]", cast(FileTypes, entry)))
+ for array_index, entry in enumerate(obj):
+ suffix = _array_suffix(array_format, array_index)
+ emitted_key = (flattened_key + suffix) if flattened_key else suffix
+ assert_is_file_content(entry, key=emitted_key)
+ files.append((emitted_key, cast(FileTypes, entry)))
return files
assert_is_file_content(obj, key=flattened_key)
@@ -86,8 +108,9 @@ def _extract_items(
index += 1
if is_dict(obj):
try:
- # We are at the last entry in the path so we must remove the field
- if (len(path)) == index:
+ # Remove the field if there are no more dict keys in the path,
+ # only "" traversal markers or end.
+ if all(p == "" for p in path[index:]):
item = obj.pop(key)
else:
item = obj[key]
@@ -105,6 +128,7 @@ def _extract_items(
path,
index=index,
flattened_key=flattened_key,
+ array_format=array_format,
)
elif is_list(obj):
if key != "":
@@ -116,9 +140,12 @@ def _extract_items(
item,
path,
index=index,
- flattened_key=flattened_key + "[]" if flattened_key is not None else "[]",
+ flattened_key=(
+ (flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index)
+ ),
+ array_format=array_format,
)
- for item in obj
+ for array_index, item in enumerate(obj)
]
)
@@ -176,21 +203,6 @@ def is_iterable(obj: object) -> TypeGuard[Iterable[object]]:
return isinstance(obj, Iterable)
-def deepcopy_minimal(item: _T) -> _T:
- """Minimal reimplementation of copy.deepcopy() that will only copy certain object types:
-
- - mappings, e.g. `dict`
- - list
-
- This is done for performance reasons.
- """
- if is_mapping(item):
- return cast(_T, {k: deepcopy_minimal(v) for k, v in item.items()})
- if is_list(item):
- return cast(_T, [deepcopy_minimal(entry) for entry in item])
- return item
-
-
# copied from https://github.com/Rapptz/RoboDanny
def human_join(seq: Sequence[str], *, delim: str = ", ", final: str = "or") -> str:
size = len(seq)
diff --git a/src/orb/_version.py b/src/orb/_version.py
index 11898a79..c5a82e2e 100644
--- a/src/orb/_version.py
+++ b/src/orb/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "orb"
-__version__ = "4.55.0" # x-release-please-version
+__version__ = "4.56.0" # x-release-please-version
diff --git a/src/orb/resources/alerts.py b/src/orb/resources/alerts.py
index 84f485f9..cb54e826 100644
--- a/src/orb/resources/alerts.py
+++ b/src/orb/resources/alerts.py
@@ -18,8 +18,8 @@
alert_create_for_subscription_params,
alert_create_for_external_customer_params,
)
-from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -32,6 +32,13 @@
class Alerts(SyncAPIResource):
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
+
@cached_property
def with_raw_response(self) -> AlertsWithRawResponse:
"""
@@ -77,7 +84,7 @@ def retrieve(
if not alert_id:
raise ValueError(f"Expected a non-empty value for `alert_id` but received {alert_id!r}")
return self._get(
- f"/alerts/{alert_id}",
+ path_template("/alerts/{alert_id}", alert_id=alert_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -118,7 +125,7 @@ def update(
f"Expected a non-empty value for `alert_configuration_id` but received {alert_configuration_id!r}"
)
return self._put(
- f"/alerts/{alert_configuration_id}",
+ path_template("/alerts/{alert_configuration_id}", alert_configuration_id=alert_configuration_id),
body=maybe_transform({"thresholds": thresholds}, alert_update_params.AlertUpdateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -254,7 +261,7 @@ def create_for_customer(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._post(
- f"/alerts/customer_id/{customer_id}",
+ path_template("/alerts/customer_id/{customer_id}", customer_id=customer_id),
body=maybe_transform(
{
"currency": currency,
@@ -321,7 +328,9 @@ def create_for_external_customer(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._post(
- f"/alerts/external_customer_id/{external_customer_id}",
+ path_template(
+ "/alerts/external_customer_id/{external_customer_id}", external_customer_id=external_customer_id
+ ),
body=maybe_transform(
{
"currency": currency,
@@ -346,7 +355,11 @@ def create_for_subscription(
*,
thresholds: Iterable[ThresholdParam],
type: Literal["usage_exceeded", "cost_exceeded"],
+ grouping_keys: Optional[SequenceNotStr[str]] | Omit = omit,
metric_id: Optional[str] | Omit = omit,
+ price_filters: Optional[Iterable[alert_create_for_subscription_params.PriceFilter]] | Omit = omit,
+ pricing_unit_id: Optional[str] | Omit = omit,
+ threshold_overrides: Optional[Iterable[alert_create_for_subscription_params.ThresholdOverride]] | 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,
@@ -373,8 +386,24 @@ def create_for_subscription(
type: The type of alert to create. This must be a valid alert type.
+ grouping_keys: The property keys to group cost alerts by. Only applicable for cost_exceeded
+ alerts.
+
metric_id: The metric to track usage for.
+ price_filters: Filters to scope which prices are included in grouped cost alert evaluation.
+ Supports filtering by price_id, item_id, or price_type with includes/excludes
+ operators. Only applicable when grouping_keys is set.
+
+ pricing_unit_id: The pricing unit to use for grouped cost alerts. Required when grouping_keys is
+ set.
+
+ threshold_overrides: Per-group threshold overrides. Each override maps a specific combination of
+ grouping_keys values to a list of thresholds that fully replaces the default
+ thresholds for that group. An empty thresholds list silences the group. Groups
+ without an override use the default thresholds. Only applicable when
+ grouping_keys is set.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -388,12 +417,16 @@ def create_for_subscription(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/alerts/subscription_id/{subscription_id}",
+ path_template("/alerts/subscription_id/{subscription_id}", subscription_id=subscription_id),
body=maybe_transform(
{
"thresholds": thresholds,
"type": type,
+ "grouping_keys": grouping_keys,
"metric_id": metric_id,
+ "price_filters": price_filters,
+ "pricing_unit_id": pricing_unit_id,
+ "threshold_overrides": threshold_overrides,
},
alert_create_for_subscription_params.AlertCreateForSubscriptionParams,
),
@@ -444,7 +477,7 @@ def disable(
f"Expected a non-empty value for `alert_configuration_id` but received {alert_configuration_id!r}"
)
return self._post(
- f"/alerts/{alert_configuration_id}/disable",
+ path_template("/alerts/{alert_configuration_id}/disable", alert_configuration_id=alert_configuration_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -493,7 +526,7 @@ def enable(
f"Expected a non-empty value for `alert_configuration_id` but received {alert_configuration_id!r}"
)
return self._post(
- f"/alerts/{alert_configuration_id}/enable",
+ path_template("/alerts/{alert_configuration_id}/enable", alert_configuration_id=alert_configuration_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -507,6 +540,13 @@ def enable(
class AsyncAlerts(AsyncAPIResource):
+ """
+ [Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
+ usage, or credit balance and trigger webhooks when a threshold is exceeded.
+
+ Alerts created through the API can be scoped to either customers or subscriptions.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncAlertsWithRawResponse:
"""
@@ -552,7 +592,7 @@ async def retrieve(
if not alert_id:
raise ValueError(f"Expected a non-empty value for `alert_id` but received {alert_id!r}")
return await self._get(
- f"/alerts/{alert_id}",
+ path_template("/alerts/{alert_id}", alert_id=alert_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -593,7 +633,7 @@ async def update(
f"Expected a non-empty value for `alert_configuration_id` but received {alert_configuration_id!r}"
)
return await self._put(
- f"/alerts/{alert_configuration_id}",
+ path_template("/alerts/{alert_configuration_id}", alert_configuration_id=alert_configuration_id),
body=await async_maybe_transform({"thresholds": thresholds}, alert_update_params.AlertUpdateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -729,7 +769,7 @@ async def create_for_customer(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return await self._post(
- f"/alerts/customer_id/{customer_id}",
+ path_template("/alerts/customer_id/{customer_id}", customer_id=customer_id),
body=await async_maybe_transform(
{
"currency": currency,
@@ -796,7 +836,9 @@ async def create_for_external_customer(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return await self._post(
- f"/alerts/external_customer_id/{external_customer_id}",
+ path_template(
+ "/alerts/external_customer_id/{external_customer_id}", external_customer_id=external_customer_id
+ ),
body=await async_maybe_transform(
{
"currency": currency,
@@ -821,7 +863,11 @@ async def create_for_subscription(
*,
thresholds: Iterable[ThresholdParam],
type: Literal["usage_exceeded", "cost_exceeded"],
+ grouping_keys: Optional[SequenceNotStr[str]] | Omit = omit,
metric_id: Optional[str] | Omit = omit,
+ price_filters: Optional[Iterable[alert_create_for_subscription_params.PriceFilter]] | Omit = omit,
+ pricing_unit_id: Optional[str] | Omit = omit,
+ threshold_overrides: Optional[Iterable[alert_create_for_subscription_params.ThresholdOverride]] | 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,
@@ -848,8 +894,24 @@ async def create_for_subscription(
type: The type of alert to create. This must be a valid alert type.
+ grouping_keys: The property keys to group cost alerts by. Only applicable for cost_exceeded
+ alerts.
+
metric_id: The metric to track usage for.
+ price_filters: Filters to scope which prices are included in grouped cost alert evaluation.
+ Supports filtering by price_id, item_id, or price_type with includes/excludes
+ operators. Only applicable when grouping_keys is set.
+
+ pricing_unit_id: The pricing unit to use for grouped cost alerts. Required when grouping_keys is
+ set.
+
+ threshold_overrides: Per-group threshold overrides. Each override maps a specific combination of
+ grouping_keys values to a list of thresholds that fully replaces the default
+ thresholds for that group. An empty thresholds list silences the group. Groups
+ without an override use the default thresholds. Only applicable when
+ grouping_keys is set.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -863,12 +925,16 @@ async def create_for_subscription(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/alerts/subscription_id/{subscription_id}",
+ path_template("/alerts/subscription_id/{subscription_id}", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"thresholds": thresholds,
"type": type,
+ "grouping_keys": grouping_keys,
"metric_id": metric_id,
+ "price_filters": price_filters,
+ "pricing_unit_id": pricing_unit_id,
+ "threshold_overrides": threshold_overrides,
},
alert_create_for_subscription_params.AlertCreateForSubscriptionParams,
),
@@ -919,7 +985,7 @@ async def disable(
f"Expected a non-empty value for `alert_configuration_id` but received {alert_configuration_id!r}"
)
return await self._post(
- f"/alerts/{alert_configuration_id}/disable",
+ path_template("/alerts/{alert_configuration_id}/disable", alert_configuration_id=alert_configuration_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -970,7 +1036,7 @@ async def enable(
f"Expected a non-empty value for `alert_configuration_id` but received {alert_configuration_id!r}"
)
return await self._post(
- f"/alerts/{alert_configuration_id}/enable",
+ path_template("/alerts/{alert_configuration_id}/enable", alert_configuration_id=alert_configuration_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/beta/beta.py b/src/orb/resources/beta/beta.py
index eb85e15f..4a49637c 100644
--- a/src/orb/resources/beta/beta.py
+++ b/src/orb/resources/beta/beta.py
@@ -9,7 +9,7 @@
from ... import _legacy_response
from ...types import beta_create_plan_version_params, beta_set_default_plan_version_params
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -29,8 +29,19 @@
class Beta(SyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def external_plan_id(self) -> ExternalPlanID:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return ExternalPlanID(self._client)
@cached_property
@@ -105,7 +116,7 @@ def create_plan_version(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return self._post(
- f"/plans/{plan_id}/versions",
+ path_template("/plans/{plan_id}/versions", plan_id=plan_id),
body=maybe_transform(
{
"version": version,
@@ -160,7 +171,7 @@ def fetch_plan_version(
if not version:
raise ValueError(f"Expected a non-empty value for `version` but received {version!r}")
return self._get(
- f"/plans/{plan_id}/versions/{version}",
+ path_template("/plans/{plan_id}/versions/{version}", plan_id=plan_id, version=version),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -199,7 +210,7 @@ def set_default_plan_version(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return self._post(
- f"/plans/{plan_id}/set_default_version",
+ path_template("/plans/{plan_id}/set_default_version", plan_id=plan_id),
body=maybe_transform(
{"version": version}, beta_set_default_plan_version_params.BetaSetDefaultPlanVersionParams
),
@@ -215,8 +226,19 @@ def set_default_plan_version(
class AsyncBeta(AsyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def external_plan_id(self) -> AsyncExternalPlanID:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncExternalPlanID(self._client)
@cached_property
@@ -291,7 +313,7 @@ async def create_plan_version(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return await self._post(
- f"/plans/{plan_id}/versions",
+ path_template("/plans/{plan_id}/versions", plan_id=plan_id),
body=await async_maybe_transform(
{
"version": version,
@@ -346,7 +368,7 @@ async def fetch_plan_version(
if not version:
raise ValueError(f"Expected a non-empty value for `version` but received {version!r}")
return await self._get(
- f"/plans/{plan_id}/versions/{version}",
+ path_template("/plans/{plan_id}/versions/{version}", plan_id=plan_id, version=version),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -385,7 +407,7 @@ async def set_default_plan_version(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return await self._post(
- f"/plans/{plan_id}/set_default_version",
+ path_template("/plans/{plan_id}/set_default_version", plan_id=plan_id),
body=await async_maybe_transform(
{"version": version}, beta_set_default_plan_version_params.BetaSetDefaultPlanVersionParams
),
@@ -416,6 +438,11 @@ def __init__(self, beta: Beta) -> None:
@cached_property
def external_plan_id(self) -> ExternalPlanIDWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return ExternalPlanIDWithRawResponse(self._beta.external_plan_id)
@@ -435,6 +462,11 @@ def __init__(self, beta: AsyncBeta) -> None:
@cached_property
def external_plan_id(self) -> AsyncExternalPlanIDWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncExternalPlanIDWithRawResponse(self._beta.external_plan_id)
@@ -454,6 +486,11 @@ def __init__(self, beta: Beta) -> None:
@cached_property
def external_plan_id(self) -> ExternalPlanIDWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return ExternalPlanIDWithStreamingResponse(self._beta.external_plan_id)
@@ -473,4 +510,9 @@ def __init__(self, beta: AsyncBeta) -> None:
@cached_property
def external_plan_id(self) -> AsyncExternalPlanIDWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncExternalPlanIDWithStreamingResponse(self._beta.external_plan_id)
diff --git a/src/orb/resources/beta/external_plan_id.py b/src/orb/resources/beta/external_plan_id.py
index d76ecb35..48aa0a7d 100644
--- a/src/orb/resources/beta/external_plan_id.py
+++ b/src/orb/resources/beta/external_plan_id.py
@@ -8,7 +8,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -21,6 +21,12 @@
class ExternalPlanID(SyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def with_raw_response(self) -> ExternalPlanIDWithRawResponse:
"""
@@ -95,7 +101,7 @@ def create_plan_version(
if not external_plan_id:
raise ValueError(f"Expected a non-empty value for `external_plan_id` but received {external_plan_id!r}")
return self._post(
- f"/plans/external_plan_id/{external_plan_id}/versions",
+ path_template("/plans/external_plan_id/{external_plan_id}/versions", external_plan_id=external_plan_id),
body=maybe_transform(
{
"version": version,
@@ -150,7 +156,11 @@ def fetch_plan_version(
if not version:
raise ValueError(f"Expected a non-empty value for `version` but received {version!r}")
return self._get(
- f"/plans/external_plan_id/{external_plan_id}/versions/{version}",
+ path_template(
+ "/plans/external_plan_id/{external_plan_id}/versions/{version}",
+ external_plan_id=external_plan_id,
+ version=version,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -189,7 +199,9 @@ def set_default_plan_version(
if not external_plan_id:
raise ValueError(f"Expected a non-empty value for `external_plan_id` but received {external_plan_id!r}")
return self._post(
- f"/plans/external_plan_id/{external_plan_id}/set_default_version",
+ path_template(
+ "/plans/external_plan_id/{external_plan_id}/set_default_version", external_plan_id=external_plan_id
+ ),
body=maybe_transform(
{"version": version},
external_plan_id_set_default_plan_version_params.ExternalPlanIDSetDefaultPlanVersionParams,
@@ -206,6 +218,12 @@ def set_default_plan_version(
class AsyncExternalPlanID(AsyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def with_raw_response(self) -> AsyncExternalPlanIDWithRawResponse:
"""
@@ -280,7 +298,7 @@ async def create_plan_version(
if not external_plan_id:
raise ValueError(f"Expected a non-empty value for `external_plan_id` but received {external_plan_id!r}")
return await self._post(
- f"/plans/external_plan_id/{external_plan_id}/versions",
+ path_template("/plans/external_plan_id/{external_plan_id}/versions", external_plan_id=external_plan_id),
body=await async_maybe_transform(
{
"version": version,
@@ -335,7 +353,11 @@ async def fetch_plan_version(
if not version:
raise ValueError(f"Expected a non-empty value for `version` but received {version!r}")
return await self._get(
- f"/plans/external_plan_id/{external_plan_id}/versions/{version}",
+ path_template(
+ "/plans/external_plan_id/{external_plan_id}/versions/{version}",
+ external_plan_id=external_plan_id,
+ version=version,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -374,7 +396,9 @@ async def set_default_plan_version(
if not external_plan_id:
raise ValueError(f"Expected a non-empty value for `external_plan_id` but received {external_plan_id!r}")
return await self._post(
- f"/plans/external_plan_id/{external_plan_id}/set_default_version",
+ path_template(
+ "/plans/external_plan_id/{external_plan_id}/set_default_version", external_plan_id=external_plan_id
+ ),
body=await async_maybe_transform(
{"version": version},
external_plan_id_set_default_plan_version_params.ExternalPlanIDSetDefaultPlanVersionParams,
diff --git a/src/orb/resources/coupons/coupons.py b/src/orb/resources/coupons/coupons.py
index b89662c6..7b3a9dad 100644
--- a/src/orb/resources/coupons/coupons.py
+++ b/src/orb/resources/coupons/coupons.py
@@ -9,7 +9,7 @@
from ... import _legacy_response
from ...types import coupon_list_params, coupon_create_params
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -29,8 +29,15 @@
class Coupons(SyncAPIResource):
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
+
@cached_property
def subscriptions(self) -> Subscriptions:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
return Subscriptions(self._client)
@cached_property
@@ -130,8 +137,7 @@ def list(
The list of coupons is ordered starting from the most recently created coupon.
The response also includes `pagination_metadata`, which lets the caller retrieve
- the next page of results if they exist. More information about pagination can be
- found in the Pagination-metadata schema.
+ the next page of results if they exist.
Args:
cursor: Cursor for pagination. This can be populated by the `next_cursor` value returned
@@ -205,7 +211,7 @@ def archive(
if not coupon_id:
raise ValueError(f"Expected a non-empty value for `coupon_id` but received {coupon_id!r}")
return self._post(
- f"/coupons/{coupon_id}/archive",
+ path_template("/coupons/{coupon_id}/archive", coupon_id=coupon_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -245,7 +251,7 @@ def fetch(
if not coupon_id:
raise ValueError(f"Expected a non-empty value for `coupon_id` but received {coupon_id!r}")
return self._get(
- f"/coupons/{coupon_id}",
+ path_template("/coupons/{coupon_id}", coupon_id=coupon_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -254,8 +260,15 @@ def fetch(
class AsyncCoupons(AsyncAPIResource):
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
+
@cached_property
def subscriptions(self) -> AsyncSubscriptions:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
return AsyncSubscriptions(self._client)
@cached_property
@@ -355,8 +368,7 @@ def list(
The list of coupons is ordered starting from the most recently created coupon.
The response also includes `pagination_metadata`, which lets the caller retrieve
- the next page of results if they exist. More information about pagination can be
- found in the Pagination-metadata schema.
+ the next page of results if they exist.
Args:
cursor: Cursor for pagination. This can be populated by the `next_cursor` value returned
@@ -430,7 +442,7 @@ async def archive(
if not coupon_id:
raise ValueError(f"Expected a non-empty value for `coupon_id` but received {coupon_id!r}")
return await self._post(
- f"/coupons/{coupon_id}/archive",
+ path_template("/coupons/{coupon_id}/archive", coupon_id=coupon_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -470,7 +482,7 @@ async def fetch(
if not coupon_id:
raise ValueError(f"Expected a non-empty value for `coupon_id` but received {coupon_id!r}")
return await self._get(
- f"/coupons/{coupon_id}",
+ path_template("/coupons/{coupon_id}", coupon_id=coupon_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -497,6 +509,9 @@ def __init__(self, coupons: Coupons) -> None:
@cached_property
def subscriptions(self) -> SubscriptionsWithRawResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
return SubscriptionsWithRawResponse(self._coupons.subscriptions)
@@ -519,6 +534,9 @@ def __init__(self, coupons: AsyncCoupons) -> None:
@cached_property
def subscriptions(self) -> AsyncSubscriptionsWithRawResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
return AsyncSubscriptionsWithRawResponse(self._coupons.subscriptions)
@@ -541,6 +559,9 @@ def __init__(self, coupons: Coupons) -> None:
@cached_property
def subscriptions(self) -> SubscriptionsWithStreamingResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
return SubscriptionsWithStreamingResponse(self._coupons.subscriptions)
@@ -563,4 +584,7 @@ def __init__(self, coupons: AsyncCoupons) -> None:
@cached_property
def subscriptions(self) -> AsyncSubscriptionsWithStreamingResponse:
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
return AsyncSubscriptionsWithStreamingResponse(self._coupons.subscriptions)
diff --git a/src/orb/resources/coupons/subscriptions.py b/src/orb/resources/coupons/subscriptions.py
index f3770de4..b8ea4181 100644
--- a/src/orb/resources/coupons/subscriptions.py
+++ b/src/orb/resources/coupons/subscriptions.py
@@ -8,7 +8,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform
+from ..._utils import path_template, maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -21,6 +21,10 @@
class Subscriptions(SyncAPIResource):
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
+
@cached_property
def with_raw_response(self) -> SubscriptionsWithRawResponse:
"""
@@ -76,7 +80,7 @@ def list(
if not coupon_id:
raise ValueError(f"Expected a non-empty value for `coupon_id` but received {coupon_id!r}")
return self._get_api_list(
- f"/coupons/{coupon_id}/subscriptions",
+ path_template("/coupons/{coupon_id}/subscriptions", coupon_id=coupon_id),
page=SyncPage[Subscription],
options=make_request_options(
extra_headers=extra_headers,
@@ -96,6 +100,10 @@ def list(
class AsyncSubscriptions(AsyncAPIResource):
+ """
+ A coupon represents a reusable discount configuration that can be applied either as a fixed or percentage amount to an invoice or subscription. Coupons are activated using a redemption code, which applies the discount to a subscription or invoice. The duration of a coupon determines how long it remains available for use by end users.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncSubscriptionsWithRawResponse:
"""
@@ -151,7 +159,7 @@ def list(
if not coupon_id:
raise ValueError(f"Expected a non-empty value for `coupon_id` but received {coupon_id!r}")
return self._get_api_list(
- f"/coupons/{coupon_id}/subscriptions",
+ path_template("/coupons/{coupon_id}/subscriptions", coupon_id=coupon_id),
page=AsyncPage[Subscription],
options=make_request_options(
extra_headers=extra_headers,
diff --git a/src/orb/resources/credit_blocks.py b/src/orb/resources/credit_blocks.py
index dbba3823..8e30f760 100644
--- a/src/orb/resources/credit_blocks.py
+++ b/src/orb/resources/credit_blocks.py
@@ -6,6 +6,7 @@
from .. import _legacy_response
from .._types import Body, Query, Headers, NoneType, NotGiven, not_given
+from .._utils import path_template
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -17,6 +18,10 @@
class CreditBlocks(SyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> CreditBlocksWithRawResponse:
"""
@@ -62,7 +67,7 @@ def retrieve(
if not block_id:
raise ValueError(f"Expected a non-empty value for `block_id` but received {block_id!r}")
return self._get(
- f"/credit_blocks/{block_id}",
+ path_template("/credit_blocks/{block_id}", block_id=block_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -113,7 +118,7 @@ def delete(
raise ValueError(f"Expected a non-empty value for `block_id` but received {block_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/credit_blocks/{block_id}",
+ path_template("/credit_blocks/{block_id}", block_id=block_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -138,14 +143,17 @@ def list_invoices(
"""
This endpoint returns the credit block and its associated purchasing invoices.
- If a credit block was purchased (as opposed to being manually added or allocated
- from a subscription), this endpoint returns the invoices that were created to
- charge the customer for the credit block. For credit blocks with payment
- schedules spanning multiple periods (e.g., monthly payments over 12 months),
- multiple invoices will be returned.
+ If a credit block was purchased (as opposed to being manually added), this
+ endpoint returns the invoices that were created to charge the customer for the
+ credit block. For credit blocks with payment schedules spanning multiple periods
+ (e.g., monthly payments over 12 months), multiple invoices will be returned.
+
+ For credit blocks created by subscription allocation prices, this endpoint
+ returns the subscription invoice containing the allocation line item that
+ created the block.
- If the credit block was not purchased (e.g., manual increment, allocation), an
- empty invoices list is returned.
+ If the credit block was not purchased (e.g., manual increment), an empty
+ invoices list is returned.
**Note: This endpoint is currently experimental and its interface may change in
future releases. Please contact support before building production integrations
@@ -163,7 +171,7 @@ def list_invoices(
if not block_id:
raise ValueError(f"Expected a non-empty value for `block_id` but received {block_id!r}")
return self._get(
- f"/credit_blocks/{block_id}/invoices",
+ path_template("/credit_blocks/{block_id}/invoices", block_id=block_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -172,6 +180,10 @@ def list_invoices(
class AsyncCreditBlocks(AsyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncCreditBlocksWithRawResponse:
"""
@@ -217,7 +229,7 @@ async def retrieve(
if not block_id:
raise ValueError(f"Expected a non-empty value for `block_id` but received {block_id!r}")
return await self._get(
- f"/credit_blocks/{block_id}",
+ path_template("/credit_blocks/{block_id}", block_id=block_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -268,7 +280,7 @@ async def delete(
raise ValueError(f"Expected a non-empty value for `block_id` but received {block_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/credit_blocks/{block_id}",
+ path_template("/credit_blocks/{block_id}", block_id=block_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -293,14 +305,17 @@ async def list_invoices(
"""
This endpoint returns the credit block and its associated purchasing invoices.
- If a credit block was purchased (as opposed to being manually added or allocated
- from a subscription), this endpoint returns the invoices that were created to
- charge the customer for the credit block. For credit blocks with payment
- schedules spanning multiple periods (e.g., monthly payments over 12 months),
- multiple invoices will be returned.
+ If a credit block was purchased (as opposed to being manually added), this
+ endpoint returns the invoices that were created to charge the customer for the
+ credit block. For credit blocks with payment schedules spanning multiple periods
+ (e.g., monthly payments over 12 months), multiple invoices will be returned.
+
+ For credit blocks created by subscription allocation prices, this endpoint
+ returns the subscription invoice containing the allocation line item that
+ created the block.
- If the credit block was not purchased (e.g., manual increment, allocation), an
- empty invoices list is returned.
+ If the credit block was not purchased (e.g., manual increment), an empty
+ invoices list is returned.
**Note: This endpoint is currently experimental and its interface may change in
future releases. Please contact support before building production integrations
@@ -318,7 +333,7 @@ async def list_invoices(
if not block_id:
raise ValueError(f"Expected a non-empty value for `block_id` but received {block_id!r}")
return await self._get(
- f"/credit_blocks/{block_id}/invoices",
+ path_template("/credit_blocks/{block_id}/invoices", block_id=block_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/orb/resources/credit_notes.py b/src/orb/resources/credit_notes.py
index 0a862b32..98307829 100644
--- a/src/orb/resources/credit_notes.py
+++ b/src/orb/resources/credit_notes.py
@@ -11,7 +11,7 @@
from .. import _legacy_response
from ..types import credit_note_list_params, credit_note_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -23,6 +23,11 @@
class CreditNotes(SyncAPIResource):
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
+
@cached_property
def with_raw_response(self) -> CreditNotesWithRawResponse:
"""
@@ -220,7 +225,7 @@ def fetch(
if not credit_note_id:
raise ValueError(f"Expected a non-empty value for `credit_note_id` but received {credit_note_id!r}")
return self._get(
- f"/credit_notes/{credit_note_id}",
+ path_template("/credit_notes/{credit_note_id}", credit_note_id=credit_note_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -229,6 +234,11 @@ def fetch(
class AsyncCreditNotes(AsyncAPIResource):
+ """
+ The [Credit Note](/invoicing/credit-notes) resource represents a credit that has been applied to a
+ particular invoice.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncCreditNotesWithRawResponse:
"""
@@ -426,7 +436,7 @@ async def fetch(
if not credit_note_id:
raise ValueError(f"Expected a non-empty value for `credit_note_id` but received {credit_note_id!r}")
return await self._get(
- f"/credit_notes/{credit_note_id}",
+ path_template("/credit_notes/{credit_note_id}", credit_note_id=credit_note_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/orb/resources/customers/balance_transactions.py b/src/orb/resources/customers/balance_transactions.py
index cf122136..a35733cb 100644
--- a/src/orb/resources/customers/balance_transactions.py
+++ b/src/orb/resources/customers/balance_transactions.py
@@ -10,7 +10,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -24,6 +24,23 @@
class BalanceTransactions(SyncAPIResource):
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> BalanceTransactionsWithRawResponse:
"""
@@ -78,7 +95,7 @@ def create(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._post(
- f"/customers/{customer_id}/balance_transactions",
+ path_template("/customers/{customer_id}/balance_transactions", customer_id=customer_id),
body=maybe_transform(
{
"amount": amount,
@@ -154,7 +171,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/balance_transactions",
+ path_template("/customers/{customer_id}/balance_transactions", customer_id=customer_id),
page=SyncPage[BalanceTransactionListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -178,6 +195,23 @@ def list(
class AsyncBalanceTransactions(AsyncAPIResource):
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncBalanceTransactionsWithRawResponse:
"""
@@ -232,7 +266,7 @@ async def create(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return await self._post(
- f"/customers/{customer_id}/balance_transactions",
+ path_template("/customers/{customer_id}/balance_transactions", customer_id=customer_id),
body=await async_maybe_transform(
{
"amount": amount,
@@ -308,7 +342,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/balance_transactions",
+ path_template("/customers/{customer_id}/balance_transactions", customer_id=customer_id),
page=AsyncPage[BalanceTransactionListResponse],
options=make_request_options(
extra_headers=extra_headers,
diff --git a/src/orb/resources/customers/costs.py b/src/orb/resources/customers/costs.py
index 6b5f040e..0ccf347b 100644
--- a/src/orb/resources/customers/costs.py
+++ b/src/orb/resources/customers/costs.py
@@ -10,7 +10,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -23,6 +23,23 @@
class Costs(SyncAPIResource):
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> CostsWithRawResponse:
"""
@@ -199,7 +216,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get(
- f"/customers/{customer_id}/costs",
+ path_template("/customers/{customer_id}/costs", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -377,7 +394,10 @@ def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get(
- f"/customers/external_customer_id/{external_customer_id}/costs",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/costs",
+ external_customer_id=external_customer_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -398,6 +418,23 @@ def list_by_external_id(
class AsyncCosts(AsyncAPIResource):
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncCostsWithRawResponse:
"""
@@ -574,7 +611,7 @@ async def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return await self._get(
- f"/customers/{customer_id}/costs",
+ path_template("/customers/{customer_id}/costs", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -752,7 +789,10 @@ async def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return await self._get(
- f"/customers/external_customer_id/{external_customer_id}/costs",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/costs",
+ external_customer_id=external_customer_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/customers/credits/credits.py b/src/orb/resources/customers/credits/credits.py
index bd4f7c3a..21eee7d2 100644
--- a/src/orb/resources/customers/credits/credits.py
+++ b/src/orb/resources/customers/credits/credits.py
@@ -25,7 +25,7 @@
AsyncTopUpsWithStreamingResponse,
)
from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ...._utils import maybe_transform
+from ...._utils import path_template, maybe_transform
from ...._compat import cached_property
from ...._resource import SyncAPIResource, AsyncAPIResource
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -39,12 +39,22 @@
class Credits(SyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def ledger(self) -> Ledger:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return Ledger(self._client)
@cached_property
def top_ups(self) -> TopUps:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return TopUps(self._client)
@cached_property
@@ -121,7 +131,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/credits",
+ path_template("/customers/{customer_id}/credits", customer_id=customer_id),
page=SyncPage[CreditListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -202,7 +212,10 @@ def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get_api_list(
- f"/customers/external_customer_id/{external_customer_id}/credits",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits",
+ external_customer_id=external_customer_id,
+ ),
page=SyncPage[CreditListByExternalIDResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -228,12 +241,22 @@ def list_by_external_id(
class AsyncCredits(AsyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def ledger(self) -> AsyncLedger:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncLedger(self._client)
@cached_property
def top_ups(self) -> AsyncTopUps:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncTopUps(self._client)
@cached_property
@@ -310,7 +333,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/credits",
+ path_template("/customers/{customer_id}/credits", customer_id=customer_id),
page=AsyncPage[CreditListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -391,7 +414,10 @@ def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get_api_list(
- f"/customers/external_customer_id/{external_customer_id}/credits",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits",
+ external_customer_id=external_customer_id,
+ ),
page=AsyncPage[CreditListByExternalIDResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -429,10 +455,16 @@ def __init__(self, credits: Credits) -> None:
@cached_property
def ledger(self) -> LedgerWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return LedgerWithRawResponse(self._credits.ledger)
@cached_property
def top_ups(self) -> TopUpsWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return TopUpsWithRawResponse(self._credits.top_ups)
@@ -449,10 +481,16 @@ def __init__(self, credits: AsyncCredits) -> None:
@cached_property
def ledger(self) -> AsyncLedgerWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncLedgerWithRawResponse(self._credits.ledger)
@cached_property
def top_ups(self) -> AsyncTopUpsWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncTopUpsWithRawResponse(self._credits.top_ups)
@@ -469,10 +507,16 @@ def __init__(self, credits: Credits) -> None:
@cached_property
def ledger(self) -> LedgerWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return LedgerWithStreamingResponse(self._credits.ledger)
@cached_property
def top_ups(self) -> TopUpsWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return TopUpsWithStreamingResponse(self._credits.top_ups)
@@ -489,8 +533,14 @@ def __init__(self, credits: AsyncCredits) -> None:
@cached_property
def ledger(self) -> AsyncLedgerWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncLedgerWithStreamingResponse(self._credits.ledger)
@cached_property
def top_ups(self) -> AsyncTopUpsWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncTopUpsWithStreamingResponse(self._credits.top_ups)
diff --git a/src/orb/resources/customers/credits/ledger.py b/src/orb/resources/customers/credits/ledger.py
index 4ae2e04d..c208d5a2 100644
--- a/src/orb/resources/customers/credits/ledger.py
+++ b/src/orb/resources/customers/credits/ledger.py
@@ -10,7 +10,7 @@
from .... import _legacy_response
from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ...._utils import required_args, maybe_transform, async_maybe_transform
+from ...._utils import path_template, required_args, maybe_transform, async_maybe_transform
from ...._compat import cached_property
from ...._resource import SyncAPIResource, AsyncAPIResource
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -33,6 +33,10 @@
class Ledger(SyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> LedgerWithRawResponse:
"""
@@ -184,7 +188,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/credits/ledger",
+ path_template("/customers/{customer_id}/credits/ledger", customer_id=customer_id),
page=SyncPage[LedgerListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -286,8 +290,14 @@ def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -460,8 +470,14 @@ def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -621,8 +637,14 @@ def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -684,9 +706,9 @@ def create_entry(
return to the customer, up to the block's initial balance.
Args:
- target_expiry_date: A future date (specified in YYYY-MM-DD format) used for expiration change,
- denoting when credits transferred (as part of a partial block expiration) should
- expire.
+ target_expiry_date: A date (specified in YYYY-MM-DD format) used for expiration change, denoting
+ when credits transferred (as part of a partial block expiration) should expire.
+ This date must be on or after the effective date of the credit block.
amount: The number of credits to effect. Note that this is required for increment,
decrement, void, or undo operations.
@@ -790,8 +812,14 @@ def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -953,8 +981,14 @@ def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -1081,7 +1115,7 @@ def create_entry(
return cast(
LedgerCreateEntryResponse,
self._post(
- f"/customers/{customer_id}/credits/ledger_entry",
+ path_template("/customers/{customer_id}/credits/ledger_entry", customer_id=customer_id),
body=maybe_transform(
{
"amount": amount,
@@ -1193,8 +1227,14 @@ def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -1367,8 +1407,14 @@ def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -1528,8 +1574,14 @@ def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -1591,9 +1643,9 @@ def create_entry_by_external_id(
return to the customer, up to the block's initial balance.
Args:
- target_expiry_date: A future date (specified in YYYY-MM-DD format) used for expiration change,
- denoting when credits transferred (as part of a partial block expiration) should
- expire.
+ target_expiry_date: A date (specified in YYYY-MM-DD format) used for expiration change, denoting
+ when credits transferred (as part of a partial block expiration) should expire.
+ This date must be on or after the effective date of the credit block.
amount: The number of credits to effect. Note that this is required for increment,
decrement, void, or undo operations.
@@ -1697,8 +1749,14 @@ def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -1860,8 +1918,14 @@ def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -1994,7 +2058,10 @@ def create_entry_by_external_id(
return cast(
LedgerCreateEntryByExternalIDResponse,
self._post(
- f"/customers/external_customer_id/{external_customer_id}/credits/ledger_entry",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/ledger_entry",
+ external_customer_id=external_customer_id,
+ ),
body=maybe_transform(
{
"amount": amount,
@@ -2160,7 +2227,10 @@ def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get_api_list(
- f"/customers/external_customer_id/{external_customer_id}/credits/ledger",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/ledger",
+ external_customer_id=external_customer_id,
+ ),
page=SyncPage[LedgerListByExternalIDResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -2190,6 +2260,10 @@ def list_by_external_id(
class AsyncLedger(AsyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncLedgerWithRawResponse:
"""
@@ -2341,7 +2415,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/credits/ledger",
+ path_template("/customers/{customer_id}/credits/ledger", customer_id=customer_id),
page=AsyncPage[LedgerListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -2443,8 +2517,14 @@ async def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -2617,8 +2697,14 @@ async def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -2778,8 +2864,14 @@ async def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -2841,9 +2933,9 @@ async def create_entry(
return to the customer, up to the block's initial balance.
Args:
- target_expiry_date: A future date (specified in YYYY-MM-DD format) used for expiration change,
- denoting when credits transferred (as part of a partial block expiration) should
- expire.
+ target_expiry_date: A date (specified in YYYY-MM-DD format) used for expiration change, denoting
+ when credits transferred (as part of a partial block expiration) should expire.
+ This date must be on or after the effective date of the credit block.
amount: The number of credits to effect. Note that this is required for increment,
decrement, void, or undo operations.
@@ -2947,8 +3039,14 @@ async def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -3110,8 +3208,14 @@ async def create_entry(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -3238,7 +3342,7 @@ async def create_entry(
return cast(
LedgerCreateEntryResponse,
await self._post(
- f"/customers/{customer_id}/credits/ledger_entry",
+ path_template("/customers/{customer_id}/credits/ledger_entry", customer_id=customer_id),
body=await async_maybe_transform(
{
"amount": amount,
@@ -3350,8 +3454,14 @@ async def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -3524,8 +3634,14 @@ async def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -3685,8 +3801,14 @@ async def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -3748,9 +3870,9 @@ async def create_entry_by_external_id(
return to the customer, up to the block's initial balance.
Args:
- target_expiry_date: A future date (specified in YYYY-MM-DD format) used for expiration change,
- denoting when credits transferred (as part of a partial block expiration) should
- expire.
+ target_expiry_date: A date (specified in YYYY-MM-DD format) used for expiration change, denoting
+ when credits transferred (as part of a partial block expiration) should expire.
+ This date must be on or after the effective date of the credit block.
amount: The number of credits to effect. Note that this is required for increment,
decrement, void, or undo operations.
@@ -3854,8 +3976,14 @@ async def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -4017,8 +4145,14 @@ async def create_entry_by_external_id(
also generate a one-off invoice for the customer for the credits pre-purchase.
Note that you _must_ provide the `per_unit_cost_basis`, since the total charges
on the invoice are calculated by multiplying the cost basis with the number of
- credit units added. Additionally, Orb also enforces invoice generation when a
- non-zero `per_unit_cost_basis` value is provided.
+ credit units added. If you invoice or handle payment of credits outside of Orb
+ (i.e. marketplace customers), set `mark_as_paid` in the `invoice_settings` to
+ `true` to prevent duplicate invoicing effects.
+
+ - if `per_unit_cost_basis` is greater than zero, an invoice will be generated
+ and `invoice_settings` must be included
+ - if `invoice_settings` is passed, one of either `custom_due_date` or
+ `net_terms` is required to determine the due date
## Deducting Credits
@@ -4151,7 +4285,10 @@ async def create_entry_by_external_id(
return cast(
LedgerCreateEntryByExternalIDResponse,
await self._post(
- f"/customers/external_customer_id/{external_customer_id}/credits/ledger_entry",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/ledger_entry",
+ external_customer_id=external_customer_id,
+ ),
body=await async_maybe_transform(
{
"amount": amount,
@@ -4317,7 +4454,10 @@ def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get_api_list(
- f"/customers/external_customer_id/{external_customer_id}/credits/ledger",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/ledger",
+ external_customer_id=external_customer_id,
+ ),
page=AsyncPage[LedgerListByExternalIDResponse],
options=make_request_options(
extra_headers=extra_headers,
diff --git a/src/orb/resources/customers/credits/top_ups.py b/src/orb/resources/customers/credits/top_ups.py
index 6dc08792..52d2ac9f 100644
--- a/src/orb/resources/customers/credits/top_ups.py
+++ b/src/orb/resources/customers/credits/top_ups.py
@@ -10,7 +10,7 @@
from .... import _legacy_response
from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from ...._utils import maybe_transform, async_maybe_transform
+from ...._utils import path_template, maybe_transform, async_maybe_transform
from ...._compat import cached_property
from ...._resource import SyncAPIResource, AsyncAPIResource
from ...._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -31,6 +31,10 @@
class TopUps(SyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> TopUpsWithRawResponse:
"""
@@ -113,7 +117,7 @@ def create(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._post(
- f"/customers/{customer_id}/credits/top_ups",
+ path_template("/customers/{customer_id}/credits/top_ups", customer_id=customer_id),
body=maybe_transform(
{
"amount": amount,
@@ -171,7 +175,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/credits/top_ups",
+ path_template("/customers/{customer_id}/credits/top_ups", customer_id=customer_id),
page=SyncPage[TopUpListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -223,7 +227,9 @@ def delete(
raise ValueError(f"Expected a non-empty value for `top_up_id` but received {top_up_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/customers/{customer_id}/credits/top_ups/{top_up_id}",
+ path_template(
+ "/customers/{customer_id}/credits/top_ups/{top_up_id}", customer_id=customer_id, top_up_id=top_up_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -299,7 +305,10 @@ def create_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._post(
- f"/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ external_customer_id=external_customer_id,
+ ),
body=maybe_transform(
{
"amount": amount,
@@ -359,7 +368,11 @@ def delete_by_external_id(
raise ValueError(f"Expected a non-empty value for `top_up_id` but received {top_up_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/customers/external_customer_id/{external_customer_id}/credits/top_ups/{top_up_id}",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/top_ups/{top_up_id}",
+ external_customer_id=external_customer_id,
+ top_up_id=top_up_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -406,7 +419,10 @@ def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get_api_list(
- f"/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ external_customer_id=external_customer_id,
+ ),
page=SyncPage[TopUpListByExternalIDResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -426,6 +442,10 @@ def list_by_external_id(
class AsyncTopUps(AsyncAPIResource):
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncTopUpsWithRawResponse:
"""
@@ -508,7 +528,7 @@ async def create(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return await self._post(
- f"/customers/{customer_id}/credits/top_ups",
+ path_template("/customers/{customer_id}/credits/top_ups", customer_id=customer_id),
body=await async_maybe_transform(
{
"amount": amount,
@@ -566,7 +586,7 @@ def list(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get_api_list(
- f"/customers/{customer_id}/credits/top_ups",
+ path_template("/customers/{customer_id}/credits/top_ups", customer_id=customer_id),
page=AsyncPage[TopUpListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -618,7 +638,9 @@ async def delete(
raise ValueError(f"Expected a non-empty value for `top_up_id` but received {top_up_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/customers/{customer_id}/credits/top_ups/{top_up_id}",
+ path_template(
+ "/customers/{customer_id}/credits/top_ups/{top_up_id}", customer_id=customer_id, top_up_id=top_up_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -694,7 +716,10 @@ async def create_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return await self._post(
- f"/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ external_customer_id=external_customer_id,
+ ),
body=await async_maybe_transform(
{
"amount": amount,
@@ -754,7 +779,11 @@ async def delete_by_external_id(
raise ValueError(f"Expected a non-empty value for `top_up_id` but received {top_up_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/customers/external_customer_id/{external_customer_id}/credits/top_ups/{top_up_id}",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/top_ups/{top_up_id}",
+ external_customer_id=external_customer_id,
+ top_up_id=top_up_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -801,7 +830,10 @@ def list_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get_api_list(
- f"/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/credits/top_ups",
+ external_customer_id=external_customer_id,
+ ),
page=AsyncPage[TopUpListByExternalIDResponse],
options=make_request_options(
extra_headers=extra_headers,
diff --git a/src/orb/resources/customers/customers.py b/src/orb/resources/customers/customers.py
index 20ae377a..94d424ab 100644
--- a/src/orb/resources/customers/customers.py
+++ b/src/orb/resources/customers/customers.py
@@ -24,7 +24,7 @@
customer_update_by_external_id_params,
)
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -57,16 +57,68 @@
class Customers(SyncAPIResource):
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
+
@cached_property
def costs(self) -> Costs:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return Costs(self._client)
@cached_property
def credits(self) -> Credits:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return Credits(self._client)
@cached_property
def balance_transactions(self) -> BalanceTransactions:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return BalanceTransactions(self._client)
@cached_property
@@ -104,7 +156,9 @@ def create(
hierarchy: Optional[CustomerHierarchyConfigParam] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
payment_configuration: Optional[customer_create_params.PaymentConfiguration] | Omit = omit,
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
| Omit = omit,
payment_provider_id: Optional[str] | Omit = omit,
reporting_configuration: Optional[NewReportingConfigurationParam] | Omit = omit,
@@ -391,7 +445,9 @@ def update(
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
name: Optional[str] | Omit = omit,
payment_configuration: Optional[customer_update_params.PaymentConfiguration] | Omit = omit,
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
| Omit = omit,
payment_provider_id: Optional[str] | Omit = omit,
reporting_configuration: Optional[NewReportingConfigurationParam] | Omit = omit,
@@ -409,9 +465,10 @@ def update(
"""
This endpoint can be used to update the `payment_provider`,
`payment_provider_id`, `name`, `email`, `email_delivery`, `tax_id`,
- `auto_collection`, `metadata`, `shipping_address`, `billing_address`, and
- `additional_emails` of an existing customer. Other fields on a customer are
- currently immutable.
+ `auto_collection`, `metadata`, `shipping_address`, `billing_address`,
+ `additional_emails`, and `currency` of an existing customer. `currency` can only
+ be set if it has not already been set on the customer. Other fields on a
+ customer are currently immutable.
Args:
additional_emails: Additional email addresses for this customer. If populated, these email
@@ -427,8 +484,10 @@ def update(
manual approval.If `null` is specified, the customer's auto issuance setting
will be inherited from the account-level setting.
- currency: An ISO 4217 currency string used for the customer's invoices and balance. If not
- set at creation time, will be set at subscription creation time.
+ currency: An ISO 4217 currency string used for the customer's invoices and balance. This
+ can only be set if the customer does not already have a currency configured. If
+ not set at creation or update time, it will be set at subscription creation
+ time.
email: A valid customer email, to be used for invoicing and notifications.
@@ -619,7 +678,7 @@ def update(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._put(
- f"/customers/{customer_id}",
+ path_template("/customers/{customer_id}", customer_id=customer_id),
body=maybe_transform(
{
"accounting_sync_configuration": accounting_sync_configuration,
@@ -757,7 +816,7 @@ def delete(
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/customers/{customer_id}",
+ path_template("/customers/{customer_id}", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -800,7 +859,7 @@ def fetch(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return self._get(
- f"/customers/{customer_id}",
+ path_template("/customers/{customer_id}", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -839,7 +898,9 @@ def fetch_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return self._get(
- f"/customers/external_customer_id/{external_customer_id}",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}", external_customer_id=external_customer_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -881,7 +942,7 @@ def sync_payment_methods_from_gateway(
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- f"/customers/{customer_id}/sync_payment_methods_from_gateway",
+ path_template("/customers/{customer_id}/sync_payment_methods_from_gateway", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -929,7 +990,10 @@ def sync_payment_methods_from_gateway_by_external_customer_id(
)
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
- f"/customers/external_customer_id/{external_customer_id}/sync_payment_methods_from_gateway",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/sync_payment_methods_from_gateway",
+ external_customer_id=external_customer_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -957,7 +1021,9 @@ def update_by_external_id(
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
name: Optional[str] | Omit = omit,
payment_configuration: Optional[customer_update_by_external_id_params.PaymentConfiguration] | Omit = omit,
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
| Omit = omit,
payment_provider_id: Optional[str] | Omit = omit,
reporting_configuration: Optional[NewReportingConfigurationParam] | Omit = omit,
@@ -992,8 +1058,10 @@ def update_by_external_id(
manual approval.If `null` is specified, the customer's auto issuance setting
will be inherited from the account-level setting.
- currency: An ISO 4217 currency string used for the customer's invoices and balance. If not
- set at creation time, will be set at subscription creation time.
+ currency: An ISO 4217 currency string used for the customer's invoices and balance. This
+ can only be set if the customer does not already have a currency configured. If
+ not set at creation or update time, it will be set at subscription creation
+ time.
email: A valid customer email, to be used for invoicing and notifications.
@@ -1184,7 +1252,7 @@ def update_by_external_id(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._put(
- f"/customers/external_customer_id/{id}",
+ path_template("/customers/external_customer_id/{id}", id=id),
body=maybe_transform(
{
"accounting_sync_configuration": accounting_sync_configuration,
@@ -1221,16 +1289,68 @@ def update_by_external_id(
class AsyncCustomers(AsyncAPIResource):
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
+
@cached_property
def costs(self) -> AsyncCosts:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return AsyncCosts(self._client)
@cached_property
def credits(self) -> AsyncCredits:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncCredits(self._client)
@cached_property
def balance_transactions(self) -> AsyncBalanceTransactions:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return AsyncBalanceTransactions(self._client)
@cached_property
@@ -1268,7 +1388,9 @@ async def create(
hierarchy: Optional[CustomerHierarchyConfigParam] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
payment_configuration: Optional[customer_create_params.PaymentConfiguration] | Omit = omit,
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
| Omit = omit,
payment_provider_id: Optional[str] | Omit = omit,
reporting_configuration: Optional[NewReportingConfigurationParam] | Omit = omit,
@@ -1555,7 +1677,9 @@ async def update(
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
name: Optional[str] | Omit = omit,
payment_configuration: Optional[customer_update_params.PaymentConfiguration] | Omit = omit,
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
| Omit = omit,
payment_provider_id: Optional[str] | Omit = omit,
reporting_configuration: Optional[NewReportingConfigurationParam] | Omit = omit,
@@ -1573,9 +1697,10 @@ async def update(
"""
This endpoint can be used to update the `payment_provider`,
`payment_provider_id`, `name`, `email`, `email_delivery`, `tax_id`,
- `auto_collection`, `metadata`, `shipping_address`, `billing_address`, and
- `additional_emails` of an existing customer. Other fields on a customer are
- currently immutable.
+ `auto_collection`, `metadata`, `shipping_address`, `billing_address`,
+ `additional_emails`, and `currency` of an existing customer. `currency` can only
+ be set if it has not already been set on the customer. Other fields on a
+ customer are currently immutable.
Args:
additional_emails: Additional email addresses for this customer. If populated, these email
@@ -1591,8 +1716,10 @@ async def update(
manual approval.If `null` is specified, the customer's auto issuance setting
will be inherited from the account-level setting.
- currency: An ISO 4217 currency string used for the customer's invoices and balance. If not
- set at creation time, will be set at subscription creation time.
+ currency: An ISO 4217 currency string used for the customer's invoices and balance. This
+ can only be set if the customer does not already have a currency configured. If
+ not set at creation or update time, it will be set at subscription creation
+ time.
email: A valid customer email, to be used for invoicing and notifications.
@@ -1783,7 +1910,7 @@ async def update(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return await self._put(
- f"/customers/{customer_id}",
+ path_template("/customers/{customer_id}", customer_id=customer_id),
body=await async_maybe_transform(
{
"accounting_sync_configuration": accounting_sync_configuration,
@@ -1921,7 +2048,7 @@ async def delete(
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/customers/{customer_id}",
+ path_template("/customers/{customer_id}", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1964,7 +2091,7 @@ async def fetch(
if not customer_id:
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
return await self._get(
- f"/customers/{customer_id}",
+ path_template("/customers/{customer_id}", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -2003,7 +2130,9 @@ async def fetch_by_external_id(
f"Expected a non-empty value for `external_customer_id` but received {external_customer_id!r}"
)
return await self._get(
- f"/customers/external_customer_id/{external_customer_id}",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}", external_customer_id=external_customer_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -2045,7 +2174,7 @@ async def sync_payment_methods_from_gateway(
raise ValueError(f"Expected a non-empty value for `customer_id` but received {customer_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- f"/customers/{customer_id}/sync_payment_methods_from_gateway",
+ path_template("/customers/{customer_id}/sync_payment_methods_from_gateway", customer_id=customer_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -2093,7 +2222,10 @@ async def sync_payment_methods_from_gateway_by_external_customer_id(
)
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
- f"/customers/external_customer_id/{external_customer_id}/sync_payment_methods_from_gateway",
+ path_template(
+ "/customers/external_customer_id/{external_customer_id}/sync_payment_methods_from_gateway",
+ external_customer_id=external_customer_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -2121,7 +2253,9 @@ async def update_by_external_id(
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
name: Optional[str] | Omit = omit,
payment_configuration: Optional[customer_update_by_external_id_params.PaymentConfiguration] | Omit = omit,
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
| Omit = omit,
payment_provider_id: Optional[str] | Omit = omit,
reporting_configuration: Optional[NewReportingConfigurationParam] | Omit = omit,
@@ -2156,8 +2290,10 @@ async def update_by_external_id(
manual approval.If `null` is specified, the customer's auto issuance setting
will be inherited from the account-level setting.
- currency: An ISO 4217 currency string used for the customer's invoices and balance. If not
- set at creation time, will be set at subscription creation time.
+ currency: An ISO 4217 currency string used for the customer's invoices and balance. This
+ can only be set if the customer does not already have a currency configured. If
+ not set at creation or update time, it will be set at subscription creation
+ time.
email: A valid customer email, to be used for invoicing and notifications.
@@ -2348,7 +2484,7 @@ async def update_by_external_id(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._put(
- f"/customers/external_customer_id/{id}",
+ path_template("/customers/external_customer_id/{id}", id=id),
body=await async_maybe_transform(
{
"accounting_sync_configuration": accounting_sync_configuration,
@@ -2418,14 +2554,49 @@ def __init__(self, customers: Customers) -> None:
@cached_property
def costs(self) -> CostsWithRawResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return CostsWithRawResponse(self._customers.costs)
@cached_property
def credits(self) -> CreditsWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return CreditsWithRawResponse(self._customers.credits)
@cached_property
def balance_transactions(self) -> BalanceTransactionsWithRawResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return BalanceTransactionsWithRawResponse(self._customers.balance_transactions)
@@ -2463,14 +2634,49 @@ def __init__(self, customers: AsyncCustomers) -> None:
@cached_property
def costs(self) -> AsyncCostsWithRawResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return AsyncCostsWithRawResponse(self._customers.costs)
@cached_property
def credits(self) -> AsyncCreditsWithRawResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncCreditsWithRawResponse(self._customers.credits)
@cached_property
def balance_transactions(self) -> AsyncBalanceTransactionsWithRawResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return AsyncBalanceTransactionsWithRawResponse(self._customers.balance_transactions)
@@ -2508,14 +2714,49 @@ def __init__(self, customers: Customers) -> None:
@cached_property
def costs(self) -> CostsWithStreamingResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return CostsWithStreamingResponse(self._customers.costs)
@cached_property
def credits(self) -> CreditsWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return CreditsWithStreamingResponse(self._customers.credits)
@cached_property
def balance_transactions(self) -> BalanceTransactionsWithStreamingResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return BalanceTransactionsWithStreamingResponse(self._customers.balance_transactions)
@@ -2553,12 +2794,47 @@ def __init__(self, customers: AsyncCustomers) -> None:
@cached_property
def costs(self) -> AsyncCostsWithStreamingResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return AsyncCostsWithStreamingResponse(self._customers.costs)
@cached_property
def credits(self) -> AsyncCreditsWithStreamingResponse:
+ """
+ The [Credit Ledger Entry resource](/product-catalog/prepurchase) models prepaid credits within Orb.
+ """
return AsyncCreditsWithStreamingResponse(self._customers.credits)
@cached_property
def balance_transactions(self) -> AsyncBalanceTransactionsWithStreamingResponse:
+ """
+ A customer is a buyer of your products, and the other party to the billing relationship.
+
+ In Orb, customers are assigned system generated identifiers automatically, but it's often desirable to have these
+ match existing identifiers in your system. To avoid having to denormalize Orb ID information, you can pass in an
+ `external_customer_id` with your own identifier. See
+ [Customer ID Aliases](/events-and-metrics/customer-aliases) for further information about how these
+ aliases work in Orb.
+
+ In addition to having an identifier in your system, a customer may exist in a payment provider solution like
+ Stripe. Use the `payment_provider_id` and the `payment_provider` enum field to express this mapping.
+
+ A customer also has a timezone (from the standard [IANA timezone database](https://www.iana.org/time-zones)), which
+ defaults to your account's timezone. See [Timezone localization](/essentials/timezones) for
+ information on what this timezone parameter influences within Orb.
+ """
return AsyncBalanceTransactionsWithStreamingResponse(self._customers.balance_transactions)
diff --git a/src/orb/resources/dimensional_price_groups/dimensional_price_groups.py b/src/orb/resources/dimensional_price_groups/dimensional_price_groups.py
index 8c1367ab..1f0691df 100644
--- a/src/orb/resources/dimensional_price_groups/dimensional_price_groups.py
+++ b/src/orb/resources/dimensional_price_groups/dimensional_price_groups.py
@@ -13,7 +13,7 @@
dimensional_price_group_update_params,
)
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -149,7 +149,10 @@ def retrieve(
f"Expected a non-empty value for `dimensional_price_group_id` but received {dimensional_price_group_id!r}"
)
return self._get(
- f"/dimensional_price_groups/{dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/{dimensional_price_group_id}",
+ dimensional_price_group_id=dimensional_price_group_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -200,7 +203,10 @@ def update(
f"Expected a non-empty value for `dimensional_price_group_id` but received {dimensional_price_group_id!r}"
)
return self._put(
- f"/dimensional_price_groups/{dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/{dimensional_price_group_id}",
+ dimensional_price_group_id=dimensional_price_group_id,
+ ),
body=maybe_transform(
{
"external_dimensional_price_group_id": external_dimensional_price_group_id,
@@ -385,7 +391,10 @@ async def retrieve(
f"Expected a non-empty value for `dimensional_price_group_id` but received {dimensional_price_group_id!r}"
)
return await self._get(
- f"/dimensional_price_groups/{dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/{dimensional_price_group_id}",
+ dimensional_price_group_id=dimensional_price_group_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -436,7 +445,10 @@ async def update(
f"Expected a non-empty value for `dimensional_price_group_id` but received {dimensional_price_group_id!r}"
)
return await self._put(
- f"/dimensional_price_groups/{dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/{dimensional_price_group_id}",
+ dimensional_price_group_id=dimensional_price_group_id,
+ ),
body=await async_maybe_transform(
{
"external_dimensional_price_group_id": external_dimensional_price_group_id,
diff --git a/src/orb/resources/dimensional_price_groups/external_dimensional_price_group_id.py b/src/orb/resources/dimensional_price_groups/external_dimensional_price_group_id.py
index dcd0e4bb..1e3bf12d 100644
--- a/src/orb/resources/dimensional_price_groups/external_dimensional_price_group_id.py
+++ b/src/orb/resources/dimensional_price_groups/external_dimensional_price_group_id.py
@@ -8,7 +8,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -67,7 +67,10 @@ def retrieve(
f"Expected a non-empty value for `external_dimensional_price_group_id` but received {external_dimensional_price_group_id!r}"
)
return self._get(
- f"/dimensional_price_groups/external_dimensional_price_group_id/{external_dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/external_dimensional_price_group_id/{external_dimensional_price_group_id}",
+ external_dimensional_price_group_id=external_dimensional_price_group_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -118,7 +121,10 @@ def update(
f"Expected a non-empty value for `path_external_dimensional_price_group_id` but received {path_external_dimensional_price_group_id!r}"
)
return self._put(
- f"/dimensional_price_groups/external_dimensional_price_group_id/{path_external_dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/external_dimensional_price_group_id/{path_external_dimensional_price_group_id}",
+ path_external_dimensional_price_group_id=path_external_dimensional_price_group_id,
+ ),
body=maybe_transform(
{
"body_external_dimensional_price_group_id": body_external_dimensional_price_group_id,
@@ -185,7 +191,10 @@ async def retrieve(
f"Expected a non-empty value for `external_dimensional_price_group_id` but received {external_dimensional_price_group_id!r}"
)
return await self._get(
- f"/dimensional_price_groups/external_dimensional_price_group_id/{external_dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/external_dimensional_price_group_id/{external_dimensional_price_group_id}",
+ external_dimensional_price_group_id=external_dimensional_price_group_id,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -236,7 +245,10 @@ async def update(
f"Expected a non-empty value for `path_external_dimensional_price_group_id` but received {path_external_dimensional_price_group_id!r}"
)
return await self._put(
- f"/dimensional_price_groups/external_dimensional_price_group_id/{path_external_dimensional_price_group_id}",
+ path_template(
+ "/dimensional_price_groups/external_dimensional_price_group_id/{path_external_dimensional_price_group_id}",
+ path_external_dimensional_price_group_id=path_external_dimensional_price_group_id,
+ ),
body=await async_maybe_transform(
{
"body_external_dimensional_price_group_id": body_external_dimensional_price_group_id,
diff --git a/src/orb/resources/events/backfills.py b/src/orb/resources/events/backfills.py
index 7839e27c..1bfd66e7 100644
--- a/src/orb/resources/events/backfills.py
+++ b/src/orb/resources/events/backfills.py
@@ -9,7 +9,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -26,6 +26,12 @@
class Backfills(SyncAPIResource):
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
+
@cached_property
def with_raw_response(self) -> BackfillsWithRawResponse:
"""
@@ -69,8 +75,8 @@ def create(
3 steps:
1. Create the backfill, specifying its parameters.
- 2. [Ingest](ingest) usage events, referencing the backfill (query parameter
- `backfill_id`).
+ 2. [Ingest](/api-reference/event/ingest-events) usage events, referencing the
+ backfill (query parameter `backfill_id`).
3. [Close](close-backfill) the backfill, propagating the update in past usage
throughout Orb.
@@ -183,8 +189,7 @@ def list(
The list of backfills is ordered starting from the most recently created
backfill. The response also includes
[`pagination_metadata`](/api-reference/pagination), which lets the caller
- retrieve the next page of results if they exist. More information about
- pagination can be found in the [Pagination-metadata schema](pagination).
+ retrieve the next page of results if they exist.
Args:
cursor: Cursor for pagination. This can be populated by the `next_cursor` value returned
@@ -252,7 +257,7 @@ def close(
if not backfill_id:
raise ValueError(f"Expected a non-empty value for `backfill_id` but received {backfill_id!r}")
return self._post(
- f"/events/backfills/{backfill_id}/close",
+ path_template("/events/backfills/{backfill_id}/close", backfill_id=backfill_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -289,7 +294,7 @@ def fetch(
if not backfill_id:
raise ValueError(f"Expected a non-empty value for `backfill_id` but received {backfill_id!r}")
return self._get(
- f"/events/backfills/{backfill_id}",
+ path_template("/events/backfills/{backfill_id}", backfill_id=backfill_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -332,7 +337,7 @@ def revert(
if not backfill_id:
raise ValueError(f"Expected a non-empty value for `backfill_id` but received {backfill_id!r}")
return self._post(
- f"/events/backfills/{backfill_id}/revert",
+ path_template("/events/backfills/{backfill_id}/revert", backfill_id=backfill_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -345,6 +350,12 @@ def revert(
class AsyncBackfills(AsyncAPIResource):
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncBackfillsWithRawResponse:
"""
@@ -388,8 +399,8 @@ async def create(
3 steps:
1. Create the backfill, specifying its parameters.
- 2. [Ingest](ingest) usage events, referencing the backfill (query parameter
- `backfill_id`).
+ 2. [Ingest](/api-reference/event/ingest-events) usage events, referencing the
+ backfill (query parameter `backfill_id`).
3. [Close](close-backfill) the backfill, propagating the update in past usage
throughout Orb.
@@ -502,8 +513,7 @@ def list(
The list of backfills is ordered starting from the most recently created
backfill. The response also includes
[`pagination_metadata`](/api-reference/pagination), which lets the caller
- retrieve the next page of results if they exist. More information about
- pagination can be found in the [Pagination-metadata schema](pagination).
+ retrieve the next page of results if they exist.
Args:
cursor: Cursor for pagination. This can be populated by the `next_cursor` value returned
@@ -571,7 +581,7 @@ async def close(
if not backfill_id:
raise ValueError(f"Expected a non-empty value for `backfill_id` but received {backfill_id!r}")
return await self._post(
- f"/events/backfills/{backfill_id}/close",
+ path_template("/events/backfills/{backfill_id}/close", backfill_id=backfill_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -608,7 +618,7 @@ async def fetch(
if not backfill_id:
raise ValueError(f"Expected a non-empty value for `backfill_id` but received {backfill_id!r}")
return await self._get(
- f"/events/backfills/{backfill_id}",
+ path_template("/events/backfills/{backfill_id}", backfill_id=backfill_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -651,7 +661,7 @@ async def revert(
if not backfill_id:
raise ValueError(f"Expected a non-empty value for `backfill_id` but received {backfill_id!r}")
return await self._post(
- f"/events/backfills/{backfill_id}/revert",
+ path_template("/events/backfills/{backfill_id}/revert", backfill_id=backfill_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/events/events.py b/src/orb/resources/events/events.py
index 0d372f1a..9deeff57 100644
--- a/src/orb/resources/events/events.py
+++ b/src/orb/resources/events/events.py
@@ -18,7 +18,7 @@
)
from ...types import event_ingest_params, event_search_params, event_update_params
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from .backfills import (
Backfills,
@@ -40,12 +40,28 @@
class Events(SyncAPIResource):
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
+
@cached_property
def backfills(self) -> Backfills:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return Backfills(self._client)
@cached_property
def volume(self) -> Volume:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return Volume(self._client)
@cached_property
@@ -159,7 +175,7 @@ def update(
if not event_id:
raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}")
return self._put(
- f"/events/{event_id}",
+ path_template("/events/{event_id}", event_id=event_id),
body=maybe_transform(
{
"event_name": event_name,
@@ -248,7 +264,7 @@ def deprecate(
if not event_id:
raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}")
return self._put(
- f"/events/{event_id}/deprecate",
+ path_template("/events/{event_id}/deprecate", event_id=event_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -591,12 +607,28 @@ def search(
class AsyncEvents(AsyncAPIResource):
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
+
@cached_property
def backfills(self) -> AsyncBackfills:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return AsyncBackfills(self._client)
@cached_property
def volume(self) -> AsyncVolume:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return AsyncVolume(self._client)
@cached_property
@@ -710,7 +742,7 @@ async def update(
if not event_id:
raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}")
return await self._put(
- f"/events/{event_id}",
+ path_template("/events/{event_id}", event_id=event_id),
body=await async_maybe_transform(
{
"event_name": event_name,
@@ -799,7 +831,7 @@ async def deprecate(
if not event_id:
raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}")
return await self._put(
- f"/events/{event_id}/deprecate",
+ path_template("/events/{event_id}/deprecate", event_id=event_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1160,10 +1192,20 @@ def __init__(self, events: Events) -> None:
@cached_property
def backfills(self) -> BackfillsWithRawResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return BackfillsWithRawResponse(self._events.backfills)
@cached_property
def volume(self) -> VolumeWithRawResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return VolumeWithRawResponse(self._events.volume)
@@ -1186,10 +1228,20 @@ def __init__(self, events: AsyncEvents) -> None:
@cached_property
def backfills(self) -> AsyncBackfillsWithRawResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return AsyncBackfillsWithRawResponse(self._events.backfills)
@cached_property
def volume(self) -> AsyncVolumeWithRawResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return AsyncVolumeWithRawResponse(self._events.volume)
@@ -1212,10 +1264,20 @@ def __init__(self, events: Events) -> None:
@cached_property
def backfills(self) -> BackfillsWithStreamingResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return BackfillsWithStreamingResponse(self._events.backfills)
@cached_property
def volume(self) -> VolumeWithStreamingResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return VolumeWithStreamingResponse(self._events.volume)
@@ -1238,8 +1300,18 @@ def __init__(self, events: AsyncEvents) -> None:
@cached_property
def backfills(self) -> AsyncBackfillsWithStreamingResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return AsyncBackfillsWithStreamingResponse(self._events.backfills)
@cached_property
def volume(self) -> AsyncVolumeWithStreamingResponse:
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
return AsyncVolumeWithStreamingResponse(self._events.volume)
diff --git a/src/orb/resources/events/volume.py b/src/orb/resources/events/volume.py
index b2be9b8e..1342b46c 100644
--- a/src/orb/resources/events/volume.py
+++ b/src/orb/resources/events/volume.py
@@ -21,6 +21,12 @@
class Volume(SyncAPIResource):
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
+
@cached_property
def with_raw_response(self) -> VolumeWithRawResponse:
"""
@@ -115,6 +121,12 @@ def list(
class AsyncVolume(AsyncAPIResource):
+ """
+ The [Event](/core-concepts#event) resource represents a usage event that has been created for a
+ customer. Events are the core of Orb's usage-based billing model, and are used to calculate the usage charges for
+ a given billing period.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncVolumeWithRawResponse:
"""
diff --git a/src/orb/resources/invoice_line_items.py b/src/orb/resources/invoice_line_items.py
index 0bc3c106..0c2d31dc 100644
--- a/src/orb/resources/invoice_line_items.py
+++ b/src/orb/resources/invoice_line_items.py
@@ -21,6 +21,13 @@
class InvoiceLineItems(SyncAPIResource):
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
+
@cached_property
def with_raw_response(self) -> InvoiceLineItemsWithRawResponse:
"""
@@ -133,6 +140,13 @@ def create(
class AsyncInvoiceLineItems(AsyncAPIResource):
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncInvoiceLineItemsWithRawResponse:
"""
diff --git a/src/orb/resources/invoices.py b/src/orb/resources/invoices.py
index 6660d1f6..22888133 100644
--- a/src/orb/resources/invoices.py
+++ b/src/orb/resources/invoices.py
@@ -10,6 +10,7 @@
from .. import _legacy_response
from ..types import (
+ invoice_pay_params,
invoice_list_params,
invoice_issue_params,
invoice_create_params,
@@ -20,7 +21,7 @@
invoice_fetch_upcoming_params,
)
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -36,6 +37,13 @@
class Invoices(SyncAPIResource):
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
+
@cached_property
def with_raw_response(self) -> InvoicesWithRawResponse:
"""
@@ -61,6 +69,7 @@ def create(
currency: str,
invoice_date: Union[str, datetime],
line_items: Iterable[invoice_create_params.LineItem],
+ auto_collection: Optional[bool] | Omit = omit,
customer_id: Optional[str] | Omit = omit,
discount: Optional[Discount] | Omit = omit,
due_date: Union[Union[str, date], Union[str, datetime], None] | Omit = omit,
@@ -87,6 +96,10 @@ def create(
invoice_date: Optional invoice date to set. Must be in the past, if not set, `invoice_date` is
set to the current time in the customer's timezone.
+ auto_collection: Determines whether this invoice will automatically attempt to charge a saved
+ payment method, if any. If not specified, the invoice inherits the customer's
+ auto_collection setting.
+
customer_id: The id of the `Customer` to create this invoice for. One of `customer_id` and
`external_customer_id` are required.
@@ -132,6 +145,7 @@ def create(
"currency": currency,
"invoice_date": invoice_date,
"line_items": line_items,
+ "auto_collection": auto_collection,
"customer_id": customer_id,
"discount": discount,
"due_date": due_date,
@@ -157,6 +171,7 @@ def update(
self,
invoice_id: str,
*,
+ auto_collection: Optional[bool] | Omit = omit,
due_date: Union[Union[str, date], Union[str, datetime], None] | Omit = omit,
invoice_date: Union[Union[str, date], Union[str, datetime], None] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
@@ -170,15 +185,20 @@ def update(
idempotency_key: str | None = None,
) -> Invoice:
"""
- This endpoint allows you to update the `metadata`, `net_terms`, `due_date`, and
- `invoice_date` properties on an invoice. If you pass null for the metadata
- value, it will clear any existing metadata for that invoice.
+ This endpoint allows you to update the `metadata`, `net_terms`, `due_date`,
+ `invoice_date`, and `auto_collection` properties on an invoice. If you pass null
+ for the metadata value, it will clear any existing metadata for that invoice.
`metadata` can be modified regardless of invoice state. `net_terms`, `due_date`,
- and `invoice_date` can only be modified if the invoice is in a `draft` state.
- `invoice_date` can only be modified for non-subscription invoices.
+ `invoice_date`, and `auto_collection` can only be modified if the invoice is in
+ a `draft` state. `invoice_date` can only be modified for non-subscription
+ invoices.
Args:
+ auto_collection: Determines whether this invoice will automatically attempt to charge a saved
+ payment method, if any. Can only be modified on draft invoices. If not
+ specified, the invoice's existing setting is unchanged.
+
due_date: An optional custom due date for the invoice. If not set, the due date will be
calculated based on the `net_terms` value.
@@ -207,9 +227,10 @@ def update(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._put(
- f"/invoices/{invoice_id}",
+ path_template("/invoices/{invoice_id}", invoice_id=invoice_id),
body=maybe_transform(
{
+ "auto_collection": auto_collection,
"due_date": due_date,
"invoice_date": invoice_date,
"metadata": metadata,
@@ -271,6 +292,10 @@ def list(
values for each draft invoice, which may not always be up-to-date since Orb
regularly refreshes invoices asynchronously.
+ If you don't need line item details, minimums, maximums, or discounts, prefer
+ the [list invoices summary](/api-reference/invoice/list-invoices-summary)
+ endpoint for better performance.
+
Args:
cursor: Cursor for pagination. This can be populated by the `next_cursor` value returned
from the initial request.
@@ -363,7 +388,11 @@ def delete_line_item(
raise ValueError(f"Expected a non-empty value for `line_item_id` but received {line_item_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
- f"/invoices/{invoice_id}/invoice_line_items/{line_item_id}",
+ path_template(
+ "/invoices/{invoice_id}/invoice_line_items/{line_item_id}",
+ invoice_id=invoice_id,
+ line_item_id=line_item_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -401,7 +430,7 @@ def fetch(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._get(
- f"/invoices/{invoice_id}",
+ path_template("/invoices/{invoice_id}", invoice_id=invoice_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -489,7 +518,7 @@ def issue(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._post(
- f"/invoices/{invoice_id}/issue",
+ path_template("/invoices/{invoice_id}/issue", invoice_id=invoice_id),
body=maybe_transform({"synchronous": synchronous}, invoice_issue_params.InvoiceIssueParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -546,7 +575,7 @@ def issue_summary(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._post(
- f"/invoices/summary/{invoice_id}/issue",
+ path_template("/invoices/summary/{invoice_id}/issue", invoice_id=invoice_id),
body=maybe_transform({"synchronous": synchronous}, invoice_issue_summary_params.InvoiceIssueSummaryParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -700,7 +729,7 @@ def mark_paid(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._post(
- f"/invoices/{invoice_id}/mark_paid",
+ path_template("/invoices/{invoice_id}/mark_paid", invoice_id=invoice_id),
body=maybe_transform(
{
"payment_received_date": payment_received_date,
@@ -723,6 +752,7 @@ def pay(
self,
invoice_id: str,
*,
+ shared_payment_token_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,
@@ -731,11 +761,16 @@ def pay(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> Invoice:
- """
- This endpoint collects payment for an invoice using the customer's default
- payment method. This action can only be taken on invoices with status "issued".
+ """This endpoint collects payment for an invoice.
+
+ By default, it uses the
+ customer's default payment method. Optionally, a shared payment token (SPT) can
+ be provided to pay using agent-granted credentials instead. This action can only
+ be taken on invoices with status "issued".
Args:
+ shared_payment_token_id: The ID of a shared payment token granted by an agent to use for this payment.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -749,7 +784,10 @@ def pay(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._post(
- f"/invoices/{invoice_id}/pay",
+ path_template("/invoices/{invoice_id}/pay", invoice_id=invoice_id),
+ body=maybe_transform(
+ {"shared_payment_token_id": shared_payment_token_id}, invoice_pay_params.InvoicePayParams
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -800,7 +838,7 @@ def void(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._post(
- f"/invoices/{invoice_id}/void",
+ path_template("/invoices/{invoice_id}/void", invoice_id=invoice_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -813,6 +851,13 @@ def void(
class AsyncInvoices(AsyncAPIResource):
+ """
+ An [`Invoice`](/core-concepts#invoice) is a fundamental billing entity, representing the request for payment for
+ a single subscription. This includes a set of line items, which correspond to prices in the subscription's plan and
+ can represent fixed recurring fees or usage-based fees. They are generated at the end of a billing period, or as
+ the result of an action, such as a cancellation.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncInvoicesWithRawResponse:
"""
@@ -838,6 +883,7 @@ async def create(
currency: str,
invoice_date: Union[str, datetime],
line_items: Iterable[invoice_create_params.LineItem],
+ auto_collection: Optional[bool] | Omit = omit,
customer_id: Optional[str] | Omit = omit,
discount: Optional[Discount] | Omit = omit,
due_date: Union[Union[str, date], Union[str, datetime], None] | Omit = omit,
@@ -864,6 +910,10 @@ async def create(
invoice_date: Optional invoice date to set. Must be in the past, if not set, `invoice_date` is
set to the current time in the customer's timezone.
+ auto_collection: Determines whether this invoice will automatically attempt to charge a saved
+ payment method, if any. If not specified, the invoice inherits the customer's
+ auto_collection setting.
+
customer_id: The id of the `Customer` to create this invoice for. One of `customer_id` and
`external_customer_id` are required.
@@ -909,6 +959,7 @@ async def create(
"currency": currency,
"invoice_date": invoice_date,
"line_items": line_items,
+ "auto_collection": auto_collection,
"customer_id": customer_id,
"discount": discount,
"due_date": due_date,
@@ -934,6 +985,7 @@ async def update(
self,
invoice_id: str,
*,
+ auto_collection: Optional[bool] | Omit = omit,
due_date: Union[Union[str, date], Union[str, datetime], None] | Omit = omit,
invoice_date: Union[Union[str, date], Union[str, datetime], None] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
@@ -947,15 +999,20 @@ async def update(
idempotency_key: str | None = None,
) -> Invoice:
"""
- This endpoint allows you to update the `metadata`, `net_terms`, `due_date`, and
- `invoice_date` properties on an invoice. If you pass null for the metadata
- value, it will clear any existing metadata for that invoice.
+ This endpoint allows you to update the `metadata`, `net_terms`, `due_date`,
+ `invoice_date`, and `auto_collection` properties on an invoice. If you pass null
+ for the metadata value, it will clear any existing metadata for that invoice.
`metadata` can be modified regardless of invoice state. `net_terms`, `due_date`,
- and `invoice_date` can only be modified if the invoice is in a `draft` state.
- `invoice_date` can only be modified for non-subscription invoices.
+ `invoice_date`, and `auto_collection` can only be modified if the invoice is in
+ a `draft` state. `invoice_date` can only be modified for non-subscription
+ invoices.
Args:
+ auto_collection: Determines whether this invoice will automatically attempt to charge a saved
+ payment method, if any. Can only be modified on draft invoices. If not
+ specified, the invoice's existing setting is unchanged.
+
due_date: An optional custom due date for the invoice. If not set, the due date will be
calculated based on the `net_terms` value.
@@ -984,9 +1041,10 @@ async def update(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._put(
- f"/invoices/{invoice_id}",
+ path_template("/invoices/{invoice_id}", invoice_id=invoice_id),
body=await async_maybe_transform(
{
+ "auto_collection": auto_collection,
"due_date": due_date,
"invoice_date": invoice_date,
"metadata": metadata,
@@ -1048,6 +1106,10 @@ def list(
values for each draft invoice, which may not always be up-to-date since Orb
regularly refreshes invoices asynchronously.
+ If you don't need line item details, minimums, maximums, or discounts, prefer
+ the [list invoices summary](/api-reference/invoice/list-invoices-summary)
+ endpoint for better performance.
+
Args:
cursor: Cursor for pagination. This can be populated by the `next_cursor` value returned
from the initial request.
@@ -1140,7 +1202,11 @@ async def delete_line_item(
raise ValueError(f"Expected a non-empty value for `line_item_id` but received {line_item_id!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
- f"/invoices/{invoice_id}/invoice_line_items/{line_item_id}",
+ path_template(
+ "/invoices/{invoice_id}/invoice_line_items/{line_item_id}",
+ invoice_id=invoice_id,
+ line_item_id=line_item_id,
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1178,7 +1244,7 @@ async def fetch(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._get(
- f"/invoices/{invoice_id}",
+ path_template("/invoices/{invoice_id}", invoice_id=invoice_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1266,7 +1332,7 @@ async def issue(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._post(
- f"/invoices/{invoice_id}/issue",
+ path_template("/invoices/{invoice_id}/issue", invoice_id=invoice_id),
body=await async_maybe_transform({"synchronous": synchronous}, invoice_issue_params.InvoiceIssueParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -1323,7 +1389,7 @@ async def issue_summary(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._post(
- f"/invoices/summary/{invoice_id}/issue",
+ path_template("/invoices/summary/{invoice_id}/issue", invoice_id=invoice_id),
body=await async_maybe_transform(
{"synchronous": synchronous}, invoice_issue_summary_params.InvoiceIssueSummaryParams
),
@@ -1479,7 +1545,7 @@ async def mark_paid(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._post(
- f"/invoices/{invoice_id}/mark_paid",
+ path_template("/invoices/{invoice_id}/mark_paid", invoice_id=invoice_id),
body=await async_maybe_transform(
{
"payment_received_date": payment_received_date,
@@ -1502,6 +1568,7 @@ async def pay(
self,
invoice_id: str,
*,
+ shared_payment_token_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,
@@ -1510,11 +1577,16 @@ async def pay(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> Invoice:
- """
- This endpoint collects payment for an invoice using the customer's default
- payment method. This action can only be taken on invoices with status "issued".
+ """This endpoint collects payment for an invoice.
+
+ By default, it uses the
+ customer's default payment method. Optionally, a shared payment token (SPT) can
+ be provided to pay using agent-granted credentials instead. This action can only
+ be taken on invoices with status "issued".
Args:
+ shared_payment_token_id: The ID of a shared payment token granted by an agent to use for this payment.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1528,7 +1600,10 @@ async def pay(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._post(
- f"/invoices/{invoice_id}/pay",
+ path_template("/invoices/{invoice_id}/pay", invoice_id=invoice_id),
+ body=await async_maybe_transform(
+ {"shared_payment_token_id": shared_payment_token_id}, invoice_pay_params.InvoicePayParams
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1579,7 +1654,7 @@ async def void(
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._post(
- f"/invoices/{invoice_id}/void",
+ path_template("/invoices/{invoice_id}/void", invoice_id=invoice_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/items.py b/src/orb/resources/items.py
index d1cd7d7d..09589686 100644
--- a/src/orb/resources/items.py
+++ b/src/orb/resources/items.py
@@ -9,7 +9,7 @@
from .. import _legacy_response
from ..types import item_list_params, item_create_params, item_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -21,6 +21,12 @@
class Items(SyncAPIResource):
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
+
@cached_property
def with_raw_response(self) -> ItemsWithRawResponse:
"""
@@ -128,7 +134,7 @@ def update(
if not item_id:
raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}")
return self._put(
- f"/items/{item_id}",
+ path_template("/items/{item_id}", item_id=item_id),
body=maybe_transform(
{
"external_connections": external_connections,
@@ -225,7 +231,7 @@ def archive(
if not item_id:
raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}")
return self._post(
- f"/items/{item_id}/archive",
+ path_template("/items/{item_id}/archive", item_id=item_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -262,7 +268,7 @@ def fetch(
if not item_id:
raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}")
return self._get(
- f"/items/{item_id}",
+ path_template("/items/{item_id}", item_id=item_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -271,6 +277,12 @@ def fetch(
class AsyncItems(AsyncAPIResource):
+ """The Item resource represents a sellable product or good.
+
+ Items are associated with all line items, billable metrics,
+ and prices and are used for defining external sync behavior for invoices and tax calculation purposes.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncItemsWithRawResponse:
"""
@@ -378,7 +390,7 @@ async def update(
if not item_id:
raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}")
return await self._put(
- f"/items/{item_id}",
+ path_template("/items/{item_id}", item_id=item_id),
body=await async_maybe_transform(
{
"external_connections": external_connections,
@@ -475,7 +487,7 @@ async def archive(
if not item_id:
raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}")
return await self._post(
- f"/items/{item_id}/archive",
+ path_template("/items/{item_id}/archive", item_id=item_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -512,7 +524,7 @@ async def fetch(
if not item_id:
raise ValueError(f"Expected a non-empty value for `item_id` but received {item_id!r}")
return await self._get(
- f"/items/{item_id}",
+ path_template("/items/{item_id}", item_id=item_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/orb/resources/license_types.py b/src/orb/resources/license_types.py
index 0809c648..f95b8e07 100644
--- a/src/orb/resources/license_types.py
+++ b/src/orb/resources/license_types.py
@@ -9,7 +9,7 @@
from .. import _legacy_response
from ..types import license_type_list_params, license_type_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -23,6 +23,11 @@
class LicenseTypes(SyncAPIResource):
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
+
@cached_property
def with_raw_response(self) -> LicenseTypesWithRawResponse:
"""
@@ -126,7 +131,7 @@ def retrieve(
if not license_type_id:
raise ValueError(f"Expected a non-empty value for `license_type_id` but received {license_type_id!r}")
return self._get(
- f"/license_types/{license_type_id}",
+ path_template("/license_types/{license_type_id}", license_type_id=license_type_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -188,6 +193,11 @@ def list(
class AsyncLicenseTypes(AsyncAPIResource):
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncLicenseTypesWithRawResponse:
"""
@@ -291,7 +301,7 @@ async def retrieve(
if not license_type_id:
raise ValueError(f"Expected a non-empty value for `license_type_id` but received {license_type_id!r}")
return await self._get(
- f"/license_types/{license_type_id}",
+ path_template("/license_types/{license_type_id}", license_type_id=license_type_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/orb/resources/licenses/external_licenses.py b/src/orb/resources/licenses/external_licenses.py
index 5d5468ff..66b98fc8 100644
--- a/src/orb/resources/licenses/external_licenses.py
+++ b/src/orb/resources/licenses/external_licenses.py
@@ -9,7 +9,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -95,7 +95,9 @@ def get_usage(
f"Expected a non-empty value for `external_license_id` but received {external_license_id!r}"
)
return self._get(
- f"/licenses/external_licenses/{external_license_id}/usage",
+ path_template(
+ "/licenses/external_licenses/{external_license_id}/usage", external_license_id=external_license_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -193,7 +195,9 @@ async def get_usage(
f"Expected a non-empty value for `external_license_id` but received {external_license_id!r}"
)
return await self._get(
- f"/licenses/external_licenses/{external_license_id}/usage",
+ path_template(
+ "/licenses/external_licenses/{external_license_id}/usage", external_license_id=external_license_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/licenses/licenses.py b/src/orb/resources/licenses/licenses.py
index 14a70f77..ea56b1c4 100644
--- a/src/orb/resources/licenses/licenses.py
+++ b/src/orb/resources/licenses/licenses.py
@@ -24,7 +24,7 @@
license_retrieve_by_external_id_params,
)
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -165,7 +165,7 @@ def retrieve(
if not license_id:
raise ValueError(f"Expected a non-empty value for `license_id` but received {license_id!r}")
return self._get(
- f"/licenses/{license_id}",
+ path_template("/licenses/{license_id}", license_id=license_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -265,7 +265,7 @@ def deactivate(
if not license_id:
raise ValueError(f"Expected a non-empty value for `license_id` but received {license_id!r}")
return self._post(
- f"/licenses/{license_id}/deactivate",
+ path_template("/licenses/{license_id}/deactivate", license_id=license_id),
body=maybe_transform({"end_date": end_date}, license_deactivate_params.LicenseDeactivateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -311,7 +311,9 @@ def retrieve_by_external_id(
f"Expected a non-empty value for `external_license_id` but received {external_license_id!r}"
)
return self._get(
- f"/licenses/external_license_id/{external_license_id}",
+ path_template(
+ "/licenses/external_license_id/{external_license_id}", external_license_id=external_license_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -447,7 +449,7 @@ async def retrieve(
if not license_id:
raise ValueError(f"Expected a non-empty value for `license_id` but received {license_id!r}")
return await self._get(
- f"/licenses/{license_id}",
+ path_template("/licenses/{license_id}", license_id=license_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -547,7 +549,7 @@ async def deactivate(
if not license_id:
raise ValueError(f"Expected a non-empty value for `license_id` but received {license_id!r}")
return await self._post(
- f"/licenses/{license_id}/deactivate",
+ path_template("/licenses/{license_id}/deactivate", license_id=license_id),
body=await async_maybe_transform({"end_date": end_date}, license_deactivate_params.LicenseDeactivateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -593,7 +595,9 @@ async def retrieve_by_external_id(
f"Expected a non-empty value for `external_license_id` but received {external_license_id!r}"
)
return await self._get(
- f"/licenses/external_license_id/{external_license_id}",
+ path_template(
+ "/licenses/external_license_id/{external_license_id}", external_license_id=external_license_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/licenses/usage.py b/src/orb/resources/licenses/usage.py
index c58214f7..d78b6e4f 100644
--- a/src/orb/resources/licenses/usage.py
+++ b/src/orb/resources/licenses/usage.py
@@ -9,7 +9,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -159,7 +159,7 @@ def get_usage(
if not license_id:
raise ValueError(f"Expected a non-empty value for `license_id` but received {license_id!r}")
return self._get(
- f"/licenses/{license_id}/usage",
+ path_template("/licenses/{license_id}/usage", license_id=license_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -318,7 +318,7 @@ async def get_usage(
if not license_id:
raise ValueError(f"Expected a non-empty value for `license_id` but received {license_id!r}")
return await self._get(
- f"/licenses/{license_id}/usage",
+ path_template("/licenses/{license_id}/usage", license_id=license_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/metrics.py b/src/orb/resources/metrics.py
index 6f62951d..08492c02 100644
--- a/src/orb/resources/metrics.py
+++ b/src/orb/resources/metrics.py
@@ -10,7 +10,7 @@
from .. import _legacy_response
from ..types import metric_list_params, metric_create_params, metric_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -22,6 +22,11 @@
class Metrics(SyncAPIResource):
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
+
@cached_property
def with_raw_response(self) -> MetricsWithRawResponse:
"""
@@ -144,7 +149,7 @@ def update(
if not metric_id:
raise ValueError(f"Expected a non-empty value for `metric_id` but received {metric_id!r}")
return self._put(
- f"/metrics/{metric_id}",
+ path_template("/metrics/{metric_id}", metric_id=metric_id),
body=maybe_transform({"metadata": metadata}, metric_update_params.MetricUpdateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -242,7 +247,7 @@ def fetch(
if not metric_id:
raise ValueError(f"Expected a non-empty value for `metric_id` but received {metric_id!r}")
return self._get(
- f"/metrics/{metric_id}",
+ path_template("/metrics/{metric_id}", metric_id=metric_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -251,6 +256,11 @@ def fetch(
class AsyncMetrics(AsyncAPIResource):
+ """
+ The Metric resource represents a calculation of a quantity based on events.
+ Metrics are defined by the query that transforms raw usage events into meaningful values for your customers.
+ """
+
@cached_property
def with_raw_response(self) -> AsyncMetricsWithRawResponse:
"""
@@ -373,7 +383,7 @@ async def update(
if not metric_id:
raise ValueError(f"Expected a non-empty value for `metric_id` but received {metric_id!r}")
return await self._put(
- f"/metrics/{metric_id}",
+ path_template("/metrics/{metric_id}", metric_id=metric_id),
body=await async_maybe_transform({"metadata": metadata}, metric_update_params.MetricUpdateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -471,7 +481,7 @@ async def fetch(
if not metric_id:
raise ValueError(f"Expected a non-empty value for `metric_id` but received {metric_id!r}")
return await self._get(
- f"/metrics/{metric_id}",
+ path_template("/metrics/{metric_id}", metric_id=metric_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/orb/resources/plans/external_plan_id.py b/src/orb/resources/plans/external_plan_id.py
index 1017afcc..3a0ea6cc 100644
--- a/src/orb/resources/plans/external_plan_id.py
+++ b/src/orb/resources/plans/external_plan_id.py
@@ -8,7 +8,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -20,6 +20,12 @@
class ExternalPlanID(SyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def with_raw_response(self) -> ExternalPlanIDWithRawResponse:
"""
@@ -43,6 +49,7 @@ def update(
self,
other_external_plan_id: str,
*,
+ description: Optional[str] | Omit = omit,
external_plan_id: Optional[str] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -54,12 +61,14 @@ def update(
idempotency_key: str | None = None,
) -> Plan:
"""
- This endpoint can be used to update the `external_plan_id`, and `metadata` of an
- existing plan.
+ This endpoint can be used to update the `external_plan_id`, `description`, and
+ `metadata` of an existing plan.
Other fields on a plan are currently immutable.
Args:
+ description: An optional user-defined description of the plan.
+
external_plan_id: An optional user-defined ID for this plan resource, used throughout the system
as an alias for this Plan. Use this field to identify a plan by an existing
identifier in your system.
@@ -83,9 +92,12 @@ def update(
f"Expected a non-empty value for `other_external_plan_id` but received {other_external_plan_id!r}"
)
return self._put(
- f"/plans/external_plan_id/{other_external_plan_id}",
+ path_template(
+ "/plans/external_plan_id/{other_external_plan_id}", other_external_plan_id=other_external_plan_id
+ ),
body=maybe_transform(
{
+ "description": description,
"external_plan_id": external_plan_id,
"metadata": metadata,
},
@@ -142,7 +154,7 @@ def fetch(
if not external_plan_id:
raise ValueError(f"Expected a non-empty value for `external_plan_id` but received {external_plan_id!r}")
return self._get(
- f"/plans/external_plan_id/{external_plan_id}",
+ path_template("/plans/external_plan_id/{external_plan_id}", external_plan_id=external_plan_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -151,6 +163,12 @@ def fetch(
class AsyncExternalPlanID(AsyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def with_raw_response(self) -> AsyncExternalPlanIDWithRawResponse:
"""
@@ -174,6 +192,7 @@ async def update(
self,
other_external_plan_id: str,
*,
+ description: Optional[str] | Omit = omit,
external_plan_id: Optional[str] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -185,12 +204,14 @@ async def update(
idempotency_key: str | None = None,
) -> Plan:
"""
- This endpoint can be used to update the `external_plan_id`, and `metadata` of an
- existing plan.
+ This endpoint can be used to update the `external_plan_id`, `description`, and
+ `metadata` of an existing plan.
Other fields on a plan are currently immutable.
Args:
+ description: An optional user-defined description of the plan.
+
external_plan_id: An optional user-defined ID for this plan resource, used throughout the system
as an alias for this Plan. Use this field to identify a plan by an existing
identifier in your system.
@@ -214,9 +235,12 @@ async def update(
f"Expected a non-empty value for `other_external_plan_id` but received {other_external_plan_id!r}"
)
return await self._put(
- f"/plans/external_plan_id/{other_external_plan_id}",
+ path_template(
+ "/plans/external_plan_id/{other_external_plan_id}", other_external_plan_id=other_external_plan_id
+ ),
body=await async_maybe_transform(
{
+ "description": description,
"external_plan_id": external_plan_id,
"metadata": metadata,
},
@@ -273,7 +297,7 @@ async def fetch(
if not external_plan_id:
raise ValueError(f"Expected a non-empty value for `external_plan_id` but received {external_plan_id!r}")
return await self._get(
- f"/plans/external_plan_id/{external_plan_id}",
+ path_template("/plans/external_plan_id/{external_plan_id}", external_plan_id=external_plan_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/orb/resources/plans/migrations.py b/src/orb/resources/plans/migrations.py
index 593a7e10..8655180b 100644
--- a/src/orb/resources/plans/migrations.py
+++ b/src/orb/resources/plans/migrations.py
@@ -8,7 +8,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform
+from ..._utils import path_template, maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -23,6 +23,12 @@
class Migrations(SyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def with_raw_response(self) -> MigrationsWithRawResponse:
"""
@@ -71,7 +77,7 @@ def retrieve(
if not migration_id:
raise ValueError(f"Expected a non-empty value for `migration_id` but received {migration_id!r}")
return self._get(
- f"/plans/{plan_id}/migrations/{migration_id}",
+ path_template("/plans/{plan_id}/migrations/{migration_id}", plan_id=plan_id, migration_id=migration_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -115,7 +121,7 @@ def list(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return self._get_api_list(
- f"/plans/{plan_id}/migrations",
+ path_template("/plans/{plan_id}/migrations", plan_id=plan_id),
page=SyncPage[MigrationListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -165,7 +171,9 @@ def cancel(
if not migration_id:
raise ValueError(f"Expected a non-empty value for `migration_id` but received {migration_id!r}")
return self._post(
- f"/plans/{plan_id}/migrations/{migration_id}/cancel",
+ path_template(
+ "/plans/{plan_id}/migrations/{migration_id}/cancel", plan_id=plan_id, migration_id=migration_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -178,6 +186,12 @@ def cancel(
class AsyncMigrations(AsyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def with_raw_response(self) -> AsyncMigrationsWithRawResponse:
"""
@@ -226,7 +240,7 @@ async def retrieve(
if not migration_id:
raise ValueError(f"Expected a non-empty value for `migration_id` but received {migration_id!r}")
return await self._get(
- f"/plans/{plan_id}/migrations/{migration_id}",
+ path_template("/plans/{plan_id}/migrations/{migration_id}", plan_id=plan_id, migration_id=migration_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -270,7 +284,7 @@ def list(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return self._get_api_list(
- f"/plans/{plan_id}/migrations",
+ path_template("/plans/{plan_id}/migrations", plan_id=plan_id),
page=AsyncPage[MigrationListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -320,7 +334,9 @@ async def cancel(
if not migration_id:
raise ValueError(f"Expected a non-empty value for `migration_id` but received {migration_id!r}")
return await self._post(
- f"/plans/{plan_id}/migrations/{migration_id}/cancel",
+ path_template(
+ "/plans/{plan_id}/migrations/{migration_id}/cancel", plan_id=plan_id, migration_id=migration_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/plans/plans.py b/src/orb/resources/plans/plans.py
index 64d0bad8..58f58f68 100644
--- a/src/orb/resources/plans/plans.py
+++ b/src/orb/resources/plans/plans.py
@@ -11,7 +11,7 @@
from ... import _legacy_response
from ...types import plan_list_params, plan_create_params, plan_update_params
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from .migrations import (
Migrations,
@@ -39,12 +39,28 @@
class Plans(SyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def external_plan_id(self) -> ExternalPlanID:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return ExternalPlanID(self._client)
@cached_property
def migrations(self) -> Migrations:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return Migrations(self._client)
@cached_property
@@ -74,6 +90,7 @@ def create(
prices: Iterable[plan_create_params.Price],
adjustments: Optional[Iterable[plan_create_params.Adjustment]] | Omit = omit,
default_invoice_memo: Optional[str] | Omit = omit,
+ description: Optional[str] | Omit = omit,
external_plan_id: Optional[str] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
net_terms: Optional[int] | Omit = omit,
@@ -102,6 +119,8 @@ def create(
default_invoice_memo: Free-form text which is available on the invoice PDF and the Orb invoice portal.
+ description: An optional user-defined description of the plan.
+
metadata: User-specified key/value pairs for the resource. Individual keys can be removed
by setting the value to `null`, and the entire metadata mapping can be cleared
by setting `metadata` to `null`.
@@ -135,6 +154,7 @@ def create(
"prices": prices,
"adjustments": adjustments,
"default_invoice_memo": default_invoice_memo,
+ "description": description,
"external_plan_id": external_plan_id,
"metadata": metadata,
"net_terms": net_terms,
@@ -157,6 +177,7 @@ def update(
self,
plan_id: str,
*,
+ description: Optional[str] | Omit = omit,
external_plan_id: Optional[str] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -168,12 +189,14 @@ def update(
idempotency_key: str | None = None,
) -> Plan:
"""
- This endpoint can be used to update the `external_plan_id`, and `metadata` of an
- existing plan.
+ This endpoint can be used to update the `external_plan_id`, `description`, and
+ `metadata` of an existing plan.
Other fields on a plan are currently immutable.
Args:
+ description: An optional user-defined description of the plan.
+
external_plan_id: An optional user-defined ID for this plan resource, used throughout the system
as an alias for this Plan. Use this field to identify a plan by an existing
identifier in your system.
@@ -195,9 +218,10 @@ def update(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return self._put(
- f"/plans/{plan_id}",
+ path_template("/plans/{plan_id}", plan_id=plan_id),
body=maybe_transform(
{
+ "description": description,
"external_plan_id": external_plan_id,
"metadata": metadata,
},
@@ -319,7 +343,7 @@ def fetch(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return self._get(
- f"/plans/{plan_id}",
+ path_template("/plans/{plan_id}", plan_id=plan_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -328,12 +352,28 @@ def fetch(
class AsyncPlans(AsyncAPIResource):
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
+
@cached_property
def external_plan_id(self) -> AsyncExternalPlanID:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncExternalPlanID(self._client)
@cached_property
def migrations(self) -> AsyncMigrations:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncMigrations(self._client)
@cached_property
@@ -363,6 +403,7 @@ async def create(
prices: Iterable[plan_create_params.Price],
adjustments: Optional[Iterable[plan_create_params.Adjustment]] | Omit = omit,
default_invoice_memo: Optional[str] | Omit = omit,
+ description: Optional[str] | Omit = omit,
external_plan_id: Optional[str] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
net_terms: Optional[int] | Omit = omit,
@@ -391,6 +432,8 @@ async def create(
default_invoice_memo: Free-form text which is available on the invoice PDF and the Orb invoice portal.
+ description: An optional user-defined description of the plan.
+
metadata: User-specified key/value pairs for the resource. Individual keys can be removed
by setting the value to `null`, and the entire metadata mapping can be cleared
by setting `metadata` to `null`.
@@ -424,6 +467,7 @@ async def create(
"prices": prices,
"adjustments": adjustments,
"default_invoice_memo": default_invoice_memo,
+ "description": description,
"external_plan_id": external_plan_id,
"metadata": metadata,
"net_terms": net_terms,
@@ -446,6 +490,7 @@ async def update(
self,
plan_id: str,
*,
+ description: Optional[str] | Omit = omit,
external_plan_id: Optional[str] | Omit = omit,
metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -457,12 +502,14 @@ async def update(
idempotency_key: str | None = None,
) -> Plan:
"""
- This endpoint can be used to update the `external_plan_id`, and `metadata` of an
- existing plan.
+ This endpoint can be used to update the `external_plan_id`, `description`, and
+ `metadata` of an existing plan.
Other fields on a plan are currently immutable.
Args:
+ description: An optional user-defined description of the plan.
+
external_plan_id: An optional user-defined ID for this plan resource, used throughout the system
as an alias for this Plan. Use this field to identify a plan by an existing
identifier in your system.
@@ -484,9 +531,10 @@ async def update(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return await self._put(
- f"/plans/{plan_id}",
+ path_template("/plans/{plan_id}", plan_id=plan_id),
body=await async_maybe_transform(
{
+ "description": description,
"external_plan_id": external_plan_id,
"metadata": metadata,
},
@@ -608,7 +656,7 @@ async def fetch(
if not plan_id:
raise ValueError(f"Expected a non-empty value for `plan_id` but received {plan_id!r}")
return await self._get(
- f"/plans/{plan_id}",
+ path_template("/plans/{plan_id}", plan_id=plan_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -635,10 +683,20 @@ def __init__(self, plans: Plans) -> None:
@cached_property
def external_plan_id(self) -> ExternalPlanIDWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return ExternalPlanIDWithRawResponse(self._plans.external_plan_id)
@cached_property
def migrations(self) -> MigrationsWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return MigrationsWithRawResponse(self._plans.migrations)
@@ -661,10 +719,20 @@ def __init__(self, plans: AsyncPlans) -> None:
@cached_property
def external_plan_id(self) -> AsyncExternalPlanIDWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncExternalPlanIDWithRawResponse(self._plans.external_plan_id)
@cached_property
def migrations(self) -> AsyncMigrationsWithRawResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncMigrationsWithRawResponse(self._plans.migrations)
@@ -687,10 +755,20 @@ def __init__(self, plans: Plans) -> None:
@cached_property
def external_plan_id(self) -> ExternalPlanIDWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return ExternalPlanIDWithStreamingResponse(self._plans.external_plan_id)
@cached_property
def migrations(self) -> MigrationsWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return MigrationsWithStreamingResponse(self._plans.migrations)
@@ -713,8 +791,18 @@ def __init__(self, plans: AsyncPlans) -> None:
@cached_property
def external_plan_id(self) -> AsyncExternalPlanIDWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncExternalPlanIDWithStreamingResponse(self._plans.external_plan_id)
@cached_property
def migrations(self) -> AsyncMigrationsWithStreamingResponse:
+ """
+ The [Plan](/core-concepts#plan-and-price) resource represents a plan that can be subscribed to by a
+ customer. Plans define the billing behavior of the subscription. You can see more about how to configure prices
+ in the [Price resource](/reference/price).
+ """
return AsyncMigrationsWithStreamingResponse(self._plans.migrations)
diff --git a/src/orb/resources/prices/external_price_id.py b/src/orb/resources/prices/external_price_id.py
index 8d023ee9..541874e3 100644
--- a/src/orb/resources/prices/external_price_id.py
+++ b/src/orb/resources/prices/external_price_id.py
@@ -8,7 +8,7 @@
from ... import _legacy_response
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -20,6 +20,16 @@
class ExternalPriceID(SyncAPIResource):
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
+
@cached_property
def with_raw_response(self) -> ExternalPriceIDWithRawResponse:
"""
@@ -78,7 +88,7 @@ def update(
return cast(
Price,
self._put(
- f"/prices/external_price_id/{external_price_id}",
+ path_template("/prices/external_price_id/{external_price_id}", external_price_id=external_price_id),
body=maybe_transform(
{"metadata": metadata}, external_price_id_update_params.ExternalPriceIDUpdateParams
),
@@ -124,7 +134,7 @@ def fetch(
return cast(
Price,
self._get(
- f"/prices/external_price_id/{external_price_id}",
+ path_template("/prices/external_price_id/{external_price_id}", external_price_id=external_price_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -134,6 +144,16 @@ def fetch(
class AsyncExternalPriceID(AsyncAPIResource):
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
+
@cached_property
def with_raw_response(self) -> AsyncExternalPriceIDWithRawResponse:
"""
@@ -192,7 +212,7 @@ async def update(
return cast(
Price,
await self._put(
- f"/prices/external_price_id/{external_price_id}",
+ path_template("/prices/external_price_id/{external_price_id}", external_price_id=external_price_id),
body=await async_maybe_transform(
{"metadata": metadata}, external_price_id_update_params.ExternalPriceIDUpdateParams
),
@@ -238,7 +258,7 @@ async def fetch(
return cast(
Price,
await self._get(
- f"/prices/external_price_id/{external_price_id}",
+ path_template("/prices/external_price_id/{external_price_id}", external_price_id=external_price_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/orb/resources/prices/prices.py b/src/orb/resources/prices/prices.py
index 1c568a13..25b204cf 100644
--- a/src/orb/resources/prices/prices.py
+++ b/src/orb/resources/prices/prices.py
@@ -18,7 +18,7 @@
price_evaluate_preview_events_params,
)
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import required_args, maybe_transform, async_maybe_transform
+from ..._utils import path_template, required_args, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -49,8 +49,27 @@
class Prices(SyncAPIResource):
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
+
@cached_property
def external_price_id(self) -> ExternalPriceID:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
return ExternalPriceID(self._client)
@cached_property
@@ -2853,6 +2872,105 @@ def create(
"""
...
+ @overload
+ def create(
+ self,
+ *,
+ cadence: Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"],
+ currency: str,
+ daily_credit_allowance_config: price_create_params.NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig,
+ item_id: str,
+ model_type: Literal["daily_credit_allowance"],
+ name: str,
+ billable_metric_id: Optional[str] | Omit = omit,
+ billed_in_advance: Optional[bool] | Omit = omit,
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration] | Omit = omit,
+ conversion_rate: Optional[float] | Omit = omit,
+ conversion_rate_config: Optional[price_create_params.NewFloatingDailyCreditAllowancePriceConversionRateConfig]
+ | Omit = omit,
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration] | Omit = omit,
+ external_price_id: Optional[str] | Omit = omit,
+ fixed_price_quantity: Optional[float] | Omit = omit,
+ invoice_grouping_key: Optional[str] | Omit = omit,
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration] | Omit = omit,
+ license_type_id: Optional[str] | Omit = omit,
+ metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> Price:
+ """
+ This endpoint is used to create a [price](/product-catalog/price-configuration).
+ A price created using this endpoint is always an add-on, meaning that it's not
+ associated with a specific plan and can instead be individually added to
+ subscriptions, including subscriptions on different plans.
+
+ An `external_price_id` can be optionally specified as an alias to allow
+ ergonomic interaction with prices in the Orb API.
+
+ See the [Price resource](/product-catalog/price-configuration) for the
+ specification of different price model configurations possible in this endpoint.
+
+ Args:
+ cadence: The cadence to bill for this price on.
+
+ currency: An ISO 4217 currency string for which this price is billed in.
+
+ daily_credit_allowance_config: Configuration for daily_credit_allowance pricing
+
+ item_id: The id of the item the price will be associated with.
+
+ model_type: The pricing model type
+
+ name: The name of the price.
+
+ billable_metric_id: The id of the billable metric for the price. Only needed if the price is
+ usage-based.
+
+ billed_in_advance: If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+
+ billing_cycle_configuration: For custom cadence: specifies the duration of the billing period in days or
+ months.
+
+ conversion_rate: The per unit conversion rate of the price currency to the invoicing currency.
+
+ conversion_rate_config: The configuration for the rate of the price currency to the invoicing currency.
+
+ dimensional_price_configuration: For dimensional price: specifies a price group and dimension values
+
+ external_price_id: An alias for the price.
+
+ fixed_price_quantity: If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+
+ invoice_grouping_key: The property used to group this price on an invoice
+
+ invoicing_cycle_configuration: Within each billing cycle, specifies the cadence at which invoices are produced.
+ If unspecified, a single invoice is produced per billing cycle.
+
+ license_type_id: The ID of the license type to associate with this price.
+
+ metadata: User-specified key/value pairs for the resource. Individual keys can be removed
+ by setting the value to `null`, and the entire metadata mapping can be cleared
+ by setting `metadata` to `null`.
+
+ 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
+
+ idempotency_key: Specify a custom idempotency key for this request
+ """
+ ...
+
@overload
def create(
self,
@@ -3179,6 +3297,7 @@ def create(
["cadence", "currency", "item_id", "model_type", "name", "scalable_matrix_with_tiered_pricing_config"],
["cadence", "cumulative_grouped_bulk_config", "currency", "item_id", "model_type", "name"],
["cadence", "cumulative_grouped_allocation_config", "currency", "item_id", "model_type", "name"],
+ ["cadence", "currency", "daily_credit_allowance_config", "item_id", "model_type", "name"],
["cadence", "currency", "item_id", "minimum_composite_config", "model_type", "name"],
["cadence", "currency", "item_id", "model_type", "name", "percent_config"],
["cadence", "currency", "event_output_config", "item_id", "model_type", "name"],
@@ -3217,6 +3336,7 @@ def create(
| Literal["scalable_matrix_with_tiered_pricing"]
| Literal["cumulative_grouped_bulk"]
| Literal["cumulative_grouped_allocation"]
+ | Literal["daily_credit_allowance"]
| Literal["minimum_composite"]
| Literal["percent"]
| Literal["event_output"],
@@ -3254,6 +3374,7 @@ def create(
| Optional[price_create_params.NewFloatingScalableMatrixWithTieredPricingPriceConversionRateConfig]
| Optional[price_create_params.NewFloatingCumulativeGroupedBulkPriceConversionRateConfig]
| Optional[price_create_params.NewFloatingCumulativeGroupedAllocationPriceConversionRateConfig]
+ | Optional[price_create_params.NewFloatingDailyCreditAllowancePriceConversionRateConfig]
| Optional[price_create_params.NewFloatingMinimumCompositePriceConversionRateConfig]
| Optional[price_create_params.NewFloatingPercentCompositePriceConversionRateConfig]
| Optional[price_create_params.NewFloatingEventOutputPriceConversionRateConfig]
@@ -3312,6 +3433,8 @@ def create(
| Omit = omit,
cumulative_grouped_allocation_config: price_create_params.NewFloatingCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig
| Omit = omit,
+ daily_credit_allowance_config: price_create_params.NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ | Omit = omit,
minimum_composite_config: price_create_params.NewFloatingMinimumCompositePriceMinimumCompositeConfig
| Omit = omit,
percent_config: price_create_params.NewFloatingPercentCompositePricePercentConfig | Omit = omit,
@@ -3375,6 +3498,7 @@ def create(
"scalable_matrix_with_tiered_pricing_config": scalable_matrix_with_tiered_pricing_config,
"cumulative_grouped_bulk_config": cumulative_grouped_bulk_config,
"cumulative_grouped_allocation_config": cumulative_grouped_allocation_config,
+ "daily_credit_allowance_config": daily_credit_allowance_config,
"minimum_composite_config": minimum_composite_config,
"percent_config": percent_config,
"event_output_config": event_output_config,
@@ -3431,7 +3555,7 @@ def update(
return cast(
Price,
self._put(
- f"/prices/{price_id}",
+ path_template("/prices/{price_id}", price_id=price_id),
body=maybe_transform({"metadata": metadata}, price_update_params.PriceUpdateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -3503,6 +3627,7 @@ def evaluate(
external_customer_id: Optional[str] | Omit = omit,
filter: Optional[str] | Omit = omit,
grouping_keys: SequenceNotStr[str] | Omit = omit,
+ metric_parameter_overrides: Optional[Dict[str, object]] | 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,
@@ -3555,6 +3680,9 @@ def evaluate(
[computed properties](/extensibility/advanced-metrics#computed-properties)) used
to group the underlying billable metric
+ metric_parameter_overrides: Optional overrides for parameterized billable metric parameters. If the metric
+ has parameter definitions and no overrides are provided, defaults will be used.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -3568,7 +3696,7 @@ def evaluate(
if not price_id:
raise ValueError(f"Expected a non-empty value for `price_id` but received {price_id!r}")
return self._post(
- f"/prices/{price_id}/evaluate",
+ path_template("/prices/{price_id}/evaluate", price_id=price_id),
body=maybe_transform(
{
"timeframe_end": timeframe_end,
@@ -3577,6 +3705,7 @@ def evaluate(
"external_customer_id": external_customer_id,
"filter": filter,
"grouping_keys": grouping_keys,
+ "metric_parameter_overrides": metric_parameter_overrides,
},
price_evaluate_params.PriceEvaluateParams,
),
@@ -3791,7 +3920,7 @@ def fetch(
return cast(
Price,
self._get(
- f"/prices/{price_id}",
+ path_template("/prices/{price_id}", price_id=price_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -3801,8 +3930,27 @@ def fetch(
class AsyncPrices(AsyncAPIResource):
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
+
@cached_property
def external_price_id(self) -> AsyncExternalPriceID:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
return AsyncExternalPriceID(self._client)
@cached_property
@@ -6605,6 +6753,105 @@ async def create(
"""
...
+ @overload
+ async def create(
+ self,
+ *,
+ cadence: Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"],
+ currency: str,
+ daily_credit_allowance_config: price_create_params.NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig,
+ item_id: str,
+ model_type: Literal["daily_credit_allowance"],
+ name: str,
+ billable_metric_id: Optional[str] | Omit = omit,
+ billed_in_advance: Optional[bool] | Omit = omit,
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration] | Omit = omit,
+ conversion_rate: Optional[float] | Omit = omit,
+ conversion_rate_config: Optional[price_create_params.NewFloatingDailyCreditAllowancePriceConversionRateConfig]
+ | Omit = omit,
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration] | Omit = omit,
+ external_price_id: Optional[str] | Omit = omit,
+ fixed_price_quantity: Optional[float] | Omit = omit,
+ invoice_grouping_key: Optional[str] | Omit = omit,
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration] | Omit = omit,
+ license_type_id: Optional[str] | Omit = omit,
+ metadata: Optional[Dict[str, Optional[str]]] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ idempotency_key: str | None = None,
+ ) -> Price:
+ """
+ This endpoint is used to create a [price](/product-catalog/price-configuration).
+ A price created using this endpoint is always an add-on, meaning that it's not
+ associated with a specific plan and can instead be individually added to
+ subscriptions, including subscriptions on different plans.
+
+ An `external_price_id` can be optionally specified as an alias to allow
+ ergonomic interaction with prices in the Orb API.
+
+ See the [Price resource](/product-catalog/price-configuration) for the
+ specification of different price model configurations possible in this endpoint.
+
+ Args:
+ cadence: The cadence to bill for this price on.
+
+ currency: An ISO 4217 currency string for which this price is billed in.
+
+ daily_credit_allowance_config: Configuration for daily_credit_allowance pricing
+
+ item_id: The id of the item the price will be associated with.
+
+ model_type: The pricing model type
+
+ name: The name of the price.
+
+ billable_metric_id: The id of the billable metric for the price. Only needed if the price is
+ usage-based.
+
+ billed_in_advance: If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+
+ billing_cycle_configuration: For custom cadence: specifies the duration of the billing period in days or
+ months.
+
+ conversion_rate: The per unit conversion rate of the price currency to the invoicing currency.
+
+ conversion_rate_config: The configuration for the rate of the price currency to the invoicing currency.
+
+ dimensional_price_configuration: For dimensional price: specifies a price group and dimension values
+
+ external_price_id: An alias for the price.
+
+ fixed_price_quantity: If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+
+ invoice_grouping_key: The property used to group this price on an invoice
+
+ invoicing_cycle_configuration: Within each billing cycle, specifies the cadence at which invoices are produced.
+ If unspecified, a single invoice is produced per billing cycle.
+
+ license_type_id: The ID of the license type to associate with this price.
+
+ metadata: User-specified key/value pairs for the resource. Individual keys can be removed
+ by setting the value to `null`, and the entire metadata mapping can be cleared
+ by setting `metadata` to `null`.
+
+ 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
+
+ idempotency_key: Specify a custom idempotency key for this request
+ """
+ ...
+
@overload
async def create(
self,
@@ -6931,6 +7178,7 @@ async def create(
["cadence", "currency", "item_id", "model_type", "name", "scalable_matrix_with_tiered_pricing_config"],
["cadence", "cumulative_grouped_bulk_config", "currency", "item_id", "model_type", "name"],
["cadence", "cumulative_grouped_allocation_config", "currency", "item_id", "model_type", "name"],
+ ["cadence", "currency", "daily_credit_allowance_config", "item_id", "model_type", "name"],
["cadence", "currency", "item_id", "minimum_composite_config", "model_type", "name"],
["cadence", "currency", "item_id", "model_type", "name", "percent_config"],
["cadence", "currency", "event_output_config", "item_id", "model_type", "name"],
@@ -6969,6 +7217,7 @@ async def create(
| Literal["scalable_matrix_with_tiered_pricing"]
| Literal["cumulative_grouped_bulk"]
| Literal["cumulative_grouped_allocation"]
+ | Literal["daily_credit_allowance"]
| Literal["minimum_composite"]
| Literal["percent"]
| Literal["event_output"],
@@ -7006,6 +7255,7 @@ async def create(
| Optional[price_create_params.NewFloatingScalableMatrixWithTieredPricingPriceConversionRateConfig]
| Optional[price_create_params.NewFloatingCumulativeGroupedBulkPriceConversionRateConfig]
| Optional[price_create_params.NewFloatingCumulativeGroupedAllocationPriceConversionRateConfig]
+ | Optional[price_create_params.NewFloatingDailyCreditAllowancePriceConversionRateConfig]
| Optional[price_create_params.NewFloatingMinimumCompositePriceConversionRateConfig]
| Optional[price_create_params.NewFloatingPercentCompositePriceConversionRateConfig]
| Optional[price_create_params.NewFloatingEventOutputPriceConversionRateConfig]
@@ -7064,6 +7314,8 @@ async def create(
| Omit = omit,
cumulative_grouped_allocation_config: price_create_params.NewFloatingCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig
| Omit = omit,
+ daily_credit_allowance_config: price_create_params.NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ | Omit = omit,
minimum_composite_config: price_create_params.NewFloatingMinimumCompositePriceMinimumCompositeConfig
| Omit = omit,
percent_config: price_create_params.NewFloatingPercentCompositePricePercentConfig | Omit = omit,
@@ -7127,6 +7379,7 @@ async def create(
"scalable_matrix_with_tiered_pricing_config": scalable_matrix_with_tiered_pricing_config,
"cumulative_grouped_bulk_config": cumulative_grouped_bulk_config,
"cumulative_grouped_allocation_config": cumulative_grouped_allocation_config,
+ "daily_credit_allowance_config": daily_credit_allowance_config,
"minimum_composite_config": minimum_composite_config,
"percent_config": percent_config,
"event_output_config": event_output_config,
@@ -7183,7 +7436,7 @@ async def update(
return cast(
Price,
await self._put(
- f"/prices/{price_id}",
+ path_template("/prices/{price_id}", price_id=price_id),
body=await async_maybe_transform({"metadata": metadata}, price_update_params.PriceUpdateParams),
options=make_request_options(
extra_headers=extra_headers,
@@ -7255,6 +7508,7 @@ async def evaluate(
external_customer_id: Optional[str] | Omit = omit,
filter: Optional[str] | Omit = omit,
grouping_keys: SequenceNotStr[str] | Omit = omit,
+ metric_parameter_overrides: Optional[Dict[str, object]] | 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,
@@ -7307,6 +7561,9 @@ async def evaluate(
[computed properties](/extensibility/advanced-metrics#computed-properties)) used
to group the underlying billable metric
+ metric_parameter_overrides: Optional overrides for parameterized billable metric parameters. If the metric
+ has parameter definitions and no overrides are provided, defaults will be used.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -7320,7 +7577,7 @@ async def evaluate(
if not price_id:
raise ValueError(f"Expected a non-empty value for `price_id` but received {price_id!r}")
return await self._post(
- f"/prices/{price_id}/evaluate",
+ path_template("/prices/{price_id}/evaluate", price_id=price_id),
body=await async_maybe_transform(
{
"timeframe_end": timeframe_end,
@@ -7329,6 +7586,7 @@ async def evaluate(
"external_customer_id": external_customer_id,
"filter": filter,
"grouping_keys": grouping_keys,
+ "metric_parameter_overrides": metric_parameter_overrides,
},
price_evaluate_params.PriceEvaluateParams,
),
@@ -7543,7 +7801,7 @@ async def fetch(
return cast(
Price,
await self._get(
- f"/prices/{price_id}",
+ path_template("/prices/{price_id}", price_id=price_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -7580,6 +7838,15 @@ def __init__(self, prices: Prices) -> None:
@cached_property
def external_price_id(self) -> ExternalPriceIDWithRawResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
return ExternalPriceIDWithRawResponse(self._prices.external_price_id)
@@ -7611,6 +7878,15 @@ def __init__(self, prices: AsyncPrices) -> None:
@cached_property
def external_price_id(self) -> AsyncExternalPriceIDWithRawResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
return AsyncExternalPriceIDWithRawResponse(self._prices.external_price_id)
@@ -7642,6 +7918,15 @@ def __init__(self, prices: Prices) -> None:
@cached_property
def external_price_id(self) -> ExternalPriceIDWithStreamingResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
return ExternalPriceIDWithStreamingResponse(self._prices.external_price_id)
@@ -7673,4 +7958,13 @@ def __init__(self, prices: AsyncPrices) -> None:
@cached_property
def external_price_id(self) -> AsyncExternalPriceIDWithStreamingResponse:
+ """
+ The Price resource represents a price that can be billed on a subscription, resulting in a charge on an invoice in
+ the form of an invoice line item. Prices take a quantity and determine an amount to bill.
+
+ Orb supports a few different pricing models out of the box. Each of these models is serialized differently in a
+ given Price object. The model_type field determines the key for the configuration object that is present.
+
+ For more on the types of prices, see [the core concepts documentation](/core-concepts#plan-and-price)
+ """
return AsyncExternalPriceIDWithStreamingResponse(self._prices.external_price_id)
diff --git a/src/orb/resources/subscription_changes.py b/src/orb/resources/subscription_changes.py
index 5adbb9e3..65d3309d 100644
--- a/src/orb/resources/subscription_changes.py
+++ b/src/orb/resources/subscription_changes.py
@@ -11,7 +11,7 @@
from .. import _legacy_response
from ..types import subscription_change_list_params, subscription_change_apply_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -81,7 +81,9 @@ def retrieve(
f"Expected a non-empty value for `subscription_change_id` but received {subscription_change_id!r}"
)
return self._get(
- f"/subscription_changes/{subscription_change_id}",
+ path_template(
+ "/subscription_changes/{subscription_change_id}", subscription_change_id=subscription_change_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -201,7 +203,9 @@ def apply(
f"Expected a non-empty value for `subscription_change_id` but received {subscription_change_id!r}"
)
return self._post(
- f"/subscription_changes/{subscription_change_id}/apply",
+ path_template(
+ "/subscription_changes/{subscription_change_id}/apply", subscription_change_id=subscription_change_id
+ ),
body=maybe_transform(
{
"description": description,
@@ -257,7 +261,9 @@ def cancel(
f"Expected a non-empty value for `subscription_change_id` but received {subscription_change_id!r}"
)
return self._post(
- f"/subscription_changes/{subscription_change_id}/cancel",
+ path_template(
+ "/subscription_changes/{subscription_change_id}/cancel", subscription_change_id=subscription_change_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -325,7 +331,9 @@ async def retrieve(
f"Expected a non-empty value for `subscription_change_id` but received {subscription_change_id!r}"
)
return await self._get(
- f"/subscription_changes/{subscription_change_id}",
+ path_template(
+ "/subscription_changes/{subscription_change_id}", subscription_change_id=subscription_change_id
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -445,7 +453,9 @@ async def apply(
f"Expected a non-empty value for `subscription_change_id` but received {subscription_change_id!r}"
)
return await self._post(
- f"/subscription_changes/{subscription_change_id}/apply",
+ path_template(
+ "/subscription_changes/{subscription_change_id}/apply", subscription_change_id=subscription_change_id
+ ),
body=await async_maybe_transform(
{
"description": description,
@@ -501,7 +511,9 @@ async def cancel(
f"Expected a non-empty value for `subscription_change_id` but received {subscription_change_id!r}"
)
return await self._post(
- f"/subscription_changes/{subscription_change_id}/cancel",
+ path_template(
+ "/subscription_changes/{subscription_change_id}/cancel", subscription_change_id=subscription_change_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/orb/resources/subscriptions.py b/src/orb/resources/subscriptions.py
index 0f41dd97..40b908cf 100644
--- a/src/orb/resources/subscriptions.py
+++ b/src/orb/resources/subscriptions.py
@@ -26,7 +26,7 @@
subscription_unschedule_fixed_fee_quantity_updates_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper
@@ -563,7 +563,7 @@ def update(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._put(
- f"/subscriptions/{subscription_id}",
+ path_template("/subscriptions/{subscription_id}", subscription_id=subscription_id),
body=maybe_transform(
{
"auto_collection": auto_collection,
@@ -760,7 +760,7 @@ def cancel(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/cancel",
+ path_template("/subscriptions/{subscription_id}/cancel", subscription_id=subscription_id),
body=maybe_transform(
{
"cancel_option": cancel_option,
@@ -806,7 +806,7 @@ def fetch(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._get(
- f"/subscriptions/{subscription_id}",
+ path_template("/subscriptions/{subscription_id}", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -835,10 +835,10 @@ def fetch_costs(
metric, in usage units rather than a currency).
The semantics of this endpoint exactly mirror those of
- [fetching a customer's costs](fetch-customer-costs). Use this endpoint to limit
- your analysis of costs to a specific subscription for the customer (e.g. to
- de-aggregate costs when a customer's subscription has started and stopped on the
- same day).
+ [fetching a customer's costs](/api-reference/customer/fetch-customer-costs). Use
+ this endpoint to limit your analysis of costs to a specific subscription for the
+ customer (e.g. to de-aggregate costs when a customer's subscription has started
+ and stopped on the same day).
Args:
currency: The currency or custom pricing unit to use.
@@ -863,7 +863,7 @@ def fetch_costs(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._get(
- f"/subscriptions/{subscription_id}/costs",
+ path_template("/subscriptions/{subscription_id}/costs", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -922,7 +922,7 @@ def fetch_schedule(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._get_api_list(
- f"/subscriptions/{subscription_id}/schedule",
+ path_template("/subscriptions/{subscription_id}/schedule", subscription_id=subscription_id),
page=SyncPage[SubscriptionFetchScheduleResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -1193,7 +1193,7 @@ def fetch_usage(
return cast(
SubscriptionUsage,
self._get(
- f"/subscriptions/{subscription_id}/usage",
+ path_template("/subscriptions/{subscription_id}/usage", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1340,7 +1340,7 @@ def price_intervals(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/price_intervals",
+ path_template("/subscriptions/{subscription_id}/price_intervals", subscription_id=subscription_id),
body=maybe_transform(
{
"add": add,
@@ -1407,7 +1407,7 @@ def redeem_coupon(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/redeem_coupon",
+ path_template("/subscriptions/{subscription_id}/redeem_coupon", subscription_id=subscription_id),
body=maybe_transform(
{
"change_option": change_option,
@@ -1745,7 +1745,7 @@ def schedule_plan_change(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/schedule_plan_change",
+ path_template("/subscriptions/{subscription_id}/schedule_plan_change", subscription_id=subscription_id),
body=maybe_transform(
{
"change_option": change_option,
@@ -1826,7 +1826,7 @@ def trigger_phase(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/trigger_phase",
+ path_template("/subscriptions/{subscription_id}/trigger_phase", subscription_id=subscription_id),
body=maybe_transform(
{
"allow_invoice_credit_or_void": allow_invoice_credit_or_void,
@@ -1864,6 +1864,12 @@ def unschedule_cancellation(
cancellation. This operation will turn on auto-renew, ensuring that the
subscription does not end at the currently scheduled cancellation time.
+ Note: uncancellation is a lossy operation. Price intervals that were cut short
+ by the cancellation are extended to infinity (original end dates are lost), and
+ future intervals or phases scheduled after the cancellation time are permanently
+ deleted. For complex subscriptions with phases or scheduled plan changes,
+ consider creating a new plan change instead of uncancelling.
+
Args:
extra_headers: Send extra headers
@@ -1878,7 +1884,7 @@ def unschedule_cancellation(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/unschedule_cancellation",
+ path_template("/subscriptions/{subscription_id}/unschedule_cancellation", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1925,7 +1931,10 @@ def unschedule_fixed_fee_quantity_updates(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/unschedule_fixed_fee_quantity_updates",
+ path_template(
+ "/subscriptions/{subscription_id}/unschedule_fixed_fee_quantity_updates",
+ subscription_id=subscription_id,
+ ),
body=maybe_transform(
{"price_id": price_id},
subscription_unschedule_fixed_fee_quantity_updates_params.SubscriptionUnscheduleFixedFeeQuantityUpdatesParams,
@@ -1970,7 +1979,9 @@ def unschedule_pending_plan_changes(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/unschedule_pending_plan_changes",
+ path_template(
+ "/subscriptions/{subscription_id}/unschedule_pending_plan_changes", subscription_id=subscription_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -2042,7 +2053,9 @@ def update_fixed_fee_quantity(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/update_fixed_fee_quantity",
+ path_template(
+ "/subscriptions/{subscription_id}/update_fixed_fee_quantity", subscription_id=subscription_id
+ ),
body=maybe_transform(
{
"price_id": price_id,
@@ -2118,7 +2131,7 @@ def update_trial(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._post(
- f"/subscriptions/{subscription_id}/update_trial",
+ path_template("/subscriptions/{subscription_id}/update_trial", subscription_id=subscription_id),
body=maybe_transform(
{
"trial_end_date": trial_end_date,
@@ -2658,7 +2671,7 @@ async def update(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._put(
- f"/subscriptions/{subscription_id}",
+ path_template("/subscriptions/{subscription_id}", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"auto_collection": auto_collection,
@@ -2855,7 +2868,7 @@ async def cancel(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/cancel",
+ path_template("/subscriptions/{subscription_id}/cancel", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"cancel_option": cancel_option,
@@ -2901,7 +2914,7 @@ async def fetch(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._get(
- f"/subscriptions/{subscription_id}",
+ path_template("/subscriptions/{subscription_id}", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -2930,10 +2943,10 @@ async def fetch_costs(
metric, in usage units rather than a currency).
The semantics of this endpoint exactly mirror those of
- [fetching a customer's costs](fetch-customer-costs). Use this endpoint to limit
- your analysis of costs to a specific subscription for the customer (e.g. to
- de-aggregate costs when a customer's subscription has started and stopped on the
- same day).
+ [fetching a customer's costs](/api-reference/customer/fetch-customer-costs). Use
+ this endpoint to limit your analysis of costs to a specific subscription for the
+ customer (e.g. to de-aggregate costs when a customer's subscription has started
+ and stopped on the same day).
Args:
currency: The currency or custom pricing unit to use.
@@ -2958,7 +2971,7 @@ async def fetch_costs(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._get(
- f"/subscriptions/{subscription_id}/costs",
+ path_template("/subscriptions/{subscription_id}/costs", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -3017,7 +3030,7 @@ def fetch_schedule(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return self._get_api_list(
- f"/subscriptions/{subscription_id}/schedule",
+ path_template("/subscriptions/{subscription_id}/schedule", subscription_id=subscription_id),
page=AsyncPage[SubscriptionFetchScheduleResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -3288,7 +3301,7 @@ async def fetch_usage(
return cast(
SubscriptionUsage,
await self._get(
- f"/subscriptions/{subscription_id}/usage",
+ path_template("/subscriptions/{subscription_id}/usage", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -3435,7 +3448,7 @@ async def price_intervals(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/price_intervals",
+ path_template("/subscriptions/{subscription_id}/price_intervals", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"add": add,
@@ -3502,7 +3515,7 @@ async def redeem_coupon(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/redeem_coupon",
+ path_template("/subscriptions/{subscription_id}/redeem_coupon", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"change_option": change_option,
@@ -3840,7 +3853,7 @@ async def schedule_plan_change(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/schedule_plan_change",
+ path_template("/subscriptions/{subscription_id}/schedule_plan_change", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"change_option": change_option,
@@ -3921,7 +3934,7 @@ async def trigger_phase(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/trigger_phase",
+ path_template("/subscriptions/{subscription_id}/trigger_phase", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"allow_invoice_credit_or_void": allow_invoice_credit_or_void,
@@ -3959,6 +3972,12 @@ async def unschedule_cancellation(
cancellation. This operation will turn on auto-renew, ensuring that the
subscription does not end at the currently scheduled cancellation time.
+ Note: uncancellation is a lossy operation. Price intervals that were cut short
+ by the cancellation are extended to infinity (original end dates are lost), and
+ future intervals or phases scheduled after the cancellation time are permanently
+ deleted. For complex subscriptions with phases or scheduled plan changes,
+ consider creating a new plan change instead of uncancelling.
+
Args:
extra_headers: Send extra headers
@@ -3973,7 +3992,7 @@ async def unschedule_cancellation(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/unschedule_cancellation",
+ path_template("/subscriptions/{subscription_id}/unschedule_cancellation", subscription_id=subscription_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -4020,7 +4039,10 @@ async def unschedule_fixed_fee_quantity_updates(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/unschedule_fixed_fee_quantity_updates",
+ path_template(
+ "/subscriptions/{subscription_id}/unschedule_fixed_fee_quantity_updates",
+ subscription_id=subscription_id,
+ ),
body=await async_maybe_transform(
{"price_id": price_id},
subscription_unschedule_fixed_fee_quantity_updates_params.SubscriptionUnscheduleFixedFeeQuantityUpdatesParams,
@@ -4065,7 +4087,9 @@ async def unschedule_pending_plan_changes(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/unschedule_pending_plan_changes",
+ path_template(
+ "/subscriptions/{subscription_id}/unschedule_pending_plan_changes", subscription_id=subscription_id
+ ),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -4137,7 +4161,9 @@ async def update_fixed_fee_quantity(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/update_fixed_fee_quantity",
+ path_template(
+ "/subscriptions/{subscription_id}/update_fixed_fee_quantity", subscription_id=subscription_id
+ ),
body=await async_maybe_transform(
{
"price_id": price_id,
@@ -4213,7 +4239,7 @@ async def update_trial(
if not subscription_id:
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
return await self._post(
- f"/subscriptions/{subscription_id}/update_trial",
+ path_template("/subscriptions/{subscription_id}/update_trial", subscription_id=subscription_id),
body=await async_maybe_transform(
{
"trial_end_date": trial_end_date,
diff --git a/src/orb/types/__init__.py b/src/orb/types/__init__.py
index fb4d0969..888766fa 100644
--- a/src/orb/types/__init__.py
+++ b/src/orb/types/__init__.py
@@ -150,6 +150,7 @@
from .alert_list_params import AlertListParams as AlertListParams
from .price_list_params import PriceListParams as PriceListParams
from .coupon_list_params import CouponListParams as CouponListParams
+from .invoice_pay_params import InvoicePayParams as InvoicePayParams
from .item_create_params import ItemCreateParams as ItemCreateParams
from .item_update_params import ItemUpdateParams as ItemUpdateParams
from .metric_list_params import MetricListParams as MetricListParams
diff --git a/src/orb/types/alert.py b/src/orb/types/alert.py
index 433daf36..9381a4a3 100644
--- a/src/orb/types/alert.py
+++ b/src/orb/types/alert.py
@@ -9,7 +9,7 @@
from .shared.customer_minified import CustomerMinified
from .shared.subscription_minified import SubscriptionMinified
-__all__ = ["Alert", "Metric", "Plan", "BalanceAlertStatus", "LicenseType"]
+__all__ = ["Alert", "Metric", "Plan", "BalanceAlertStatus", "LicenseType", "PriceFilter", "ThresholdOverride"]
class Metric(BaseModel):
@@ -51,6 +51,37 @@ class LicenseType(BaseModel):
id: str
+class PriceFilter(BaseModel):
+ field: Literal["price_id", "item_id", "price_type", "currency", "pricing_unit_id"]
+ """The property of the price to filter on."""
+
+ operator: Literal["includes", "excludes"]
+ """Should prices that match the filter be included or excluded."""
+
+ values: List[str]
+ """The IDs or values that match this filter."""
+
+
+class ThresholdOverride(BaseModel):
+ """A per-group threshold override on a grouped cost alert.
+
+ An empty `thresholds` list means the group is silenced (never fires).
+ A non-empty list fully replaces the default thresholds for that group.
+ """
+
+ group_values: List[str]
+ """The values of the grouping keys that identify this group.
+
+ The list length matches the alert's grouping_keys.
+ """
+
+ thresholds: List[Threshold]
+ """The thresholds applied to this group.
+
+ An empty list means the group is silenced.
+ """
+
+
class Alert(BaseModel):
"""
[Alerts within Orb](/product-catalog/configuring-alerts) monitor spending,
@@ -105,5 +136,22 @@ class Alert(BaseModel):
This field is only present for credit balance alerts.
"""
+ grouping_keys: Optional[List[str]] = None
+ """The property keys to group cost alerts by.
+
+ Only present for cost alerts with grouping enabled.
+ """
+
license_type: Optional[LicenseType] = None
"""Minified license type for alert serialization."""
+
+ price_filters: Optional[List[PriceFilter]] = None
+ """Filters scoping which prices are included in grouped cost alert evaluation."""
+
+ threshold_overrides: Optional[List[ThresholdOverride]] = None
+ """Per-group threshold overrides.
+
+ Each override maps a specific combination of grouping_keys values to a
+ replacement threshold list. Only present for grouped cost alerts that have at
+ least one override.
+ """
diff --git a/src/orb/types/alert_create_for_subscription_params.py b/src/orb/types/alert_create_for_subscription_params.py
index 9b8f2208..5777336d 100644
--- a/src/orb/types/alert_create_for_subscription_params.py
+++ b/src/orb/types/alert_create_for_subscription_params.py
@@ -5,9 +5,10 @@
from typing import Iterable, Optional
from typing_extensions import Literal, Required, TypedDict
+from .._types import SequenceNotStr
from .threshold_param import ThresholdParam
-__all__ = ["AlertCreateForSubscriptionParams"]
+__all__ = ["AlertCreateForSubscriptionParams", "PriceFilter", "ThresholdOverride"]
class AlertCreateForSubscriptionParams(TypedDict, total=False):
@@ -17,5 +18,66 @@ class AlertCreateForSubscriptionParams(TypedDict, total=False):
type: Required[Literal["usage_exceeded", "cost_exceeded"]]
"""The type of alert to create. This must be a valid alert type."""
+ grouping_keys: Optional[SequenceNotStr[str]]
+ """The property keys to group cost alerts by.
+
+ Only applicable for cost_exceeded alerts.
+ """
+
metric_id: Optional[str]
"""The metric to track usage for."""
+
+ price_filters: Optional[Iterable[PriceFilter]]
+ """Filters to scope which prices are included in grouped cost alert evaluation.
+
+ Supports filtering by price_id, item_id, or price_type with includes/excludes
+ operators. Only applicable when grouping_keys is set.
+ """
+
+ pricing_unit_id: Optional[str]
+ """The pricing unit to use for grouped cost alerts.
+
+ Required when grouping_keys is set.
+ """
+
+ threshold_overrides: Optional[Iterable[ThresholdOverride]]
+ """Per-group threshold overrides.
+
+ Each override maps a specific combination of grouping_keys values to a list of
+ thresholds that fully replaces the default thresholds for that group. An empty
+ thresholds list silences the group. Groups without an override use the default
+ thresholds. Only applicable when grouping_keys is set.
+ """
+
+
+class PriceFilter(TypedDict, total=False):
+ field: Required[Literal["price_id", "item_id", "price_type", "currency", "pricing_unit_id"]]
+ """The property of the price to filter on."""
+
+ operator: Required[Literal["includes", "excludes"]]
+ """Should prices that match the filter be included or excluded."""
+
+ values: Required[SequenceNotStr[str]]
+ """The IDs or values that match this filter."""
+
+
+class ThresholdOverride(TypedDict, total=False):
+ """Per-group threshold override on a grouped cost alert.
+
+ - An empty `thresholds` list silences alerts for this group (never fires).
+ - A non-empty list fully replaces the default thresholds for this group.
+ """
+
+ group_values: Required[SequenceNotStr[str]]
+ """The values of the grouping keys that identify this group.
+
+ The list length must match the alert's grouping_keys, and values appear in the
+ same order as grouping_keys.
+ """
+
+ thresholds: Required[Iterable[ThresholdParam]]
+ """The thresholds to apply to this group.
+
+ An empty list silences alerts for this group. A non-empty list fully replaces
+ the default thresholds for this group.
+ """
diff --git a/src/orb/types/beta/external_plan_id_create_plan_version_params.py b/src/orb/types/beta/external_plan_id_create_plan_version_params.py
index 6b31bed1..025db34b 100644
--- a/src/orb/types/beta/external_plan_id_create_plan_version_params.py
+++ b/src/orb/types/beta/external_plan_id_create_plan_version_params.py
@@ -5,8 +5,10 @@
from typing import Dict, Union, Iterable, Optional
from typing_extensions import Literal, Required, TypeAlias, TypedDict
+from ..._types import SequenceNotStr
from ..shared_params.new_maximum import NewMaximum
from ..shared_params.new_minimum import NewMinimum
+from ..shared_params.unit_config import UnitConfig
from ..shared_params.new_usage_discount import NewUsageDiscount
from ..shared_params.new_amount_discount import NewAmountDiscount
from ..shared_params.new_plan_bulk_price import NewPlanBulkPrice
@@ -48,6 +50,9 @@
"AddAdjustment",
"AddAdjustmentAdjustment",
"AddPrice",
+ "AddPriceLicenseAllocationPrice",
+ "AddPriceLicenseAllocationPriceLicenseAllocation",
+ "AddPriceLicenseAllocationPriceConversionRateConfig",
"AddPricePrice",
"AddPricePriceNewPlanBulkWithFiltersPrice",
"AddPricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfig",
@@ -64,6 +69,10 @@
"AddPricePriceNewPlanCumulativeGroupedAllocationPrice",
"AddPricePriceNewPlanCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"AddPricePriceNewPlanCumulativeGroupedAllocationPriceConversionRateConfig",
+ "AddPricePriceNewPlanDailyCreditAllowancePrice",
+ "AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "AddPricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig",
"AddPricePriceNewPlanPercentCompositePrice",
"AddPricePriceNewPlanPercentCompositePricePercentConfig",
"AddPricePriceNewPlanPercentCompositePriceConversionRateConfig",
@@ -75,6 +84,9 @@
"ReplaceAdjustment",
"ReplaceAdjustmentAdjustment",
"ReplacePrice",
+ "ReplacePriceLicenseAllocationPrice",
+ "ReplacePriceLicenseAllocationPriceLicenseAllocation",
+ "ReplacePriceLicenseAllocationPriceConversionRateConfig",
"ReplacePricePrice",
"ReplacePricePriceNewPlanBulkWithFiltersPrice",
"ReplacePricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfig",
@@ -91,6 +103,10 @@
"ReplacePricePriceNewPlanCumulativeGroupedAllocationPrice",
"ReplacePricePriceNewPlanCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"ReplacePricePriceNewPlanCumulativeGroupedAllocationPriceConversionRateConfig",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePrice",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig",
"ReplacePricePriceNewPlanPercentCompositePrice",
"ReplacePricePriceNewPlanPercentCompositePricePercentConfig",
"ReplacePricePriceNewPlanPercentCompositePriceConversionRateConfig",
@@ -139,6 +155,115 @@ class AddAdjustment(TypedDict, total=False):
"""The phase to add this adjustment to."""
+class AddPriceLicenseAllocationPriceLicenseAllocation(TypedDict, total=False):
+ amount: Required[str]
+ """The amount of credits granted per active license per cadence."""
+
+ currency: Required[str]
+ """The currency of the license allocation."""
+
+ write_off_overage: Optional[bool]
+ """When True, overage beyond the allocation is written off."""
+
+
+AddPriceLicenseAllocationPriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class AddPriceLicenseAllocationPrice(TypedDict, total=False):
+ """The license allocation price to add to the plan."""
+
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ license_allocations: Required[Iterable[AddPriceLicenseAllocationPriceLicenseAllocation]]
+ """License allocations to associate with this price.
+
+ Each entry defines a per-license credit pool granted each cadence. Requires
+ license_type_id or license_type_configuration to be set.
+ """
+
+ model_type: Required[Literal["unit"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ unit_config: Required[UnitConfig]
+ """Configuration for unit pricing"""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[AddPriceLicenseAllocationPriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class AddPricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfigFilter(TypedDict, total=False):
"""Configuration for a single property filter"""
@@ -581,6 +706,137 @@ class AddPricePriceNewPlanCumulativeGroupedAllocationPrice(TypedDict, total=Fals
"""
+class AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(TypedDict, total=False):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+AddPricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class AddPricePriceNewPlanDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[AddPricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class AddPricePriceNewPlanPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -815,6 +1071,7 @@ class AddPricePriceNewPlanEventOutputPrice(TypedDict, total=False):
NewPlanScalableMatrixWithTieredPricingPrice,
NewPlanCumulativeGroupedBulkPrice,
AddPricePriceNewPlanCumulativeGroupedAllocationPrice,
+ AddPricePriceNewPlanDailyCreditAllowancePrice,
NewPlanMinimumCompositePrice,
AddPricePriceNewPlanPercentCompositePrice,
AddPricePriceNewPlanEventOutputPrice,
@@ -825,6 +1082,9 @@ class AddPrice(TypedDict, total=False):
allocation_price: Optional[NewAllocationPrice]
"""The allocation price to add to the plan."""
+ license_allocation_price: Optional[AddPriceLicenseAllocationPrice]
+ """The license allocation price to add to the plan."""
+
plan_phase_order: Optional[int]
"""The phase to add this price to."""
@@ -864,6 +1124,115 @@ class ReplaceAdjustment(TypedDict, total=False):
"""The phase to replace this adjustment from."""
+class ReplacePriceLicenseAllocationPriceLicenseAllocation(TypedDict, total=False):
+ amount: Required[str]
+ """The amount of credits granted per active license per cadence."""
+
+ currency: Required[str]
+ """The currency of the license allocation."""
+
+ write_off_overage: Optional[bool]
+ """When True, overage beyond the allocation is written off."""
+
+
+ReplacePriceLicenseAllocationPriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class ReplacePriceLicenseAllocationPrice(TypedDict, total=False):
+ """The license allocation price to add to the plan."""
+
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ license_allocations: Required[Iterable[ReplacePriceLicenseAllocationPriceLicenseAllocation]]
+ """License allocations to associate with this price.
+
+ Each entry defines a per-license credit pool granted each cadence. Requires
+ license_type_id or license_type_configuration to be set.
+ """
+
+ model_type: Required[Literal["unit"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ unit_config: Required[UnitConfig]
+ """Configuration for unit pricing"""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[ReplacePriceLicenseAllocationPriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class ReplacePricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfigFilter(TypedDict, total=False):
"""Configuration for a single property filter"""
@@ -1306,6 +1675,137 @@ class ReplacePricePriceNewPlanCumulativeGroupedAllocationPrice(TypedDict, total=
"""
+class ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(TypedDict, total=False):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+ReplacePricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class ReplacePricePriceNewPlanDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[ReplacePricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class ReplacePricePriceNewPlanPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -1540,6 +2040,7 @@ class ReplacePricePriceNewPlanEventOutputPrice(TypedDict, total=False):
NewPlanScalableMatrixWithTieredPricingPrice,
NewPlanCumulativeGroupedBulkPrice,
ReplacePricePriceNewPlanCumulativeGroupedAllocationPrice,
+ ReplacePricePriceNewPlanDailyCreditAllowancePrice,
NewPlanMinimumCompositePrice,
ReplacePricePriceNewPlanPercentCompositePrice,
ReplacePricePriceNewPlanEventOutputPrice,
@@ -1553,6 +2054,9 @@ class ReplacePrice(TypedDict, total=False):
allocation_price: Optional[NewAllocationPrice]
"""The allocation price to add to the plan."""
+ license_allocation_price: Optional[ReplacePriceLicenseAllocationPrice]
+ """The license allocation price to add to the plan."""
+
plan_phase_order: Optional[int]
"""The phase to replace this price from."""
diff --git a/src/orb/types/beta_create_plan_version_params.py b/src/orb/types/beta_create_plan_version_params.py
index 813cbba0..a45fe163 100644
--- a/src/orb/types/beta_create_plan_version_params.py
+++ b/src/orb/types/beta_create_plan_version_params.py
@@ -5,8 +5,10 @@
from typing import Dict, Union, Iterable, Optional
from typing_extensions import Literal, Required, TypeAlias, TypedDict
+from .._types import SequenceNotStr
from .shared_params.new_maximum import NewMaximum
from .shared_params.new_minimum import NewMinimum
+from .shared_params.unit_config import UnitConfig
from .shared_params.new_usage_discount import NewUsageDiscount
from .shared_params.new_amount_discount import NewAmountDiscount
from .shared_params.new_plan_bulk_price import NewPlanBulkPrice
@@ -48,6 +50,9 @@
"AddAdjustment",
"AddAdjustmentAdjustment",
"AddPrice",
+ "AddPriceLicenseAllocationPrice",
+ "AddPriceLicenseAllocationPriceLicenseAllocation",
+ "AddPriceLicenseAllocationPriceConversionRateConfig",
"AddPricePrice",
"AddPricePriceNewPlanBulkWithFiltersPrice",
"AddPricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfig",
@@ -64,6 +69,10 @@
"AddPricePriceNewPlanCumulativeGroupedAllocationPrice",
"AddPricePriceNewPlanCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"AddPricePriceNewPlanCumulativeGroupedAllocationPriceConversionRateConfig",
+ "AddPricePriceNewPlanDailyCreditAllowancePrice",
+ "AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "AddPricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig",
"AddPricePriceNewPlanPercentCompositePrice",
"AddPricePriceNewPlanPercentCompositePricePercentConfig",
"AddPricePriceNewPlanPercentCompositePriceConversionRateConfig",
@@ -75,6 +84,9 @@
"ReplaceAdjustment",
"ReplaceAdjustmentAdjustment",
"ReplacePrice",
+ "ReplacePriceLicenseAllocationPrice",
+ "ReplacePriceLicenseAllocationPriceLicenseAllocation",
+ "ReplacePriceLicenseAllocationPriceConversionRateConfig",
"ReplacePricePrice",
"ReplacePricePriceNewPlanBulkWithFiltersPrice",
"ReplacePricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfig",
@@ -91,6 +103,10 @@
"ReplacePricePriceNewPlanCumulativeGroupedAllocationPrice",
"ReplacePricePriceNewPlanCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"ReplacePricePriceNewPlanCumulativeGroupedAllocationPriceConversionRateConfig",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePrice",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "ReplacePricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig",
"ReplacePricePriceNewPlanPercentCompositePrice",
"ReplacePricePriceNewPlanPercentCompositePricePercentConfig",
"ReplacePricePriceNewPlanPercentCompositePriceConversionRateConfig",
@@ -139,6 +155,115 @@ class AddAdjustment(TypedDict, total=False):
"""The phase to add this adjustment to."""
+class AddPriceLicenseAllocationPriceLicenseAllocation(TypedDict, total=False):
+ amount: Required[str]
+ """The amount of credits granted per active license per cadence."""
+
+ currency: Required[str]
+ """The currency of the license allocation."""
+
+ write_off_overage: Optional[bool]
+ """When True, overage beyond the allocation is written off."""
+
+
+AddPriceLicenseAllocationPriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class AddPriceLicenseAllocationPrice(TypedDict, total=False):
+ """The license allocation price to add to the plan."""
+
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ license_allocations: Required[Iterable[AddPriceLicenseAllocationPriceLicenseAllocation]]
+ """License allocations to associate with this price.
+
+ Each entry defines a per-license credit pool granted each cadence. Requires
+ license_type_id or license_type_configuration to be set.
+ """
+
+ model_type: Required[Literal["unit"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ unit_config: Required[UnitConfig]
+ """Configuration for unit pricing"""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[AddPriceLicenseAllocationPriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class AddPricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfigFilter(TypedDict, total=False):
"""Configuration for a single property filter"""
@@ -581,6 +706,137 @@ class AddPricePriceNewPlanCumulativeGroupedAllocationPrice(TypedDict, total=Fals
"""
+class AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(TypedDict, total=False):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+AddPricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class AddPricePriceNewPlanDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[AddPricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[AddPricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class AddPricePriceNewPlanPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -815,6 +1071,7 @@ class AddPricePriceNewPlanEventOutputPrice(TypedDict, total=False):
NewPlanScalableMatrixWithTieredPricingPrice,
NewPlanCumulativeGroupedBulkPrice,
AddPricePriceNewPlanCumulativeGroupedAllocationPrice,
+ AddPricePriceNewPlanDailyCreditAllowancePrice,
NewPlanMinimumCompositePrice,
AddPricePriceNewPlanPercentCompositePrice,
AddPricePriceNewPlanEventOutputPrice,
@@ -825,6 +1082,9 @@ class AddPrice(TypedDict, total=False):
allocation_price: Optional[NewAllocationPrice]
"""The allocation price to add to the plan."""
+ license_allocation_price: Optional[AddPriceLicenseAllocationPrice]
+ """The license allocation price to add to the plan."""
+
plan_phase_order: Optional[int]
"""The phase to add this price to."""
@@ -864,6 +1124,115 @@ class ReplaceAdjustment(TypedDict, total=False):
"""The phase to replace this adjustment from."""
+class ReplacePriceLicenseAllocationPriceLicenseAllocation(TypedDict, total=False):
+ amount: Required[str]
+ """The amount of credits granted per active license per cadence."""
+
+ currency: Required[str]
+ """The currency of the license allocation."""
+
+ write_off_overage: Optional[bool]
+ """When True, overage beyond the allocation is written off."""
+
+
+ReplacePriceLicenseAllocationPriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class ReplacePriceLicenseAllocationPrice(TypedDict, total=False):
+ """The license allocation price to add to the plan."""
+
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ license_allocations: Required[Iterable[ReplacePriceLicenseAllocationPriceLicenseAllocation]]
+ """License allocations to associate with this price.
+
+ Each entry defines a per-license credit pool granted each cadence. Requires
+ license_type_id or license_type_configuration to be set.
+ """
+
+ model_type: Required[Literal["unit"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ unit_config: Required[UnitConfig]
+ """Configuration for unit pricing"""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[ReplacePriceLicenseAllocationPriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class ReplacePricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfigFilter(TypedDict, total=False):
"""Configuration for a single property filter"""
@@ -1306,6 +1675,137 @@ class ReplacePricePriceNewPlanCumulativeGroupedAllocationPrice(TypedDict, total=
"""
+class ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(TypedDict, total=False):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+ReplacePricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class ReplacePricePriceNewPlanDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[ReplacePricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[ReplacePricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class ReplacePricePriceNewPlanPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -1540,6 +2040,7 @@ class ReplacePricePriceNewPlanEventOutputPrice(TypedDict, total=False):
NewPlanScalableMatrixWithTieredPricingPrice,
NewPlanCumulativeGroupedBulkPrice,
ReplacePricePriceNewPlanCumulativeGroupedAllocationPrice,
+ ReplacePricePriceNewPlanDailyCreditAllowancePrice,
NewPlanMinimumCompositePrice,
ReplacePricePriceNewPlanPercentCompositePrice,
ReplacePricePriceNewPlanEventOutputPrice,
@@ -1553,6 +2054,9 @@ class ReplacePrice(TypedDict, total=False):
allocation_price: Optional[NewAllocationPrice]
"""The allocation price to add to the plan."""
+ license_allocation_price: Optional[ReplacePriceLicenseAllocationPrice]
+ """The license allocation price to add to the plan."""
+
plan_phase_order: Optional[int]
"""The phase to replace this price from."""
diff --git a/src/orb/types/billable_metric.py b/src/orb/types/billable_metric.py
index e618c404..b3b6a158 100644
--- a/src/orb/types/billable_metric.py
+++ b/src/orb/types/billable_metric.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, Optional
+from typing import Dict, List, Optional
from typing_extensions import Literal
from .item import Item
@@ -38,3 +38,5 @@ class BillableMetric(BaseModel):
name: str
status: Literal["active", "draft", "archived"]
+
+ parameter_definitions: Optional[List[Dict[str, object]]] = None
diff --git a/src/orb/types/customer.py b/src/orb/types/customer.py
index 4eccf4a8..c89b5f54 100644
--- a/src/orb/types/customer.py
+++ b/src/orb/types/customer.py
@@ -31,7 +31,7 @@ class Hierarchy(BaseModel):
class AccountingSyncConfigurationAccountingProvider(BaseModel):
external_provider_id: Optional[str] = None
- provider_type: Literal["quickbooks", "netsuite"]
+ provider_type: Literal["quickbooks", "netsuite", "netsuite_ampersand"]
class AccountingSyncConfiguration(BaseModel):
@@ -44,6 +44,13 @@ class PaymentConfigurationPaymentProvider(BaseModel):
provider_type: Literal["stripe"]
"""The payment provider to configure."""
+ default_shared_payment_token: Optional[str] = None
+ """
+ The ID of a shared payment token granted by an agent to use as the default
+ payment instrument for this customer. When set, auto-collection will use this
+ token instead of the customer's default payment method.
+ """
+
excluded_payment_method_types: Optional[List[str]] = None
"""List of Stripe payment method types to exclude for this customer.
@@ -139,7 +146,9 @@ class Customer(BaseModel):
name: str
"""The full name of the customer"""
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]] = None
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ] = None
"""This is used for creating charges or invoices in an external system via Orb.
When not in test mode, the connection must first be configured in the Orb
diff --git a/src/orb/types/customer_create_params.py b/src/orb/types/customer_create_params.py
index 7d8e6155..4e3aafe2 100644
--- a/src/orb/types/customer_create_params.py
+++ b/src/orb/types/customer_create_params.py
@@ -95,7 +95,9 @@ class CustomerCreateParams(TypedDict, total=False):
a supported payment provider such as Stripe.
"""
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
"""This is used for creating charges or invoices in an external system via Orb.
When not in test mode, the connection must first be configured in the Orb
@@ -275,6 +277,13 @@ class PaymentConfigurationPaymentProvider(TypedDict, total=False):
provider_type: Required[Literal["stripe"]]
"""The payment provider to configure."""
+ default_shared_payment_token: Optional[str]
+ """
+ The ID of a shared payment token granted by an agent to use as the default
+ payment instrument for this customer. When set, auto-collection will use this
+ token instead of the customer's default payment method.
+ """
+
excluded_payment_method_types: SequenceNotStr[str]
"""List of Stripe payment method types to exclude for this customer.
diff --git a/src/orb/types/customer_update_by_external_id_params.py b/src/orb/types/customer_update_by_external_id_params.py
index 3d7a832e..92327800 100644
--- a/src/orb/types/customer_update_by_external_id_params.py
+++ b/src/orb/types/customer_update_by_external_id_params.py
@@ -57,7 +57,9 @@ class CustomerUpdateByExternalIDParams(TypedDict, total=False):
currency: Optional[str]
"""An ISO 4217 currency string used for the customer's invoices and balance.
- If not set at creation time, will be set at subscription creation time.
+ This can only be set if the customer does not already have a currency
+ configured. If not set at creation or update time, it will be set at
+ subscription creation time.
"""
email: Optional[str]
@@ -93,7 +95,9 @@ class CustomerUpdateByExternalIDParams(TypedDict, total=False):
a supported payment provider such as Stripe.
"""
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
"""This is used for creating charges or invoices in an external system via Orb.
When not in test mode:
@@ -270,6 +274,13 @@ class PaymentConfigurationPaymentProvider(TypedDict, total=False):
provider_type: Required[Literal["stripe"]]
"""The payment provider to configure."""
+ default_shared_payment_token: Optional[str]
+ """
+ The ID of a shared payment token granted by an agent to use as the default
+ payment instrument for this customer. When set, auto-collection will use this
+ token instead of the customer's default payment method.
+ """
+
excluded_payment_method_types: SequenceNotStr[str]
"""List of Stripe payment method types to exclude for this customer.
diff --git a/src/orb/types/customer_update_params.py b/src/orb/types/customer_update_params.py
index 13673f40..050d126d 100644
--- a/src/orb/types/customer_update_params.py
+++ b/src/orb/types/customer_update_params.py
@@ -57,7 +57,9 @@ class CustomerUpdateParams(TypedDict, total=False):
currency: Optional[str]
"""An ISO 4217 currency string used for the customer's invoices and balance.
- If not set at creation time, will be set at subscription creation time.
+ This can only be set if the customer does not already have a currency
+ configured. If not set at creation or update time, it will be set at
+ subscription creation time.
"""
email: Optional[str]
@@ -93,7 +95,9 @@ class CustomerUpdateParams(TypedDict, total=False):
a supported payment provider such as Stripe.
"""
- payment_provider: Optional[Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite"]]
+ payment_provider: Optional[
+ Literal["quickbooks", "bill.com", "stripe_charge", "stripe_invoice", "netsuite", "netsuite_ampersand"]
+ ]
"""This is used for creating charges or invoices in an external system via Orb.
When not in test mode:
@@ -270,6 +274,13 @@ class PaymentConfigurationPaymentProvider(TypedDict, total=False):
provider_type: Required[Literal["stripe"]]
"""The payment provider to configure."""
+ default_shared_payment_token: Optional[str]
+ """
+ The ID of a shared payment token granted by an agent to use as the default
+ payment instrument for this customer. When set, auto-collection will use this
+ token instead of the customer's default payment method.
+ """
+
excluded_payment_method_types: SequenceNotStr[str]
"""List of Stripe payment method types to exclude for this customer.
diff --git a/src/orb/types/customers/credits/decrement_ledger_entry.py b/src/orb/types/customers/credits/decrement_ledger_entry.py
index 9373f061..3f0896c2 100644
--- a/src/orb/types/customers/credits/decrement_ledger_entry.py
+++ b/src/orb/types/customers/credits/decrement_ledger_entry.py
@@ -45,6 +45,10 @@ class DecrementLedgerEntry(BaseModel):
starting_balance: float
event_id: Optional[str] = None
+ """This field is deprecated and will always be null.
+
+ Decrements are not associated with individual events.
+ """
invoice_id: Optional[str] = None
diff --git a/src/orb/types/customers/credits/ledger_create_entry_by_external_id_params.py b/src/orb/types/customers/credits/ledger_create_entry_by_external_id_params.py
index 598e681b..37c7f2b5 100644
--- a/src/orb/types/customers/credits/ledger_create_entry_by_external_id_params.py
+++ b/src/orb/types/customers/credits/ledger_create_entry_by_external_id_params.py
@@ -125,6 +125,9 @@ class AddIncrementCreditLedgerEntryRequestParamsInvoiceSettings(TypedDict, total
If not provided, a default 'Credits' item will be used.
"""
+ mark_as_paid: bool
+ """If true, the new credits purchase invoice will be marked as paid."""
+
memo: Optional[str]
"""An optional memo to display on the invoice."""
@@ -134,8 +137,8 @@ class AddIncrementCreditLedgerEntryRequestParamsInvoiceSettings(TypedDict, total
Due date is calculated based on the invoice or issuance date, depending on the
account's configured due date calculation method. A value of '0' here represents
that the invoice is due on issue, whereas a value of '30' represents that the
- customer has 30 days to pay the invoice. Do not set this field if you want to
- set a custom due date.
+ customer has 30 days to pay the invoice. You must set either `net_terms` or
+ `custom_due_date`, but not both.
"""
require_successful_payment: bool
@@ -181,9 +184,9 @@ class AddExpirationChangeCreditLedgerEntryRequestParams(TypedDict, total=False):
target_expiry_date: Required[Annotated[Union[str, date], PropertyInfo(format="iso8601")]]
"""
- A future date (specified in YYYY-MM-DD format) used for expiration change,
- denoting when credits transferred (as part of a partial block expiration) should
- expire.
+ A date (specified in YYYY-MM-DD format) used for expiration change, denoting
+ when credits transferred (as part of a partial block expiration) should expire.
+ This date must be on or after the effective date of the credit block.
"""
amount: Optional[float]
diff --git a/src/orb/types/customers/credits/ledger_create_entry_params.py b/src/orb/types/customers/credits/ledger_create_entry_params.py
index b0b47f75..f52c8ad2 100644
--- a/src/orb/types/customers/credits/ledger_create_entry_params.py
+++ b/src/orb/types/customers/credits/ledger_create_entry_params.py
@@ -125,6 +125,9 @@ class AddIncrementCreditLedgerEntryRequestParamsInvoiceSettings(TypedDict, total
If not provided, a default 'Credits' item will be used.
"""
+ mark_as_paid: bool
+ """If true, the new credits purchase invoice will be marked as paid."""
+
memo: Optional[str]
"""An optional memo to display on the invoice."""
@@ -134,8 +137,8 @@ class AddIncrementCreditLedgerEntryRequestParamsInvoiceSettings(TypedDict, total
Due date is calculated based on the invoice or issuance date, depending on the
account's configured due date calculation method. A value of '0' here represents
that the invoice is due on issue, whereas a value of '30' represents that the
- customer has 30 days to pay the invoice. Do not set this field if you want to
- set a custom due date.
+ customer has 30 days to pay the invoice. You must set either `net_terms` or
+ `custom_due_date`, but not both.
"""
require_successful_payment: bool
@@ -181,9 +184,9 @@ class AddExpirationChangeCreditLedgerEntryRequestParams(TypedDict, total=False):
target_expiry_date: Required[Annotated[Union[str, date], PropertyInfo(format="iso8601")]]
"""
- A future date (specified in YYYY-MM-DD format) used for expiration change,
- denoting when credits transferred (as part of a partial block expiration) should
- expire.
+ A date (specified in YYYY-MM-DD format) used for expiration change, denoting
+ when credits transferred (as part of a partial block expiration) should expire.
+ This date must be on or after the effective date of the credit block.
"""
amount: Optional[float]
diff --git a/src/orb/types/invoice_create_params.py b/src/orb/types/invoice_create_params.py
index 92ae0229..650d26c0 100644
--- a/src/orb/types/invoice_create_params.py
+++ b/src/orb/types/invoice_create_params.py
@@ -29,6 +29,13 @@ class InvoiceCreateParams(TypedDict, total=False):
line_items: Required[Iterable[LineItem]]
+ auto_collection: Optional[bool]
+ """
+ Determines whether this invoice will automatically attempt to charge a saved
+ payment method, if any. If not specified, the invoice inherits the customer's
+ auto_collection setting.
+ """
+
customer_id: Optional[str]
"""The id of the `Customer` to create this invoice for.
diff --git a/src/orb/types/invoice_pay_params.py b/src/orb/types/invoice_pay_params.py
new file mode 100644
index 00000000..e7a883d8
--- /dev/null
+++ b/src/orb/types/invoice_pay_params.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["InvoicePayParams"]
+
+
+class InvoicePayParams(TypedDict, total=False):
+ shared_payment_token_id: Required[str]
+ """The ID of a shared payment token granted by an agent to use for this payment."""
diff --git a/src/orb/types/invoice_update_params.py b/src/orb/types/invoice_update_params.py
index b097d6f8..30367bce 100644
--- a/src/orb/types/invoice_update_params.py
+++ b/src/orb/types/invoice_update_params.py
@@ -12,6 +12,13 @@
class InvoiceUpdateParams(TypedDict, total=False):
+ auto_collection: Optional[bool]
+ """
+ Determines whether this invoice will automatically attempt to charge a saved
+ payment method, if any. Can only be modified on draft invoices. If not
+ specified, the invoice's existing setting is unchanged.
+ """
+
due_date: Annotated[Union[Union[str, date], Union[str, datetime], None], PropertyInfo(format="iso8601")]
"""An optional custom due date for the invoice.
diff --git a/src/orb/types/item.py b/src/orb/types/item.py
index c25cd993..6f4fcb32 100644
--- a/src/orb/types/item.py
+++ b/src/orb/types/item.py
@@ -15,7 +15,7 @@ class ExternalConnection(BaseModel):
"""
external_connection_name: Literal[
- "stripe", "quickbooks", "bill.com", "netsuite", "taxjar", "avalara", "anrok", "numeral"
+ "stripe", "quickbooks", "bill.com", "netsuite", "taxjar", "avalara", "anrok", "numeral", "stripe_tax"
]
"""The name of the external system this item is connected to."""
diff --git a/src/orb/types/item_update_params.py b/src/orb/types/item_update_params.py
index d9504846..939b406c 100644
--- a/src/orb/types/item_update_params.py
+++ b/src/orb/types/item_update_params.py
@@ -27,7 +27,7 @@ class ExternalConnection(TypedDict, total=False):
"""
external_connection_name: Required[
- Literal["stripe", "quickbooks", "bill.com", "netsuite", "taxjar", "avalara", "anrok", "numeral"]
+ Literal["stripe", "quickbooks", "bill.com", "netsuite", "taxjar", "avalara", "anrok", "numeral", "stripe_tax"]
]
"""The name of the external system this item is connected to."""
diff --git a/src/orb/types/new_subscription_scalable_matrix_with_unit_pricing_price_param.py b/src/orb/types/new_subscription_scalable_matrix_with_unit_pricing_price_param.py
index c0ea7c96..683bf6db 100644
--- a/src/orb/types/new_subscription_scalable_matrix_with_unit_pricing_price_param.py
+++ b/src/orb/types/new_subscription_scalable_matrix_with_unit_pricing_price_param.py
@@ -40,6 +40,9 @@ class ScalableMatrixWithUnitPricingConfig(TypedDict, total=False):
unit_price: Required[str]
"""The final unit price to rate against the output of the matrix"""
+ grouping_key: Optional[str]
+ """The property used to group this price"""
+
prorate: Optional[bool]
"""If true, the unit price will be prorated to the billing period"""
diff --git a/src/orb/types/plan_create_params.py b/src/orb/types/plan_create_params.py
index ff20826c..feea923a 100644
--- a/src/orb/types/plan_create_params.py
+++ b/src/orb/types/plan_create_params.py
@@ -5,8 +5,10 @@
from typing import Dict, Union, Iterable, Optional
from typing_extensions import Literal, Required, TypeAlias, TypedDict
+from .._types import SequenceNotStr
from .shared_params.new_maximum import NewMaximum
from .shared_params.new_minimum import NewMinimum
+from .shared_params.unit_config import UnitConfig
from .shared_params.new_usage_discount import NewUsageDiscount
from .shared_params.new_amount_discount import NewAmountDiscount
from .shared_params.new_plan_bulk_price import NewPlanBulkPrice
@@ -46,6 +48,9 @@
__all__ = [
"PlanCreateParams",
"Price",
+ "PriceLicenseAllocationPrice",
+ "PriceLicenseAllocationPriceLicenseAllocation",
+ "PriceLicenseAllocationPriceConversionRateConfig",
"PricePrice",
"PricePriceNewPlanBulkWithFiltersPrice",
"PricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfig",
@@ -62,6 +67,10 @@
"PricePriceNewPlanCumulativeGroupedAllocationPrice",
"PricePriceNewPlanCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"PricePriceNewPlanCumulativeGroupedAllocationPriceConversionRateConfig",
+ "PricePriceNewPlanDailyCreditAllowancePrice",
+ "PricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "PricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "PricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig",
"PricePriceNewPlanPercentCompositePrice",
"PricePriceNewPlanPercentCompositePricePercentConfig",
"PricePriceNewPlanPercentCompositePriceConversionRateConfig",
@@ -100,6 +109,9 @@ class PlanCreateParams(TypedDict, total=False):
Free-form text which is available on the invoice PDF and the Orb invoice portal.
"""
+ description: Optional[str]
+ """An optional user-defined description of the plan."""
+
external_plan_id: Optional[str]
metadata: Optional[Dict[str, Optional[str]]]
@@ -129,6 +141,113 @@ class PlanCreateParams(TypedDict, total=False):
"""
+class PriceLicenseAllocationPriceLicenseAllocation(TypedDict, total=False):
+ amount: Required[str]
+ """The amount of credits granted per active license per cadence."""
+
+ currency: Required[str]
+ """The currency of the license allocation."""
+
+ write_off_overage: Optional[bool]
+ """When True, overage beyond the allocation is written off."""
+
+
+PriceLicenseAllocationPriceConversionRateConfig: TypeAlias = Union[UnitConversionRateConfig, TieredConversionRateConfig]
+
+
+class PriceLicenseAllocationPrice(TypedDict, total=False):
+ """The license allocation price to add to the plan."""
+
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ license_allocations: Required[Iterable[PriceLicenseAllocationPriceLicenseAllocation]]
+ """License allocations to associate with this price.
+
+ Each entry defines a per-license credit pool granted each cadence. Requires
+ license_type_id or license_type_configuration to be set.
+ """
+
+ model_type: Required[Literal["unit"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ unit_config: Required[UnitConfig]
+ """Configuration for unit pricing"""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[PriceLicenseAllocationPriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class PricePriceNewPlanBulkWithFiltersPriceBulkWithFiltersConfigFilter(TypedDict, total=False):
"""Configuration for a single property filter"""
@@ -571,6 +690,135 @@ class PricePriceNewPlanCumulativeGroupedAllocationPrice(TypedDict, total=False):
"""
+class PricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(TypedDict, total=False):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class PricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[Iterable[PricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]]
+ """Per-dimension credit rates"""
+
+
+PricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class PricePriceNewPlanDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[PricePriceNewPlanDailyCreditAllowancePriceDailyCreditAllowanceConfig]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[PricePriceNewPlanDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class PricePriceNewPlanPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -805,6 +1053,7 @@ class PricePriceNewPlanEventOutputPrice(TypedDict, total=False):
NewPlanScalableMatrixWithTieredPricingPrice,
NewPlanCumulativeGroupedBulkPrice,
PricePriceNewPlanCumulativeGroupedAllocationPrice,
+ PricePriceNewPlanDailyCreditAllowancePrice,
NewPlanMinimumCompositePrice,
PricePriceNewPlanPercentCompositePrice,
PricePriceNewPlanEventOutputPrice,
@@ -815,6 +1064,9 @@ class Price(TypedDict, total=False):
allocation_price: Optional[NewAllocationPrice]
"""The allocation price to add to the plan."""
+ license_allocation_price: Optional[PriceLicenseAllocationPrice]
+ """The license allocation price to add to the plan."""
+
plan_phase_order: Optional[int]
"""The phase to add this price to."""
diff --git a/src/orb/types/plan_update_params.py b/src/orb/types/plan_update_params.py
index 5fc717f0..c535603d 100644
--- a/src/orb/types/plan_update_params.py
+++ b/src/orb/types/plan_update_params.py
@@ -9,6 +9,9 @@
class PlanUpdateParams(TypedDict, total=False):
+ description: Optional[str]
+ """An optional user-defined description of the plan."""
+
external_plan_id: Optional[str]
"""
An optional user-defined ID for this plan resource, used throughout the system
diff --git a/src/orb/types/plans/external_plan_id_update_params.py b/src/orb/types/plans/external_plan_id_update_params.py
index d7017899..7f58c79b 100644
--- a/src/orb/types/plans/external_plan_id_update_params.py
+++ b/src/orb/types/plans/external_plan_id_update_params.py
@@ -9,6 +9,9 @@
class ExternalPlanIDUpdateParams(TypedDict, total=False):
+ description: Optional[str]
+ """An optional user-defined description of the plan."""
+
external_plan_id: Optional[str]
"""
An optional user-defined ID for this plan resource, used throughout the system
diff --git a/src/orb/types/price_create_params.py b/src/orb/types/price_create_params.py
index e114775b..35962507 100644
--- a/src/orb/types/price_create_params.py
+++ b/src/orb/types/price_create_params.py
@@ -5,6 +5,7 @@
from typing import Dict, Union, Iterable, Optional
from typing_extensions import Literal, Required, TypeAlias, TypedDict
+from .._types import SequenceNotStr
from .shared_params.bulk_config import BulkConfig
from .shared_params.unit_config import UnitConfig
from .shared_params.matrix_config import MatrixConfig
@@ -114,6 +115,10 @@
"NewFloatingCumulativeGroupedAllocationPrice",
"NewFloatingCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"NewFloatingCumulativeGroupedAllocationPriceConversionRateConfig",
+ "NewFloatingDailyCreditAllowancePrice",
+ "NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "NewFloatingDailyCreditAllowancePriceConversionRateConfig",
"NewFloatingMinimumCompositePrice",
"NewFloatingMinimumCompositePriceMinimumCompositeConfig",
"NewFloatingMinimumCompositePriceConversionRateConfig",
@@ -2516,6 +2521,9 @@ class NewFloatingScalableMatrixWithUnitPricingPriceScalableMatrixWithUnitPricing
unit_price: Required[str]
"""The final unit price to rate against the output of the matrix"""
+ grouping_key: Optional[str]
+ """The property used to group this price"""
+
prorate: Optional[bool]
"""If true, the unit price will be prorated to the billing period"""
@@ -2849,6 +2857,126 @@ class NewFloatingCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConf
]
+class NewFloatingDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ currency: Required[str]
+ """An ISO 4217 currency string for which this price is billed in."""
+
+ daily_credit_allowance_config: Required[NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[NewFloatingDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+
+class NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(TypedDict, total=False):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[Iterable[NewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]]
+ """Per-dimension credit rates"""
+
+
+NewFloatingDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
class NewFloatingMinimumCompositePrice(TypedDict, total=False):
cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
"""The cadence to bill for this price on."""
@@ -3152,6 +3280,7 @@ class NewFloatingEventOutputPriceEventOutputConfig(TypedDict, total=False):
NewFloatingScalableMatrixWithTieredPricingPrice,
NewFloatingCumulativeGroupedBulkPrice,
NewFloatingCumulativeGroupedAllocationPrice,
+ NewFloatingDailyCreditAllowancePrice,
NewFloatingMinimumCompositePrice,
NewFloatingPercentCompositePrice,
NewFloatingEventOutputPrice,
diff --git a/src/orb/types/price_evaluate_multiple_params.py b/src/orb/types/price_evaluate_multiple_params.py
index 90cd75d4..8abdd727 100644
--- a/src/orb/types/price_evaluate_multiple_params.py
+++ b/src/orb/types/price_evaluate_multiple_params.py
@@ -58,6 +58,10 @@
"PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPrice",
"PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPriceConversionRateConfig",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePrice",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig",
"PriceEvaluationPriceNewFloatingPercentCompositePrice",
"PriceEvaluationPriceNewFloatingPercentCompositePricePercentConfig",
"PriceEvaluationPriceNewFloatingPercentCompositePriceConversionRateConfig",
@@ -398,6 +402,132 @@ class PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPrice(TypedDict,
"""
+class PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(
+ TypedDict, total=False
+):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class PriceEvaluationPriceNewFloatingDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ currency: Required[str]
+ """An ISO 4217 currency string for which this price is billed in."""
+
+ daily_credit_allowance_config: Required[
+ PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ ]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+
class PriceEvaluationPriceNewFloatingPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -614,6 +744,7 @@ class PriceEvaluationPriceNewFloatingEventOutputPrice(TypedDict, total=False):
NewFloatingScalableMatrixWithTieredPricingPrice,
NewFloatingCumulativeGroupedBulkPrice,
PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPrice,
+ PriceEvaluationPriceNewFloatingDailyCreditAllowancePrice,
NewFloatingMinimumCompositePrice,
PriceEvaluationPriceNewFloatingPercentCompositePrice,
PriceEvaluationPriceNewFloatingEventOutputPrice,
@@ -638,6 +769,13 @@ class PriceEvaluation(TypedDict, total=False):
to group the underlying billable metric
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Optional overrides for parameterized billable metric parameters.
+
+ If the metric has parameter definitions and no overrides are provided, defaults
+ will be used.
+ """
+
price: Optional[PriceEvaluationPrice]
"""New floating price request body params."""
diff --git a/src/orb/types/price_evaluate_params.py b/src/orb/types/price_evaluate_params.py
index fa8d6b66..4e508f11 100644
--- a/src/orb/types/price_evaluate_params.py
+++ b/src/orb/types/price_evaluate_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Union, Optional
+from typing import Dict, Union, Optional
from datetime import datetime
from typing_extensions import Required, Annotated, TypedDict
@@ -38,3 +38,10 @@ class PriceEvaluateParams(TypedDict, total=False):
[computed properties](/extensibility/advanced-metrics#computed-properties)) used
to group the underlying billable metric
"""
+
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Optional overrides for parameterized billable metric parameters.
+
+ If the metric has parameter definitions and no overrides are provided, defaults
+ will be used.
+ """
diff --git a/src/orb/types/price_evaluate_preview_events_params.py b/src/orb/types/price_evaluate_preview_events_params.py
index ec487155..b1e52a0f 100644
--- a/src/orb/types/price_evaluate_preview_events_params.py
+++ b/src/orb/types/price_evaluate_preview_events_params.py
@@ -59,6 +59,10 @@
"PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPrice",
"PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPriceConversionRateConfig",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePrice",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig",
"PriceEvaluationPriceNewFloatingPercentCompositePrice",
"PriceEvaluationPriceNewFloatingPercentCompositePricePercentConfig",
"PriceEvaluationPriceNewFloatingPercentCompositePriceConversionRateConfig",
@@ -430,6 +434,132 @@ class PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPrice(TypedDict,
"""
+class PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(
+ TypedDict, total=False
+):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class PriceEvaluationPriceNewFloatingDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ currency: Required[str]
+ """An ISO 4217 currency string for which this price is billed in."""
+
+ daily_credit_allowance_config: Required[
+ PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ ]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[PriceEvaluationPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+
class PriceEvaluationPriceNewFloatingPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -646,6 +776,7 @@ class PriceEvaluationPriceNewFloatingEventOutputPrice(TypedDict, total=False):
NewFloatingScalableMatrixWithTieredPricingPrice,
NewFloatingCumulativeGroupedBulkPrice,
PriceEvaluationPriceNewFloatingCumulativeGroupedAllocationPrice,
+ PriceEvaluationPriceNewFloatingDailyCreditAllowancePrice,
NewFloatingMinimumCompositePrice,
PriceEvaluationPriceNewFloatingPercentCompositePrice,
PriceEvaluationPriceNewFloatingEventOutputPrice,
@@ -670,6 +801,13 @@ class PriceEvaluation(TypedDict, total=False):
to group the underlying billable metric
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Optional overrides for parameterized billable metric parameters.
+
+ If the metric has parameter definitions and no overrides are provided, defaults
+ will be used.
+ """
+
price: Optional[PriceEvaluationPrice]
"""New floating price request body params."""
diff --git a/src/orb/types/shared/new_allocation_price.py b/src/orb/types/shared/new_allocation_price.py
index afaf82c6..7f6c1355 100644
--- a/src/orb/types/shared/new_allocation_price.py
+++ b/src/orb/types/shared/new_allocation_price.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import Dict, List, Optional
from typing_extensions import Literal
from ..._models import BaseModel
@@ -57,6 +57,13 @@ class NewAllocationPrice(BaseModel):
license_type_id: Optional[str] = None
"""The license type ID to associate the price with license allocation."""
+ metadata: Optional[Dict[str, Optional[str]]] = None
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
per_unit_cost_basis: Optional[str] = None
"""The (per-unit) cost basis of each created block.
diff --git a/src/orb/types/shared/new_floating_scalable_matrix_with_unit_pricing_price.py b/src/orb/types/shared/new_floating_scalable_matrix_with_unit_pricing_price.py
index afeb9a28..e1cc30a2 100644
--- a/src/orb/types/shared/new_floating_scalable_matrix_with_unit_pricing_price.py
+++ b/src/orb/types/shared/new_floating_scalable_matrix_with_unit_pricing_price.py
@@ -42,6 +42,9 @@ class ScalableMatrixWithUnitPricingConfig(BaseModel):
unit_price: str
"""The final unit price to rate against the output of the matrix"""
+ grouping_key: Optional[str] = None
+ """The property used to group this price"""
+
prorate: Optional[bool] = None
"""If true, the unit price will be prorated to the billing period"""
diff --git a/src/orb/types/shared/new_plan_scalable_matrix_with_unit_pricing_price.py b/src/orb/types/shared/new_plan_scalable_matrix_with_unit_pricing_price.py
index 9927a55e..5ed45a08 100644
--- a/src/orb/types/shared/new_plan_scalable_matrix_with_unit_pricing_price.py
+++ b/src/orb/types/shared/new_plan_scalable_matrix_with_unit_pricing_price.py
@@ -42,6 +42,9 @@ class ScalableMatrixWithUnitPricingConfig(BaseModel):
unit_price: str
"""The final unit price to rate against the output of the matrix"""
+ grouping_key: Optional[str] = None
+ """The property used to group this price"""
+
prorate: Optional[bool] = None
"""If true, the unit price will be prorated to the billing period"""
diff --git a/src/orb/types/shared/price.py b/src/orb/types/shared/price.py
index 68a9a5a8..07a0e001 100644
--- a/src/orb/types/shared/price.py
+++ b/src/orb/types/shared/price.py
@@ -179,6 +179,12 @@
"CumulativeGroupedAllocationPriceConversionRateConfig",
"CumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"CumulativeGroupedAllocationPriceLicenseType",
+ "DailyCreditAllowancePrice",
+ "DailyCreditAllowancePriceCompositePriceFilter",
+ "DailyCreditAllowancePriceConversionRateConfig",
+ "DailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "DailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "DailyCreditAllowancePriceLicenseType",
"MinimumCompositePrice",
"MinimumCompositePriceCompositePriceFilter",
"MinimumCompositePriceConversionRateConfig",
@@ -261,6 +267,8 @@ class UnitPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -377,6 +385,8 @@ class TieredPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -496,6 +506,8 @@ class BulkPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -642,6 +654,8 @@ class BulkWithFiltersPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -755,6 +769,8 @@ class PackagePrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -871,6 +887,8 @@ class MatrixPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1009,6 +1027,8 @@ class ThresholdTotalAmountPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1148,6 +1168,8 @@ class TieredPackagePrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1291,6 +1313,8 @@ class TieredWithMinimumPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1432,6 +1456,8 @@ class GroupedTieredPrice(BaseModel):
grouped_tiered_config: GroupedTieredPriceGroupedTieredConfig
"""Configuration for grouped_tiered pricing"""
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1567,6 +1593,8 @@ class TieredPackageWithMinimumPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1693,6 +1721,8 @@ class PackageWithAllocationPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1819,6 +1849,8 @@ class UnitWithPercentPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -1935,6 +1967,8 @@ class MatrixWithAllocationPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -2071,6 +2105,8 @@ class TieredWithProrationPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -2194,6 +2230,8 @@ class UnitWithProrationPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -2326,6 +2364,8 @@ class GroupedAllocationPrice(BaseModel):
grouped_allocation_config: GroupedAllocationPriceGroupedAllocationConfig
"""Configuration for grouped_allocation pricing"""
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -2459,6 +2499,8 @@ class BulkWithProrationPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -2588,6 +2630,8 @@ class GroupedWithProratedMinimumPrice(BaseModel):
grouped_with_prorated_minimum_config: GroupedWithProratedMinimumPriceGroupedWithProratedMinimumConfig
"""Configuration for grouped_with_prorated_minimum pricing"""
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -2749,6 +2793,8 @@ class GroupedWithMeteredMinimumPrice(BaseModel):
grouped_with_metered_minimum_config: GroupedWithMeteredMinimumPriceGroupedWithMeteredMinimumConfig
"""Configuration for grouped_with_metered_minimum pricing"""
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -2881,6 +2927,8 @@ class GroupedWithMinMaxThresholdsPrice(BaseModel):
grouped_with_min_max_thresholds_config: GroupedWithMinMaxThresholdsPriceGroupedWithMinMaxThresholdsConfig
"""Configuration for grouped_with_min_max_thresholds pricing"""
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3017,6 +3065,8 @@ class MatrixWithDisplayNamePrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3160,6 +3210,8 @@ class GroupedTieredPackagePrice(BaseModel):
grouped_tiered_package_config: GroupedTieredPackagePriceGroupedTieredPackageConfig
"""Configuration for grouped_tiered_package pricing"""
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3296,6 +3348,8 @@ class MaxGroupTieredPackagePrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3388,6 +3442,9 @@ class ScalableMatrixWithUnitPricingPriceScalableMatrixWithUnitPricingConfig(Base
unit_price: str
"""The final unit price to rate against the output of the matrix"""
+ grouping_key: Optional[str] = None
+ """The property used to group this price"""
+
prorate: Optional[bool] = None
"""If true, the unit price will be prorated to the billing period"""
@@ -3443,6 +3500,8 @@ class ScalableMatrixWithUnitPricingPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3594,6 +3653,8 @@ class ScalableMatrixWithTieredPricingPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3737,6 +3798,8 @@ class CumulativeGroupedBulkPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3869,6 +3932,8 @@ class CumulativeGroupedAllocationPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -3918,6 +3983,164 @@ class CumulativeGroupedAllocationPrice(BaseModel):
"""
+class DailyCreditAllowancePriceCompositePriceFilter(BaseModel):
+ field: Literal["price_id", "item_id", "price_type", "currency", "pricing_unit_id"]
+ """The property of the price to filter on."""
+
+ operator: Literal["includes", "excludes"]
+ """Should prices that match the filter be included or excluded."""
+
+ values: List[str]
+ """The IDs or values that match this filter."""
+
+
+DailyCreditAllowancePriceConversionRateConfig: TypeAlias = Annotated[
+ Union[UnitConversionRateConfig, TieredConversionRateConfig], PropertyInfo(discriminator="conversion_rate_type")
+]
+
+
+class DailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(BaseModel):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: List[Optional[str]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: str
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class DailyCreditAllowancePriceDailyCreditAllowanceConfig(BaseModel):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: str
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: str
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: List[Optional[str]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: str
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: List[DailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ """Per-dimension credit rates"""
+
+
+class DailyCreditAllowancePriceLicenseType(BaseModel):
+ """
+ The LicenseType resource represents a type of license that can be assigned to users.
+ License types are used during billing by grouping metrics on the configured grouping key.
+ """
+
+ id: str
+ """The Orb-assigned unique identifier for the license type."""
+
+ grouping_key: str
+ """The key used for grouping licenses of this type.
+
+ This is typically a user identifier field.
+ """
+
+ name: str
+ """The name of the license type."""
+
+
+class DailyCreditAllowancePrice(BaseModel):
+ id: str
+
+ billable_metric: Optional[BillableMetricTiny] = None
+
+ billing_cycle_configuration: BillingCycleConfiguration
+
+ billing_mode: Literal["in_advance", "in_arrear"]
+
+ cadence: Literal["one_time", "monthly", "quarterly", "semi_annual", "annual", "custom"]
+
+ composite_price_filters: Optional[List[DailyCreditAllowancePriceCompositePriceFilter]] = None
+
+ conversion_rate: Optional[float] = None
+
+ conversion_rate_config: Optional[DailyCreditAllowancePriceConversionRateConfig] = None
+
+ created_at: datetime
+
+ credit_allocation: Optional[Allocation] = None
+
+ currency: str
+
+ daily_credit_allowance_config: DailyCreditAllowancePriceDailyCreditAllowanceConfig
+ """Configuration for daily_credit_allowance pricing"""
+
+ discount: Optional[Discount] = None
+
+ external_price_id: Optional[str] = None
+
+ fixed_price_quantity: Optional[float] = None
+
+ invoice_grouping_key: Optional[str] = None
+
+ invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
+
+ item: ItemSlim
+ """
+ A minimal representation of an Item containing only the essential identifying
+ information.
+ """
+
+ maximum: Optional[Maximum] = None
+
+ maximum_amount: Optional[str] = None
+
+ metadata: Dict[str, str]
+ """User specified key-value pairs for the resource.
+
+ If not present, this defaults to an empty dictionary. Individual keys can be
+ removed by setting the value to `null`, and the entire metadata mapping can be
+ cleared by setting `metadata` to `null`.
+ """
+
+ minimum: Optional[Minimum] = None
+
+ minimum_amount: Optional[str] = None
+
+ price_model_type: Literal["daily_credit_allowance"] = FieldInfo(alias="model_type")
+ """The pricing model type"""
+
+ name: str
+
+ plan_phase_order: Optional[int] = None
+
+ price_type: Literal["usage_price", "fixed_price", "composite_price"]
+
+ replaces_price_id: Optional[str] = None
+ """The price id this price replaces.
+
+ This price will take the place of the replaced price in plan version migrations.
+ """
+
+ dimensional_price_configuration: Optional[DimensionalPriceConfiguration] = None
+
+ license_type: Optional[DailyCreditAllowancePriceLicenseType] = None
+ """
+ The LicenseType resource represents a type of license that can be assigned to
+ users. License types are used during billing by grouping metrics on the
+ configured grouping key.
+ """
+
+
class MinimumCompositePriceCompositePriceFilter(BaseModel):
field: Literal["price_id", "item_id", "price_type", "currency", "pricing_unit_id"]
"""The property of the price to filter on."""
@@ -3992,6 +4215,8 @@ class MinimumCompositePrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -4115,6 +4340,8 @@ class PercentCompositePrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -4254,6 +4481,8 @@ class EventOutputPrice(BaseModel):
fixed_price_quantity: Optional[float] = None
+ invoice_grouping_key: Optional[str] = None
+
invoicing_cycle_configuration: Optional[BillingCycleConfiguration] = None
item: ItemSlim
@@ -4333,6 +4562,7 @@ class EventOutputPrice(BaseModel):
ScalableMatrixWithTieredPricingPrice,
CumulativeGroupedBulkPrice,
CumulativeGroupedAllocationPrice,
+ DailyCreditAllowancePrice,
MinimumCompositePrice,
PercentCompositePrice,
EventOutputPrice,
diff --git a/src/orb/types/shared/price_interval.py b/src/orb/types/shared/price_interval.py
index 6240931b..03fa50be 100644
--- a/src/orb/types/shared/price_interval.py
+++ b/src/orb/types/shared/price_interval.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import Dict, List, Optional
from datetime import datetime
from .price import Price
@@ -83,3 +83,9 @@ class PriceInterval(BaseModel):
A list of customer IDs whose usage events will be aggregated and billed under
this price interval.
"""
+
+ metric_parameter_overrides: Optional[Dict[str, object]] = None
+ """Override values for parameterized billable metric variables.
+
+ Keys are parameter names, values are the override values.
+ """
diff --git a/src/orb/types/shared_params/new_allocation_price.py b/src/orb/types/shared_params/new_allocation_price.py
index 22331d9e..54500bea 100644
--- a/src/orb/types/shared_params/new_allocation_price.py
+++ b/src/orb/types/shared_params/new_allocation_price.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Iterable, Optional
+from typing import Dict, Iterable, Optional
from typing_extensions import Literal, Required, TypedDict
from ..._types import SequenceNotStr
@@ -59,6 +59,13 @@ class NewAllocationPrice(TypedDict, total=False):
license_type_id: Optional[str]
"""The license type ID to associate the price with license allocation."""
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
per_unit_cost_basis: str
"""The (per-unit) cost basis of each created block.
diff --git a/src/orb/types/shared_params/new_floating_scalable_matrix_with_unit_pricing_price.py b/src/orb/types/shared_params/new_floating_scalable_matrix_with_unit_pricing_price.py
index 374f11e1..009b8569 100644
--- a/src/orb/types/shared_params/new_floating_scalable_matrix_with_unit_pricing_price.py
+++ b/src/orb/types/shared_params/new_floating_scalable_matrix_with_unit_pricing_price.py
@@ -40,6 +40,9 @@ class ScalableMatrixWithUnitPricingConfig(TypedDict, total=False):
unit_price: Required[str]
"""The final unit price to rate against the output of the matrix"""
+ grouping_key: Optional[str]
+ """The property used to group this price"""
+
prorate: Optional[bool]
"""If true, the unit price will be prorated to the billing period"""
diff --git a/src/orb/types/shared_params/new_plan_scalable_matrix_with_unit_pricing_price.py b/src/orb/types/shared_params/new_plan_scalable_matrix_with_unit_pricing_price.py
index f9bee34c..d2085ec1 100644
--- a/src/orb/types/shared_params/new_plan_scalable_matrix_with_unit_pricing_price.py
+++ b/src/orb/types/shared_params/new_plan_scalable_matrix_with_unit_pricing_price.py
@@ -40,6 +40,9 @@ class ScalableMatrixWithUnitPricingConfig(TypedDict, total=False):
unit_price: Required[str]
"""The final unit price to rate against the output of the matrix"""
+ grouping_key: Optional[str]
+ """The property used to group this price"""
+
prorate: Optional[bool]
"""If true, the unit price will be prorated to the billing period"""
diff --git a/src/orb/types/subscription_create_params.py b/src/orb/types/subscription_create_params.py
index 0f454571..228ed977 100644
--- a/src/orb/types/subscription_create_params.py
+++ b/src/orb/types/subscription_create_params.py
@@ -75,6 +75,10 @@
"AddPricePriceNewSubscriptionCumulativeGroupedAllocationPrice",
"AddPricePriceNewSubscriptionCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"AddPricePriceNewSubscriptionCumulativeGroupedAllocationPriceConversionRateConfig",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePrice",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig",
"AddPricePriceNewSubscriptionPercentCompositePrice",
"AddPricePriceNewSubscriptionPercentCompositePricePercentConfig",
"AddPricePriceNewSubscriptionPercentCompositePriceConversionRateConfig",
@@ -102,6 +106,10 @@
"ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPrice",
"ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPriceConversionRateConfig",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePrice",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig",
"ReplacePricePriceNewSubscriptionPercentCompositePrice",
"ReplacePricePriceNewSubscriptionPercentCompositePricePercentConfig",
"ReplacePricePriceNewSubscriptionPercentCompositePriceConversionRateConfig",
@@ -756,6 +764,141 @@ class AddPricePriceNewSubscriptionCumulativeGroupedAllocationPrice(TypedDict, to
"""
+class AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(
+ TypedDict, total=False
+):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+AddPricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class AddPricePriceNewSubscriptionDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[
+ AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ ]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[AddPricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class AddPricePriceNewSubscriptionPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -990,6 +1133,7 @@ class AddPricePriceNewSubscriptionEventOutputPrice(TypedDict, total=False):
NewSubscriptionScalableMatrixWithTieredPricingPriceParam,
NewSubscriptionCumulativeGroupedBulkPriceParam,
AddPricePriceNewSubscriptionCumulativeGroupedAllocationPrice,
+ AddPricePriceNewSubscriptionDailyCreditAllowancePrice,
NewSubscriptionMinimumCompositePriceParam,
AddPricePriceNewSubscriptionPercentCompositePrice,
AddPricePriceNewSubscriptionEventOutputPrice,
@@ -1022,6 +1166,12 @@ class AddPrice(TypedDict, total=False):
The subscription's maximum amount for this price.
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Override values for parameterized billable metric variables.
+
+ Keys are parameter names, values are the override values.
+ """
+
minimum_amount: Optional[str]
"""[DEPRECATED] Use add_adjustments instead.
@@ -1523,6 +1673,141 @@ class ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPrice(TypedDict
"""
+class ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(
+ TypedDict, total=False
+):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class ReplacePricePriceNewSubscriptionDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[
+ ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ ]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class ReplacePricePriceNewSubscriptionPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -1757,6 +2042,7 @@ class ReplacePricePriceNewSubscriptionEventOutputPrice(TypedDict, total=False):
NewSubscriptionScalableMatrixWithTieredPricingPriceParam,
NewSubscriptionCumulativeGroupedBulkPriceParam,
ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPrice,
+ ReplacePricePriceNewSubscriptionDailyCreditAllowancePrice,
NewSubscriptionMinimumCompositePriceParam,
ReplacePricePriceNewSubscriptionPercentCompositePrice,
ReplacePricePriceNewSubscriptionEventOutputPrice,
@@ -1788,6 +2074,12 @@ class ReplacePrice(TypedDict, total=False):
The subscription's maximum amount for the replacement price.
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Override values for parameterized billable metric variables.
+
+ Keys are parameter names, values are the override values.
+ """
+
minimum_amount: Optional[str]
"""[DEPRECATED] Use add_adjustments instead.
diff --git a/src/orb/types/subscription_price_intervals_params.py b/src/orb/types/subscription_price_intervals_params.py
index eba9360a..35405a4e 100644
--- a/src/orb/types/subscription_price_intervals_params.py
+++ b/src/orb/types/subscription_price_intervals_params.py
@@ -70,6 +70,10 @@
"AddPriceNewFloatingCumulativeGroupedAllocationPrice",
"AddPriceNewFloatingCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"AddPriceNewFloatingCumulativeGroupedAllocationPriceConversionRateConfig",
+ "AddPriceNewFloatingDailyCreditAllowancePrice",
+ "AddPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "AddPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "AddPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig",
"AddPriceNewFloatingPercentCompositePrice",
"AddPriceNewFloatingPercentCompositePricePercentConfig",
"AddPriceNewFloatingPercentCompositePriceConversionRateConfig",
@@ -459,6 +463,126 @@ class AddPriceNewFloatingCumulativeGroupedAllocationPrice(TypedDict, total=False
"""
+class AddPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(TypedDict, total=False):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class AddPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[Iterable[AddPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]]
+ """Per-dimension credit rates"""
+
+
+AddPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class AddPriceNewFloatingDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ currency: Required[str]
+ """An ISO 4217 currency string for which this price is billed in."""
+
+ daily_credit_allowance_config: Required[AddPriceNewFloatingDailyCreditAllowancePriceDailyCreditAllowanceConfig]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[AddPriceNewFloatingDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+
class AddPriceNewFloatingPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -675,6 +799,7 @@ class AddPriceNewFloatingEventOutputPrice(TypedDict, total=False):
NewFloatingScalableMatrixWithTieredPricingPrice,
NewFloatingCumulativeGroupedBulkPrice,
AddPriceNewFloatingCumulativeGroupedAllocationPrice,
+ AddPriceNewFloatingDailyCreditAllowancePrice,
NewFloatingMinimumCompositePrice,
AddPriceNewFloatingPercentCompositePrice,
AddPriceNewFloatingEventOutputPrice,
@@ -729,6 +854,12 @@ class Add(TypedDict, total=False):
billing period.
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Override values for parameterized billable metric variables.
+
+ Keys are parameter names, values are the override values (number or string).
+ """
+
minimum_amount: Optional[float]
"""
The minimum amount that will be billed for this price interval for a given
@@ -836,6 +967,12 @@ class Edit(TypedDict, total=False):
on the price interval.
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Override values for parameterized billable metric variables.
+
+ Keys are parameter names, values are the override values (number or string).
+ """
+
start_date: Annotated[Union[Union[str, datetime], BillingCycleRelativeDate], PropertyInfo(format="iso8601")]
"""The updated start date of this price interval.
diff --git a/src/orb/types/subscription_schedule_plan_change_params.py b/src/orb/types/subscription_schedule_plan_change_params.py
index e2208e29..b9001c82 100644
--- a/src/orb/types/subscription_schedule_plan_change_params.py
+++ b/src/orb/types/subscription_schedule_plan_change_params.py
@@ -75,6 +75,10 @@
"AddPricePriceNewSubscriptionCumulativeGroupedAllocationPrice",
"AddPricePriceNewSubscriptionCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"AddPricePriceNewSubscriptionCumulativeGroupedAllocationPriceConversionRateConfig",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePrice",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "AddPricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig",
"AddPricePriceNewSubscriptionPercentCompositePrice",
"AddPricePriceNewSubscriptionPercentCompositePricePercentConfig",
"AddPricePriceNewSubscriptionPercentCompositePriceConversionRateConfig",
@@ -102,6 +106,10 @@
"ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPrice",
"ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPriceCumulativeGroupedAllocationConfig",
"ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPriceConversionRateConfig",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePrice",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue",
+ "ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig",
"ReplacePricePriceNewSubscriptionPercentCompositePrice",
"ReplacePricePriceNewSubscriptionPercentCompositePricePercentConfig",
"ReplacePricePriceNewSubscriptionPercentCompositePriceConversionRateConfig",
@@ -744,6 +752,141 @@ class AddPricePriceNewSubscriptionCumulativeGroupedAllocationPrice(TypedDict, to
"""
+class AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(
+ TypedDict, total=False
+):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+AddPricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class AddPricePriceNewSubscriptionDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[
+ AddPricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ ]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[AddPricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class AddPricePriceNewSubscriptionPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -978,6 +1121,7 @@ class AddPricePriceNewSubscriptionEventOutputPrice(TypedDict, total=False):
NewSubscriptionScalableMatrixWithTieredPricingPriceParam,
NewSubscriptionCumulativeGroupedBulkPriceParam,
AddPricePriceNewSubscriptionCumulativeGroupedAllocationPrice,
+ AddPricePriceNewSubscriptionDailyCreditAllowancePrice,
NewSubscriptionMinimumCompositePriceParam,
AddPricePriceNewSubscriptionPercentCompositePrice,
AddPricePriceNewSubscriptionEventOutputPrice,
@@ -1010,6 +1154,12 @@ class AddPrice(TypedDict, total=False):
The subscription's maximum amount for this price.
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Override values for parameterized billable metric variables.
+
+ Keys are parameter names, values are the override values.
+ """
+
minimum_amount: Optional[str]
"""[DEPRECATED] Use add_adjustments instead.
@@ -1511,6 +1661,141 @@ class ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPrice(TypedDict
"""
+class ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue(
+ TypedDict, total=False
+):
+ """Per-dimension credit price for the daily credit allowance model."""
+
+ dimension_values: Required[SequenceNotStr[Optional[str]]]
+ """One or two matrix keys to filter usage to this value by.
+
+ For example, ["model"] could be used to apply a different credit rate to each AI
+ model.
+ """
+
+ unit_amount: Required[str]
+ """Credits charged per unit of usage matching the specified dimension_values"""
+
+
+class ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig(TypedDict, total=False):
+ """Configuration for daily_credit_allowance pricing"""
+
+ daily_allowance: Required[str]
+ """Credits granted per day. Lose-it-or-use-it; does not roll over."""
+
+ default_unit_amount: Required[str]
+ """
+ Default per-unit credit rate for any usage not bucketed into a specified
+ matrix_value
+ """
+
+ dimensions: Required[SequenceNotStr[Optional[str]]]
+ """One or two event property values to evaluate matrix groups by"""
+
+ event_day_property: Required[str]
+ """Event property whose value identifies the day bucket the event belongs to (e.g.
+
+ 'event_day' set to an ISO date string in the customer's timezone). The allowance
+ resets per distinct value of this property.
+ """
+
+ matrix_values: Required[
+ Iterable[ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfigMatrixValue]
+ ]
+ """Per-dimension credit rates"""
+
+
+ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig: TypeAlias = Union[
+ UnitConversionRateConfig, TieredConversionRateConfig
+]
+
+
+class ReplacePricePriceNewSubscriptionDailyCreditAllowancePrice(TypedDict, total=False):
+ cadence: Required[Literal["annual", "semi_annual", "monthly", "quarterly", "one_time", "custom"]]
+ """The cadence to bill for this price on."""
+
+ daily_credit_allowance_config: Required[
+ ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceDailyCreditAllowanceConfig
+ ]
+ """Configuration for daily_credit_allowance pricing"""
+
+ item_id: Required[str]
+ """The id of the item the price will be associated with."""
+
+ model_type: Required[Literal["daily_credit_allowance"]]
+ """The pricing model type"""
+
+ name: Required[str]
+ """The name of the price."""
+
+ billable_metric_id: Optional[str]
+ """The id of the billable metric for the price.
+
+ Only needed if the price is usage-based.
+ """
+
+ billed_in_advance: Optional[bool]
+ """
+ If the Price represents a fixed cost, the price will be billed in-advance if
+ this is true, and in-arrears if this is false.
+ """
+
+ billing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """
+ For custom cadence: specifies the duration of the billing period in days or
+ months.
+ """
+
+ conversion_rate: Optional[float]
+ """The per unit conversion rate of the price currency to the invoicing currency."""
+
+ conversion_rate_config: Optional[ReplacePricePriceNewSubscriptionDailyCreditAllowancePriceConversionRateConfig]
+ """The configuration for the rate of the price currency to the invoicing currency."""
+
+ currency: Optional[str]
+ """
+ An ISO 4217 currency string, or custom pricing unit identifier, in which this
+ price is billed.
+ """
+
+ dimensional_price_configuration: Optional[NewDimensionalPriceConfiguration]
+ """For dimensional price: specifies a price group and dimension values"""
+
+ external_price_id: Optional[str]
+ """An alias for the price."""
+
+ fixed_price_quantity: Optional[float]
+ """
+ If the Price represents a fixed cost, this represents the quantity of units
+ applied.
+ """
+
+ invoice_grouping_key: Optional[str]
+ """The property used to group this price on an invoice"""
+
+ invoicing_cycle_configuration: Optional[NewBillingCycleConfiguration]
+ """Within each billing cycle, specifies the cadence at which invoices are produced.
+
+ If unspecified, a single invoice is produced per billing cycle.
+ """
+
+ license_type_id: Optional[str]
+ """The ID of the license type to associate with this price."""
+
+ metadata: Optional[Dict[str, Optional[str]]]
+ """User-specified key/value pairs for the resource.
+
+ Individual keys can be removed by setting the value to `null`, and the entire
+ metadata mapping can be cleared by setting `metadata` to `null`.
+ """
+
+ reference_id: Optional[str]
+ """
+ A transient ID that can be used to reference this price when adding adjustments
+ in the same API call.
+ """
+
+
class ReplacePricePriceNewSubscriptionPercentCompositePricePercentConfig(TypedDict, total=False):
"""Configuration for percent pricing"""
@@ -1745,6 +2030,7 @@ class ReplacePricePriceNewSubscriptionEventOutputPrice(TypedDict, total=False):
NewSubscriptionScalableMatrixWithTieredPricingPriceParam,
NewSubscriptionCumulativeGroupedBulkPriceParam,
ReplacePricePriceNewSubscriptionCumulativeGroupedAllocationPrice,
+ ReplacePricePriceNewSubscriptionDailyCreditAllowancePrice,
NewSubscriptionMinimumCompositePriceParam,
ReplacePricePriceNewSubscriptionPercentCompositePrice,
ReplacePricePriceNewSubscriptionEventOutputPrice,
@@ -1776,6 +2062,12 @@ class ReplacePrice(TypedDict, total=False):
The subscription's maximum amount for the replacement price.
"""
+ metric_parameter_overrides: Optional[Dict[str, object]]
+ """Override values for parameterized billable metric variables.
+
+ Keys are parameter names, values are the override values.
+ """
+
minimum_amount: Optional[str]
"""[DEPRECATED] Use add_adjustments instead.
diff --git a/tests/api_resources/beta/test_external_plan_id.py b/tests/api_resources/beta/test_external_plan_id.py
index 13c78e4b..15b702e7 100644
--- a/tests/api_resources/beta/test_external_plan_id.py
+++ b/tests/api_resources/beta/test_external_plan_id.py
@@ -72,8 +72,53 @@ def test_method_create_plan_version_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -170,8 +215,53 @@ def test_method_create_plan_version_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -401,8 +491,53 @@ async def test_method_create_plan_version_with_all_params(self, async_client: As
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -499,8 +634,53 @@ async def test_method_create_plan_version_with_all_params(self, async_client: As
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
diff --git a/tests/api_resources/customers/credits/test_ledger.py b/tests/api_resources/customers/credits/test_ledger.py
index f3cf3ee6..d056bec6 100644
--- a/tests/api_resources/customers/credits/test_ledger.py
+++ b/tests/api_resources/customers/credits/test_ledger.py
@@ -110,6 +110,7 @@ def test_method_create_entry_with_all_params_overload_1(self, client: Orb) -> No
"custom_due_date": parse_date("2019-12-27"),
"invoice_date": parse_date("2019-12-27"),
"item_id": "item_id",
+ "mark_as_paid": True,
"memo": "memo",
"net_terms": 0,
"require_successful_payment": True,
@@ -433,6 +434,7 @@ def test_method_create_entry_by_external_id_with_all_params_overload_1(self, cli
"custom_due_date": parse_date("2019-12-27"),
"invoice_date": parse_date("2019-12-27"),
"item_id": "item_id",
+ "mark_as_paid": True,
"memo": "memo",
"net_terms": 0,
"require_successful_payment": True,
@@ -872,6 +874,7 @@ async def test_method_create_entry_with_all_params_overload_1(self, async_client
"custom_due_date": parse_date("2019-12-27"),
"invoice_date": parse_date("2019-12-27"),
"item_id": "item_id",
+ "mark_as_paid": True,
"memo": "memo",
"net_terms": 0,
"require_successful_payment": True,
@@ -1195,6 +1198,7 @@ async def test_method_create_entry_by_external_id_with_all_params_overload_1(sel
"custom_due_date": parse_date("2019-12-27"),
"invoice_date": parse_date("2019-12-27"),
"item_id": "item_id",
+ "mark_as_paid": True,
"memo": "memo",
"net_terms": 0,
"require_successful_payment": True,
diff --git a/tests/api_resources/plans/test_external_plan_id.py b/tests/api_resources/plans/test_external_plan_id.py
index 3c77aa9c..64838190 100644
--- a/tests/api_resources/plans/test_external_plan_id.py
+++ b/tests/api_resources/plans/test_external_plan_id.py
@@ -28,6 +28,7 @@ def test_method_update(self, client: Orb) -> None:
def test_method_update_with_all_params(self, client: Orb) -> None:
external_plan_id = client.plans.external_plan_id.update(
other_external_plan_id="external_plan_id",
+ description="description",
external_plan_id="external_plan_id",
metadata={"foo": "string"},
)
@@ -121,6 +122,7 @@ async def test_method_update(self, async_client: AsyncOrb) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncOrb) -> None:
external_plan_id = await async_client.plans.external_plan_id.update(
other_external_plan_id="external_plan_id",
+ description="description",
external_plan_id="external_plan_id",
metadata={"foo": "string"},
)
diff --git a/tests/api_resources/test_alerts.py b/tests/api_resources/test_alerts.py
index bcae7a6b..b43e00ba 100644
--- a/tests/api_resources/test_alerts.py
+++ b/tests/api_resources/test_alerts.py
@@ -274,7 +274,22 @@ def test_method_create_for_subscription_with_all_params(self, client: Orb) -> No
subscription_id="subscription_id",
thresholds=[{"value": 0}],
type="usage_exceeded",
+ grouping_keys=["string"],
metric_id="metric_id",
+ price_filters=[
+ {
+ "field": "price_id",
+ "operator": "includes",
+ "values": ["string"],
+ }
+ ],
+ pricing_unit_id="pricing_unit_id",
+ threshold_overrides=[
+ {
+ "group_values": ["string"],
+ "thresholds": [{"value": 0}],
+ }
+ ],
)
assert_matches_type(Alert, alert, path=["response"])
@@ -670,7 +685,22 @@ async def test_method_create_for_subscription_with_all_params(self, async_client
subscription_id="subscription_id",
thresholds=[{"value": 0}],
type="usage_exceeded",
+ grouping_keys=["string"],
metric_id="metric_id",
+ price_filters=[
+ {
+ "field": "price_id",
+ "operator": "includes",
+ "values": ["string"],
+ }
+ ],
+ pricing_unit_id="pricing_unit_id",
+ threshold_overrides=[
+ {
+ "group_values": ["string"],
+ "thresholds": [{"value": 0}],
+ }
+ ],
)
assert_matches_type(Alert, alert, path=["response"])
diff --git a/tests/api_resources/test_beta.py b/tests/api_resources/test_beta.py
index e391b9b2..d2f31794 100644
--- a/tests/api_resources/test_beta.py
+++ b/tests/api_resources/test_beta.py
@@ -72,8 +72,53 @@ def test_method_create_plan_version_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -170,8 +215,53 @@ def test_method_create_plan_version_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -401,8 +491,53 @@ async def test_method_create_plan_version_with_all_params(self, async_client: As
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -499,8 +634,53 @@ async def test_method_create_plan_version_with_all_params(self, async_client: As
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
diff --git a/tests/api_resources/test_customers.py b/tests/api_resources/test_customers.py
index 99212e34..2fd979de 100644
--- a/tests/api_resources/test_customers.py
+++ b/tests/api_resources/test_customers.py
@@ -66,6 +66,7 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
"payment_providers": [
{
"provider_type": "stripe",
+ "default_shared_payment_token": "default_shared_payment_token",
"excluded_payment_method_types": ["string"],
}
]
@@ -167,6 +168,7 @@ def test_method_update_with_all_params(self, client: Orb) -> None:
"payment_providers": [
{
"provider_type": "stripe",
+ "default_shared_payment_token": "default_shared_payment_token",
"excluded_payment_method_types": ["string"],
}
]
@@ -499,6 +501,7 @@ def test_method_update_by_external_id_with_all_params(self, client: Orb) -> None
"payment_providers": [
{
"provider_type": "stripe",
+ "default_shared_payment_token": "default_shared_payment_token",
"excluded_payment_method_types": ["string"],
}
]
@@ -610,6 +613,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
"payment_providers": [
{
"provider_type": "stripe",
+ "default_shared_payment_token": "default_shared_payment_token",
"excluded_payment_method_types": ["string"],
}
]
@@ -711,6 +715,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncOrb) -> No
"payment_providers": [
{
"provider_type": "stripe",
+ "default_shared_payment_token": "default_shared_payment_token",
"excluded_payment_method_types": ["string"],
}
]
@@ -1055,6 +1060,7 @@ async def test_method_update_by_external_id_with_all_params(self, async_client:
"payment_providers": [
{
"provider_type": "stripe",
+ "default_shared_payment_token": "default_shared_payment_token",
"excluded_payment_method_types": ["string"],
}
]
diff --git a/tests/api_resources/test_invoices.py b/tests/api_resources/test_invoices.py
index 316aefc3..8ae434a3 100644
--- a/tests/api_resources/test_invoices.py
+++ b/tests/api_resources/test_invoices.py
@@ -62,6 +62,7 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
},
}
],
+ auto_collection=True,
customer_id="4khy3nwzktxv7",
discount={
"discount_type": "percentage",
@@ -144,6 +145,7 @@ def test_method_update(self, client: Orb) -> None:
def test_method_update_with_all_params(self, client: Orb) -> None:
invoice = client.invoices.update(
invoice_id="invoice_id",
+ auto_collection=True,
due_date=parse_date("2023-09-22"),
invoice_date=parse_date("2023-09-22"),
metadata={"foo": "string"},
@@ -546,14 +548,16 @@ def test_path_params_mark_paid(self, client: Orb) -> None:
@parametrize
def test_method_pay(self, client: Orb) -> None:
invoice = client.invoices.pay(
- "invoice_id",
+ invoice_id="invoice_id",
+ shared_payment_token_id="shared_payment_token_id",
)
assert_matches_type(Invoice, invoice, path=["response"])
@parametrize
def test_raw_response_pay(self, client: Orb) -> None:
response = client.invoices.with_raw_response.pay(
- "invoice_id",
+ invoice_id="invoice_id",
+ shared_payment_token_id="shared_payment_token_id",
)
assert response.is_closed is True
@@ -564,7 +568,8 @@ def test_raw_response_pay(self, client: Orb) -> None:
@parametrize
def test_streaming_response_pay(self, client: Orb) -> None:
with client.invoices.with_streaming_response.pay(
- "invoice_id",
+ invoice_id="invoice_id",
+ shared_payment_token_id="shared_payment_token_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -578,7 +583,8 @@ def test_streaming_response_pay(self, client: Orb) -> None:
def test_path_params_pay(self, client: Orb) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `invoice_id` but received ''"):
client.invoices.with_raw_response.pay(
- "",
+ invoice_id="",
+ shared_payment_token_id="shared_payment_token_id",
)
@parametrize
@@ -663,6 +669,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
},
}
],
+ auto_collection=True,
customer_id="4khy3nwzktxv7",
discount={
"discount_type": "percentage",
@@ -745,6 +752,7 @@ async def test_method_update(self, async_client: AsyncOrb) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncOrb) -> None:
invoice = await async_client.invoices.update(
invoice_id="invoice_id",
+ auto_collection=True,
due_date=parse_date("2023-09-22"),
invoice_date=parse_date("2023-09-22"),
metadata={"foo": "string"},
@@ -1147,14 +1155,16 @@ async def test_path_params_mark_paid(self, async_client: AsyncOrb) -> None:
@parametrize
async def test_method_pay(self, async_client: AsyncOrb) -> None:
invoice = await async_client.invoices.pay(
- "invoice_id",
+ invoice_id="invoice_id",
+ shared_payment_token_id="shared_payment_token_id",
)
assert_matches_type(Invoice, invoice, path=["response"])
@parametrize
async def test_raw_response_pay(self, async_client: AsyncOrb) -> None:
response = await async_client.invoices.with_raw_response.pay(
- "invoice_id",
+ invoice_id="invoice_id",
+ shared_payment_token_id="shared_payment_token_id",
)
assert response.is_closed is True
@@ -1165,7 +1175,8 @@ async def test_raw_response_pay(self, async_client: AsyncOrb) -> None:
@parametrize
async def test_streaming_response_pay(self, async_client: AsyncOrb) -> None:
async with async_client.invoices.with_streaming_response.pay(
- "invoice_id",
+ invoice_id="invoice_id",
+ shared_payment_token_id="shared_payment_token_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1179,7 +1190,8 @@ async def test_streaming_response_pay(self, async_client: AsyncOrb) -> None:
async def test_path_params_pay(self, async_client: AsyncOrb) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `invoice_id` but received ''"):
await async_client.invoices.with_raw_response.pay(
- "",
+ invoice_id="",
+ shared_payment_token_id="shared_payment_token_id",
)
@parametrize
diff --git a/tests/api_resources/test_license_types.py b/tests/api_resources/test_license_types.py
index 18c708d2..804081fe 100644
--- a/tests/api_resources/test_license_types.py
+++ b/tests/api_resources/test_license_types.py
@@ -25,16 +25,16 @@ class TestLicenseTypes:
@parametrize
def test_method_create(self, client: Orb) -> None:
license_type = client.license_types.create(
- grouping_key="grouping_key",
- name="name",
+ grouping_key="x",
+ name="x",
)
assert_matches_type(LicenseTypeCreateResponse, license_type, path=["response"])
@parametrize
def test_raw_response_create(self, client: Orb) -> None:
response = client.license_types.with_raw_response.create(
- grouping_key="grouping_key",
- name="name",
+ grouping_key="x",
+ name="x",
)
assert response.is_closed is True
@@ -45,8 +45,8 @@ def test_raw_response_create(self, client: Orb) -> None:
@parametrize
def test_streaming_response_create(self, client: Orb) -> None:
with client.license_types.with_streaming_response.create(
- grouping_key="grouping_key",
- name="name",
+ grouping_key="x",
+ name="x",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -136,16 +136,16 @@ class TestAsyncLicenseTypes:
@parametrize
async def test_method_create(self, async_client: AsyncOrb) -> None:
license_type = await async_client.license_types.create(
- grouping_key="grouping_key",
- name="name",
+ grouping_key="x",
+ name="x",
)
assert_matches_type(LicenseTypeCreateResponse, license_type, path=["response"])
@parametrize
async def test_raw_response_create(self, async_client: AsyncOrb) -> None:
response = await async_client.license_types.with_raw_response.create(
- grouping_key="grouping_key",
- name="name",
+ grouping_key="x",
+ name="x",
)
assert response.is_closed is True
@@ -156,8 +156,8 @@ async def test_raw_response_create(self, async_client: AsyncOrb) -> None:
@parametrize
async def test_streaming_response_create(self, async_client: AsyncOrb) -> None:
async with async_client.license_types.with_streaming_response.create(
- grouping_key="grouping_key",
- name="name",
+ grouping_key="x",
+ name="x",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/test_plans.py b/tests/api_resources/test_plans.py
index 24286962..b8867eb5 100644
--- a/tests/api_resources/test_plans.py
+++ b/tests/api_resources/test_plans.py
@@ -53,8 +53,53 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -118,6 +163,7 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
}
],
default_invoice_memo="default_invoice_memo",
+ description="description",
external_plan_id="external_plan_id",
metadata={"foo": "string"},
net_terms=0,
@@ -172,6 +218,7 @@ def test_method_update(self, client: Orb) -> None:
def test_method_update_with_all_params(self, client: Orb) -> None:
plan = client.plans.update(
plan_id="plan_id",
+ description="description",
external_plan_id="external_plan_id",
metadata={"foo": "string"},
)
@@ -324,8 +371,53 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
+ "license_allocation_price": {
+ "cadence": "annual",
+ "item_id": "item_id",
+ "license_allocations": [
+ {
+ "amount": "amount",
+ "currency": "currency",
+ "write_off_overage": True,
+ }
+ ],
+ "model_type": "unit",
+ "name": "Annual fee",
+ "unit_config": {
+ "unit_amount": "unit_amount",
+ "prorated": True,
+ },
+ "billable_metric_id": "billable_metric_id",
+ "billed_in_advance": True,
+ "billing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "conversion_rate": 0,
+ "conversion_rate_config": {
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ "currency": "currency",
+ "dimensional_price_configuration": {
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ "external_price_id": "external_price_id",
+ "fixed_price_quantity": 0,
+ "invoice_grouping_key": "x",
+ "invoicing_cycle_configuration": {
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ "license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
+ "reference_id": "reference_id",
+ },
"plan_phase_order": 0,
"price": {
"cadence": "annual",
@@ -389,6 +481,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
}
],
default_invoice_memo="default_invoice_memo",
+ description="description",
external_plan_id="external_plan_id",
metadata={"foo": "string"},
net_terms=0,
@@ -443,6 +536,7 @@ async def test_method_update(self, async_client: AsyncOrb) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncOrb) -> None:
plan = await async_client.plans.update(
plan_id="plan_id",
+ description="description",
external_plan_id="external_plan_id",
metadata={"foo": "string"},
)
diff --git a/tests/api_resources/test_prices.py b/tests/api_resources/test_prices.py
index 68a1c59b..17549d55 100644
--- a/tests/api_resources/test_prices.py
+++ b/tests/api_resources/test_prices.py
@@ -2802,6 +2802,7 @@ def test_method_create_with_all_params_overload_25(self, client: Orb) -> None:
}
],
"unit_price": "unit_price",
+ "grouping_key": "x",
"prorate": True,
"second_dimension": "second_dimension",
},
@@ -3266,6 +3267,133 @@ def test_streaming_response_create_overload_28(self, client: Orb) -> None:
@parametrize
def test_method_create_overload_29(self, client: Orb) -> None:
+ price = client.prices.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ )
+ assert_matches_type(Price, price, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params_overload_29(self, client: Orb) -> None:
+ price = client.prices.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ billable_metric_id="billable_metric_id",
+ billed_in_advance=True,
+ billing_cycle_configuration={
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ conversion_rate=0,
+ conversion_rate_config={
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ dimensional_price_configuration={
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ external_price_id="external_price_id",
+ fixed_price_quantity=0,
+ invoice_grouping_key="x",
+ invoicing_cycle_configuration={
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ license_type_id="license_type_id",
+ metadata={"foo": "string"},
+ )
+ assert_matches_type(Price, price, path=["response"])
+
+ @parametrize
+ def test_raw_response_create_overload_29(self, client: Orb) -> None:
+ response = client.prices.with_raw_response.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ price = response.parse()
+ assert_matches_type(Price, price, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create_overload_29(self, client: Orb) -> None:
+ with client.prices.with_streaming_response.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ price = response.parse()
+ assert_matches_type(Price, price, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_create_overload_30(self, client: Orb) -> None:
price = client.prices.create(
cadence="annual",
currency="currency",
@@ -3277,7 +3405,7 @@ def test_method_create_overload_29(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_method_create_with_all_params_overload_29(self, client: Orb) -> None:
+ def test_method_create_with_all_params_overload_30(self, client: Orb) -> None:
price = client.prices.create(
cadence="annual",
currency="currency",
@@ -3317,7 +3445,7 @@ def test_method_create_with_all_params_overload_29(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_raw_response_create_overload_29(self, client: Orb) -> None:
+ def test_raw_response_create_overload_30(self, client: Orb) -> None:
response = client.prices.with_raw_response.create(
cadence="annual",
currency="currency",
@@ -3333,7 +3461,7 @@ def test_raw_response_create_overload_29(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_streaming_response_create_overload_29(self, client: Orb) -> None:
+ def test_streaming_response_create_overload_30(self, client: Orb) -> None:
with client.prices.with_streaming_response.create(
cadence="annual",
currency="currency",
@@ -3351,7 +3479,7 @@ def test_streaming_response_create_overload_29(self, client: Orb) -> None:
assert cast(Any, response.is_closed) is True
@parametrize
- def test_method_create_overload_30(self, client: Orb) -> None:
+ def test_method_create_overload_31(self, client: Orb) -> None:
price = client.prices.create(
cadence="annual",
currency="currency",
@@ -3363,7 +3491,7 @@ def test_method_create_overload_30(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_method_create_with_all_params_overload_30(self, client: Orb) -> None:
+ def test_method_create_with_all_params_overload_31(self, client: Orb) -> None:
price = client.prices.create(
cadence="annual",
currency="currency",
@@ -3400,7 +3528,7 @@ def test_method_create_with_all_params_overload_30(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_raw_response_create_overload_30(self, client: Orb) -> None:
+ def test_raw_response_create_overload_31(self, client: Orb) -> None:
response = client.prices.with_raw_response.create(
cadence="annual",
currency="currency",
@@ -3416,7 +3544,7 @@ def test_raw_response_create_overload_30(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_streaming_response_create_overload_30(self, client: Orb) -> None:
+ def test_streaming_response_create_overload_31(self, client: Orb) -> None:
with client.prices.with_streaming_response.create(
cadence="annual",
currency="currency",
@@ -3434,7 +3562,7 @@ def test_streaming_response_create_overload_30(self, client: Orb) -> None:
assert cast(Any, response.is_closed) is True
@parametrize
- def test_method_create_overload_31(self, client: Orb) -> None:
+ def test_method_create_overload_32(self, client: Orb) -> None:
price = client.prices.create(
cadence="annual",
currency="currency",
@@ -3446,7 +3574,7 @@ def test_method_create_overload_31(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_method_create_with_all_params_overload_31(self, client: Orb) -> None:
+ def test_method_create_with_all_params_overload_32(self, client: Orb) -> None:
price = client.prices.create(
cadence="annual",
currency="currency",
@@ -3487,7 +3615,7 @@ def test_method_create_with_all_params_overload_31(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_raw_response_create_overload_31(self, client: Orb) -> None:
+ def test_raw_response_create_overload_32(self, client: Orb) -> None:
response = client.prices.with_raw_response.create(
cadence="annual",
currency="currency",
@@ -3503,7 +3631,7 @@ def test_raw_response_create_overload_31(self, client: Orb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- def test_streaming_response_create_overload_31(self, client: Orb) -> None:
+ def test_streaming_response_create_overload_32(self, client: Orb) -> None:
with client.prices.with_streaming_response.create(
cadence="annual",
currency="currency",
@@ -3618,6 +3746,7 @@ def test_method_evaluate_with_all_params(self, client: Orb) -> None:
external_customer_id="external_customer_id",
filter="my_numeric_property > 100 AND my_other_property = 'bar'",
grouping_keys=["case when my_event_type = 'foo' then true else false end"],
+ metric_parameter_overrides={"foo": "bar"},
)
assert_matches_type(PriceEvaluateResponse, price, path=["response"])
@@ -3678,6 +3807,7 @@ def test_method_evaluate_multiple_with_all_params(self, client: Orb) -> None:
"external_price_id": "external_price_id",
"filter": "my_numeric_property > 100 AND my_other_property = 'bar'",
"grouping_keys": ["case when my_event_type = 'foo' then true else false end"],
+ "metric_parameter_overrides": {"foo": "bar"},
"price": {
"cadence": "annual",
"currency": "currency",
@@ -3775,6 +3905,7 @@ def test_method_evaluate_preview_events_with_all_params(self, client: Orb) -> No
"external_price_id": "external_price_id",
"filter": "my_numeric_property > 100 AND my_other_property = 'bar'",
"grouping_keys": ["case when my_event_type = 'foo' then true else false end"],
+ "metric_parameter_overrides": {"foo": "bar"},
"price": {
"cadence": "annual",
"currency": "currency",
@@ -6665,6 +6796,7 @@ async def test_method_create_with_all_params_overload_25(self, async_client: Asy
}
],
"unit_price": "unit_price",
+ "grouping_key": "x",
"prorate": True,
"second_dimension": "second_dimension",
},
@@ -7129,6 +7261,133 @@ async def test_streaming_response_create_overload_28(self, async_client: AsyncOr
@parametrize
async def test_method_create_overload_29(self, async_client: AsyncOrb) -> None:
+ price = await async_client.prices.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ )
+ assert_matches_type(Price, price, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params_overload_29(self, async_client: AsyncOrb) -> None:
+ price = await async_client.prices.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ billable_metric_id="billable_metric_id",
+ billed_in_advance=True,
+ billing_cycle_configuration={
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ conversion_rate=0,
+ conversion_rate_config={
+ "conversion_rate_type": "unit",
+ "unit_config": {"unit_amount": "unit_amount"},
+ },
+ dimensional_price_configuration={
+ "dimension_values": ["string"],
+ "dimensional_price_group_id": "dimensional_price_group_id",
+ "external_dimensional_price_group_id": "external_dimensional_price_group_id",
+ },
+ external_price_id="external_price_id",
+ fixed_price_quantity=0,
+ invoice_grouping_key="x",
+ invoicing_cycle_configuration={
+ "duration": 0,
+ "duration_unit": "day",
+ },
+ license_type_id="license_type_id",
+ metadata={"foo": "string"},
+ )
+ assert_matches_type(Price, price, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create_overload_29(self, async_client: AsyncOrb) -> None:
+ response = await async_client.prices.with_raw_response.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ price = response.parse()
+ assert_matches_type(Price, price, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create_overload_29(self, async_client: AsyncOrb) -> None:
+ async with async_client.prices.with_streaming_response.create(
+ cadence="annual",
+ currency="currency",
+ daily_credit_allowance_config={
+ "daily_allowance": "daily_allowance",
+ "default_unit_amount": "default_unit_amount",
+ "dimensions": ["string"],
+ "event_day_property": "x",
+ "matrix_values": [
+ {
+ "dimension_values": ["string"],
+ "unit_amount": "unit_amount",
+ }
+ ],
+ },
+ item_id="item_id",
+ model_type="daily_credit_allowance",
+ name="Annual fee",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ price = await response.parse()
+ assert_matches_type(Price, price, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_create_overload_30(self, async_client: AsyncOrb) -> None:
price = await async_client.prices.create(
cadence="annual",
currency="currency",
@@ -7140,7 +7399,7 @@ async def test_method_create_overload_29(self, async_client: AsyncOrb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_method_create_with_all_params_overload_29(self, async_client: AsyncOrb) -> None:
+ async def test_method_create_with_all_params_overload_30(self, async_client: AsyncOrb) -> None:
price = await async_client.prices.create(
cadence="annual",
currency="currency",
@@ -7180,7 +7439,7 @@ async def test_method_create_with_all_params_overload_29(self, async_client: Asy
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_raw_response_create_overload_29(self, async_client: AsyncOrb) -> None:
+ async def test_raw_response_create_overload_30(self, async_client: AsyncOrb) -> None:
response = await async_client.prices.with_raw_response.create(
cadence="annual",
currency="currency",
@@ -7196,7 +7455,7 @@ async def test_raw_response_create_overload_29(self, async_client: AsyncOrb) ->
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_streaming_response_create_overload_29(self, async_client: AsyncOrb) -> None:
+ async def test_streaming_response_create_overload_30(self, async_client: AsyncOrb) -> None:
async with async_client.prices.with_streaming_response.create(
cadence="annual",
currency="currency",
@@ -7214,7 +7473,7 @@ async def test_streaming_response_create_overload_29(self, async_client: AsyncOr
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_method_create_overload_30(self, async_client: AsyncOrb) -> None:
+ async def test_method_create_overload_31(self, async_client: AsyncOrb) -> None:
price = await async_client.prices.create(
cadence="annual",
currency="currency",
@@ -7226,7 +7485,7 @@ async def test_method_create_overload_30(self, async_client: AsyncOrb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_method_create_with_all_params_overload_30(self, async_client: AsyncOrb) -> None:
+ async def test_method_create_with_all_params_overload_31(self, async_client: AsyncOrb) -> None:
price = await async_client.prices.create(
cadence="annual",
currency="currency",
@@ -7263,7 +7522,7 @@ async def test_method_create_with_all_params_overload_30(self, async_client: Asy
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_raw_response_create_overload_30(self, async_client: AsyncOrb) -> None:
+ async def test_raw_response_create_overload_31(self, async_client: AsyncOrb) -> None:
response = await async_client.prices.with_raw_response.create(
cadence="annual",
currency="currency",
@@ -7279,7 +7538,7 @@ async def test_raw_response_create_overload_30(self, async_client: AsyncOrb) ->
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_streaming_response_create_overload_30(self, async_client: AsyncOrb) -> None:
+ async def test_streaming_response_create_overload_31(self, async_client: AsyncOrb) -> None:
async with async_client.prices.with_streaming_response.create(
cadence="annual",
currency="currency",
@@ -7297,7 +7556,7 @@ async def test_streaming_response_create_overload_30(self, async_client: AsyncOr
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_method_create_overload_31(self, async_client: AsyncOrb) -> None:
+ async def test_method_create_overload_32(self, async_client: AsyncOrb) -> None:
price = await async_client.prices.create(
cadence="annual",
currency="currency",
@@ -7309,7 +7568,7 @@ async def test_method_create_overload_31(self, async_client: AsyncOrb) -> None:
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_method_create_with_all_params_overload_31(self, async_client: AsyncOrb) -> None:
+ async def test_method_create_with_all_params_overload_32(self, async_client: AsyncOrb) -> None:
price = await async_client.prices.create(
cadence="annual",
currency="currency",
@@ -7350,7 +7609,7 @@ async def test_method_create_with_all_params_overload_31(self, async_client: Asy
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_raw_response_create_overload_31(self, async_client: AsyncOrb) -> None:
+ async def test_raw_response_create_overload_32(self, async_client: AsyncOrb) -> None:
response = await async_client.prices.with_raw_response.create(
cadence="annual",
currency="currency",
@@ -7366,7 +7625,7 @@ async def test_raw_response_create_overload_31(self, async_client: AsyncOrb) ->
assert_matches_type(Price, price, path=["response"])
@parametrize
- async def test_streaming_response_create_overload_31(self, async_client: AsyncOrb) -> None:
+ async def test_streaming_response_create_overload_32(self, async_client: AsyncOrb) -> None:
async with async_client.prices.with_streaming_response.create(
cadence="annual",
currency="currency",
@@ -7481,6 +7740,7 @@ async def test_method_evaluate_with_all_params(self, async_client: AsyncOrb) ->
external_customer_id="external_customer_id",
filter="my_numeric_property > 100 AND my_other_property = 'bar'",
grouping_keys=["case when my_event_type = 'foo' then true else false end"],
+ metric_parameter_overrides={"foo": "bar"},
)
assert_matches_type(PriceEvaluateResponse, price, path=["response"])
@@ -7541,6 +7801,7 @@ async def test_method_evaluate_multiple_with_all_params(self, async_client: Asyn
"external_price_id": "external_price_id",
"filter": "my_numeric_property > 100 AND my_other_property = 'bar'",
"grouping_keys": ["case when my_event_type = 'foo' then true else false end"],
+ "metric_parameter_overrides": {"foo": "bar"},
"price": {
"cadence": "annual",
"currency": "currency",
@@ -7638,6 +7899,7 @@ async def test_method_evaluate_preview_events_with_all_params(self, async_client
"external_price_id": "external_price_id",
"filter": "my_numeric_property > 100 AND my_other_property = 'bar'",
"grouping_keys": ["case when my_event_type = 'foo' then true else false end"],
+ "metric_parameter_overrides": {"foo": "bar"},
"price": {
"cadence": "annual",
"currency": "currency",
diff --git a/tests/api_resources/test_subscriptions.py b/tests/api_resources/test_subscriptions.py
index 2078ccf8..849aad5c 100644
--- a/tests/api_resources/test_subscriptions.py
+++ b/tests/api_resources/test_subscriptions.py
@@ -77,6 +77,7 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -90,6 +91,7 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
"end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
"external_price_id": "external_price_id",
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"plan_phase_order": 0,
"price": {
@@ -211,6 +213,7 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -224,6 +227,7 @@ def test_method_create_with_all_params(self, client: Orb) -> None:
"external_price_id": "external_price_id",
"fixed_price_quantity": 2,
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"price": {
"cadence": "annual",
@@ -648,7 +652,7 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
subscription_id="subscription_id",
add=[
{
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "start_date": "start_of_term",
"allocation_price": {
"amount": "10.00",
"cadence": "monthly",
@@ -667,6 +671,7 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"can_defer_billing": True,
@@ -676,7 +681,7 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
"discount_type": "amount",
}
],
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
"external_price_id": "external_price_id",
"filter": "my_property > 100 AND my_other_property = 'bar'",
"fixed_fee_quantity_transitions": [
@@ -686,6 +691,7 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
}
],
"maximum_amount": 0,
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": 0,
"price": {
"cadence": "annual",
@@ -729,7 +735,7 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
],
add_adjustments=[
{
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "start_date": "start_of_term",
"adjustment": {
"adjustment_type": "percentage_discount",
"percentage_discount": 0,
@@ -748,7 +754,7 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
"price_type": "usage",
},
"adjustment_id": "h74gfhdjvn7ujokd",
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
}
],
allow_invoice_credit_or_void=True,
@@ -758,7 +764,7 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
"price_interval_id": "sdfs6wdjvn7ujokd",
"billing_cycle_day": 0,
"can_defer_billing": True,
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
"filter": "my_property > 100 AND my_other_property = 'bar'",
"fixed_fee_quantity_transitions": [
{
@@ -766,15 +772,16 @@ def test_method_price_intervals_with_all_params(self, client: Orb) -> None:
"quantity": 5,
}
],
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "metric_parameter_overrides": {"foo": "bar"},
+ "start_date": "start_of_term",
"usage_customer_ids": ["string"],
}
],
edit_adjustments=[
{
"adjustment_interval_id": "sdfs6wdjvn7ujokd",
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
+ "start_date": "start_of_term",
}
],
)
@@ -925,6 +932,7 @@ def test_method_schedule_plan_change_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -938,6 +946,7 @@ def test_method_schedule_plan_change_with_all_params(self, client: Orb) -> None:
"end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
"external_price_id": "external_price_id",
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"plan_phase_order": 0,
"price": {
@@ -1052,6 +1061,7 @@ def test_method_schedule_plan_change_with_all_params(self, client: Orb) -> None:
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -1065,6 +1075,7 @@ def test_method_schedule_plan_change_with_all_params(self, client: Orb) -> None:
"external_price_id": "external_price_id",
"fixed_price_quantity": 2,
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"price": {
"cadence": "annual",
@@ -1477,6 +1488,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -1490,6 +1502,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
"end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
"external_price_id": "external_price_id",
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"plan_phase_order": 0,
"price": {
@@ -1611,6 +1624,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -1624,6 +1638,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncOrb) -> No
"external_price_id": "external_price_id",
"fixed_price_quantity": 2,
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"price": {
"cadence": "annual",
@@ -2048,7 +2063,7 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
subscription_id="subscription_id",
add=[
{
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "start_date": "start_of_term",
"allocation_price": {
"amount": "10.00",
"cadence": "monthly",
@@ -2067,6 +2082,7 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"can_defer_billing": True,
@@ -2076,7 +2092,7 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
"discount_type": "amount",
}
],
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
"external_price_id": "external_price_id",
"filter": "my_property > 100 AND my_other_property = 'bar'",
"fixed_fee_quantity_transitions": [
@@ -2086,6 +2102,7 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
}
],
"maximum_amount": 0,
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": 0,
"price": {
"cadence": "annual",
@@ -2129,7 +2146,7 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
],
add_adjustments=[
{
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "start_date": "start_of_term",
"adjustment": {
"adjustment_type": "percentage_discount",
"percentage_discount": 0,
@@ -2148,7 +2165,7 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
"price_type": "usage",
},
"adjustment_id": "h74gfhdjvn7ujokd",
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
}
],
allow_invoice_credit_or_void=True,
@@ -2158,7 +2175,7 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
"price_interval_id": "sdfs6wdjvn7ujokd",
"billing_cycle_day": 0,
"can_defer_billing": True,
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
"filter": "my_property > 100 AND my_other_property = 'bar'",
"fixed_fee_quantity_transitions": [
{
@@ -2166,15 +2183,16 @@ async def test_method_price_intervals_with_all_params(self, async_client: AsyncO
"quantity": 5,
}
],
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "metric_parameter_overrides": {"foo": "bar"},
+ "start_date": "start_of_term",
"usage_customer_ids": ["string"],
}
],
edit_adjustments=[
{
"adjustment_interval_id": "sdfs6wdjvn7ujokd",
- "end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
- "start_date": parse_datetime("2019-12-27T18:11:19.117Z"),
+ "end_date": "start_of_term",
+ "start_date": "start_of_term",
}
],
)
@@ -2325,6 +2343,7 @@ async def test_method_schedule_plan_change_with_all_params(self, async_client: A
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -2338,6 +2357,7 @@ async def test_method_schedule_plan_change_with_all_params(self, async_client: A
"end_date": parse_datetime("2019-12-27T18:11:19.117Z"),
"external_price_id": "external_price_id",
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"plan_phase_order": 0,
"price": {
@@ -2452,6 +2472,7 @@ async def test_method_schedule_plan_change_with_all_params(self, async_client: A
],
"item_id": "item_id",
"license_type_id": "license_type_id",
+ "metadata": {"foo": "string"},
"per_unit_cost_basis": "per_unit_cost_basis",
},
"discounts": [
@@ -2465,6 +2486,7 @@ async def test_method_schedule_plan_change_with_all_params(self, async_client: A
"external_price_id": "external_price_id",
"fixed_price_quantity": 2,
"maximum_amount": "1.23",
+ "metric_parameter_overrides": {"foo": "bar"},
"minimum_amount": "1.23",
"price": {
"cadence": "annual",
diff --git a/tests/test_client.py b/tests/test_client.py
index 32ed4d23..d6290454 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -419,6 +419,30 @@ def test_default_query_option(self) -> None:
client.close()
+ def test_hardcoded_query_params_in_url(self, client: Orb) -> None:
+ request = client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true"))
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true"}
+
+ request = client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/foo?beta=true",
+ params={"limit": "10", "page": "abc"},
+ )
+ )
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"}
+
+ request = client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/files/a%2Fb?beta=true",
+ params={"limit": "10"},
+ )
+ )
+ assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10"
+
def test_request_extra_json(self, client: Orb) -> None:
request = client._build_request(
FinalRequestOptions(
@@ -993,6 +1017,14 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None:
# Test that the proxy environment variables are set correctly
monkeypatch.setenv("HTTPS_PROXY", "https://example.org")
+ # Delete in case our environment has any proxy env vars set
+ monkeypatch.delenv("HTTP_PROXY", raising=False)
+ monkeypatch.delenv("ALL_PROXY", raising=False)
+ monkeypatch.delenv("NO_PROXY", raising=False)
+ monkeypatch.delenv("http_proxy", raising=False)
+ monkeypatch.delenv("https_proxy", raising=False)
+ monkeypatch.delenv("all_proxy", raising=False)
+ monkeypatch.delenv("no_proxy", raising=False)
client = DefaultHttpxClient()
@@ -1358,6 +1390,30 @@ async def test_default_query_option(self) -> None:
await client.close()
+ async def test_hardcoded_query_params_in_url(self, async_client: AsyncOrb) -> None:
+ request = async_client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true"))
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true"}
+
+ request = async_client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/foo?beta=true",
+ params={"limit": "10", "page": "abc"},
+ )
+ )
+ url = httpx.URL(request.url)
+ assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"}
+
+ request = async_client._build_request(
+ FinalRequestOptions(
+ method="get",
+ url="/files/a%2Fb?beta=true",
+ params={"limit": "10"},
+ )
+ )
+ assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10"
+
def test_request_extra_json(self, client: Orb) -> None:
request = client._build_request(
FinalRequestOptions(
@@ -1947,6 +2003,14 @@ async def test_get_platform(self) -> None:
async def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None:
# Test that the proxy environment variables are set correctly
monkeypatch.setenv("HTTPS_PROXY", "https://example.org")
+ # Delete in case our environment has any proxy env vars set
+ monkeypatch.delenv("HTTP_PROXY", raising=False)
+ monkeypatch.delenv("ALL_PROXY", raising=False)
+ monkeypatch.delenv("NO_PROXY", raising=False)
+ monkeypatch.delenv("http_proxy", raising=False)
+ monkeypatch.delenv("https_proxy", raising=False)
+ monkeypatch.delenv("all_proxy", raising=False)
+ monkeypatch.delenv("no_proxy", raising=False)
client = DefaultAsyncHttpxClient()
diff --git a/tests/test_deepcopy.py b/tests/test_deepcopy.py
deleted file mode 100644
index c05f70c0..00000000
--- a/tests/test_deepcopy.py
+++ /dev/null
@@ -1,58 +0,0 @@
-from orb._utils import deepcopy_minimal
-
-
-def assert_different_identities(obj1: object, obj2: object) -> None:
- assert obj1 == obj2
- assert id(obj1) != id(obj2)
-
-
-def test_simple_dict() -> None:
- obj1 = {"foo": "bar"}
- obj2 = deepcopy_minimal(obj1)
- assert_different_identities(obj1, obj2)
-
-
-def test_nested_dict() -> None:
- obj1 = {"foo": {"bar": True}}
- obj2 = deepcopy_minimal(obj1)
- assert_different_identities(obj1, obj2)
- assert_different_identities(obj1["foo"], obj2["foo"])
-
-
-def test_complex_nested_dict() -> None:
- obj1 = {"foo": {"bar": [{"hello": "world"}]}}
- obj2 = deepcopy_minimal(obj1)
- assert_different_identities(obj1, obj2)
- assert_different_identities(obj1["foo"], obj2["foo"])
- assert_different_identities(obj1["foo"]["bar"], obj2["foo"]["bar"])
- assert_different_identities(obj1["foo"]["bar"][0], obj2["foo"]["bar"][0])
-
-
-def test_simple_list() -> None:
- obj1 = ["a", "b", "c"]
- obj2 = deepcopy_minimal(obj1)
- assert_different_identities(obj1, obj2)
-
-
-def test_nested_list() -> None:
- obj1 = ["a", [1, 2, 3]]
- obj2 = deepcopy_minimal(obj1)
- assert_different_identities(obj1, obj2)
- assert_different_identities(obj1[1], obj2[1])
-
-
-class MyObject: ...
-
-
-def test_ignores_other_types() -> None:
- # custom classes
- my_obj = MyObject()
- obj1 = {"foo": my_obj}
- obj2 = deepcopy_minimal(obj1)
- assert_different_identities(obj1, obj2)
- assert obj1["foo"] is my_obj
-
- # tuples
- obj3 = ("a", "b")
- obj4 = deepcopy_minimal(obj3)
- assert obj3 is obj4
diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py
index 722b1a6c..180faff0 100644
--- a/tests/test_extract_files.py
+++ b/tests/test_extract_files.py
@@ -4,7 +4,7 @@
import pytest
-from orb._types import FileTypes
+from orb._types import FileTypes, ArrayFormat
from orb._utils import extract_files
@@ -35,6 +35,12 @@ def test_multiple_files() -> None:
assert query == {"documents": [{}, {}]}
+def test_top_level_file_array() -> None:
+ query = {"files": [b"file one", b"file two"], "title": "hello"}
+ assert extract_files(query, paths=[["files", ""]]) == [("files[]", b"file one"), ("files[]", b"file two")]
+ assert query == {"title": "hello"}
+
+
@pytest.mark.parametrize(
"query,paths,expected",
[
@@ -62,3 +68,24 @@ def test_ignores_incorrect_paths(
expected: list[tuple[str, FileTypes]],
) -> None:
assert extract_files(query, paths=paths) == expected
+
+
+@pytest.mark.parametrize(
+ "array_format,expected_top_level,expected_nested",
+ [
+ ("brackets", [("files[]", b"a"), ("files[]", b"b")], [("items[][file]", b"a"), ("items[][file]", b"b")]),
+ ("repeat", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]),
+ ("comma", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]),
+ ("indices", [("files[0]", b"a"), ("files[1]", b"b")], [("items[0][file]", b"a"), ("items[1][file]", b"b")]),
+ ],
+)
+def test_array_format_controls_file_field_names(
+ array_format: ArrayFormat,
+ expected_top_level: list[tuple[str, FileTypes]],
+ expected_nested: list[tuple[str, FileTypes]],
+) -> None:
+ top_level = {"files": [b"a", b"b"]}
+ assert extract_files(top_level, paths=[["files", ""]], array_format=array_format) == expected_top_level
+
+ nested = {"items": [{"file": b"a"}, {"file": b"b"}]}
+ assert extract_files(nested, paths=[["items", "", "file"]], array_format=array_format) == expected_nested
diff --git a/tests/test_files.py b/tests/test_files.py
index b84f4e26..20e2990c 100644
--- a/tests/test_files.py
+++ b/tests/test_files.py
@@ -4,7 +4,8 @@
import pytest
from dirty_equals import IsDict, IsList, IsBytes, IsTuple
-from orb._files import to_httpx_files, async_to_httpx_files
+from orb._files import to_httpx_files, deepcopy_with_paths, async_to_httpx_files
+from orb._utils import extract_files
readme_path = Path(__file__).parent.parent.joinpath("README.md")
@@ -49,3 +50,99 @@ def test_string_not_allowed() -> None:
"file": "foo", # type: ignore
}
)
+
+
+def assert_different_identities(obj1: object, obj2: object) -> None:
+ assert obj1 == obj2
+ assert obj1 is not obj2
+
+
+class TestDeepcopyWithPaths:
+ def test_copies_top_level_dict(self) -> None:
+ original = {"file": b"data", "other": "value"}
+ result = deepcopy_with_paths(original, [["file"]])
+ assert_different_identities(result, original)
+
+ def test_file_value_is_same_reference(self) -> None:
+ file_bytes = b"contents"
+ original = {"file": file_bytes}
+ result = deepcopy_with_paths(original, [["file"]])
+ assert_different_identities(result, original)
+ assert result["file"] is file_bytes
+
+ def test_list_popped_wholesale(self) -> None:
+ files = [b"f1", b"f2"]
+ original = {"files": files, "title": "t"}
+ result = deepcopy_with_paths(original, [["files", ""]])
+ assert_different_identities(result, original)
+ result_files = result["files"]
+ assert isinstance(result_files, list)
+ assert_different_identities(result_files, files)
+
+ def test_nested_array_path_copies_list_and_elements(self) -> None:
+ elem1 = {"file": b"f1", "extra": 1}
+ elem2 = {"file": b"f2", "extra": 2}
+ original = {"items": [elem1, elem2]}
+ result = deepcopy_with_paths(original, [["items", "", "file"]])
+ assert_different_identities(result, original)
+ result_items = result["items"]
+ assert isinstance(result_items, list)
+ assert_different_identities(result_items, original["items"])
+ assert_different_identities(result_items[0], elem1)
+ assert_different_identities(result_items[1], elem2)
+
+ def test_empty_paths_returns_same_object(self) -> None:
+ original = {"foo": "bar"}
+ result = deepcopy_with_paths(original, [])
+ assert result is original
+
+ def test_multiple_paths(self) -> None:
+ f1 = b"file1"
+ f2 = b"file2"
+ original = {"a": f1, "b": f2, "c": "unchanged"}
+ result = deepcopy_with_paths(original, [["a"], ["b"]])
+ assert_different_identities(result, original)
+ assert result["a"] is f1
+ assert result["b"] is f2
+ assert result["c"] is original["c"]
+
+ def test_extract_files_does_not_mutate_original_top_level(self) -> None:
+ file_bytes = b"contents"
+ original = {"file": file_bytes, "other": "value"}
+
+ copied = deepcopy_with_paths(original, [["file"]])
+ extracted = extract_files(copied, paths=[["file"]])
+
+ assert extracted == [("file", file_bytes)]
+ assert original == {"file": file_bytes, "other": "value"}
+ assert copied == {"other": "value"}
+
+ def test_extract_files_does_not_mutate_original_nested_array_path(self) -> None:
+ file1 = b"f1"
+ file2 = b"f2"
+ original = {
+ "items": [
+ {"file": file1, "extra": 1},
+ {"file": file2, "extra": 2},
+ ],
+ "title": "example",
+ }
+
+ copied = deepcopy_with_paths(original, [["items", "", "file"]])
+ extracted = extract_files(copied, paths=[["items", "", "file"]])
+
+ assert [entry for _, entry in extracted] == [file1, file2]
+ assert original == {
+ "items": [
+ {"file": file1, "extra": 1},
+ {"file": file2, "extra": 2},
+ ],
+ "title": "example",
+ }
+ assert copied == {
+ "items": [
+ {"extra": 1},
+ {"extra": 2},
+ ],
+ "title": "example",
+ }
diff --git a/tests/test_utils/test_path.py b/tests/test_utils/test_path.py
new file mode 100644
index 00000000..a6b990b5
--- /dev/null
+++ b/tests/test_utils/test_path.py
@@ -0,0 +1,89 @@
+from __future__ import annotations
+
+from typing import Any
+
+import pytest
+
+from orb._utils._path import path_template
+
+
+@pytest.mark.parametrize(
+ "template, kwargs, expected",
+ [
+ ("/v1/{id}", dict(id="abc"), "/v1/abc"),
+ ("/v1/{a}/{b}", dict(a="x", b="y"), "/v1/x/y"),
+ ("/v1/{a}{b}/path/{c}?val={d}#{e}", dict(a="x", b="y", c="z", d="u", e="v"), "/v1/xy/path/z?val=u#v"),
+ ("/{w}/{w}", dict(w="echo"), "/echo/echo"),
+ ("/v1/static", {}, "/v1/static"),
+ ("", {}, ""),
+ ("/v1/?q={n}&count=10", dict(n=42), "/v1/?q=42&count=10"),
+ ("/v1/{v}", dict(v=None), "/v1/null"),
+ ("/v1/{v}", dict(v=True), "/v1/true"),
+ ("/v1/{v}", dict(v=False), "/v1/false"),
+ ("/v1/{v}", dict(v=".hidden"), "/v1/.hidden"), # dot prefix ok
+ ("/v1/{v}", dict(v="file.txt"), "/v1/file.txt"), # dot in middle ok
+ ("/v1/{v}", dict(v="..."), "/v1/..."), # triple dot ok
+ ("/v1/{a}{b}", dict(a=".", b="txt"), "/v1/.txt"), # dot var combining with adjacent to be ok
+ ("/items?q={v}#{f}", dict(v=".", f=".."), "/items?q=.#.."), # dots in query/fragment are fine
+ (
+ "/v1/{a}?query={b}",
+ dict(a="../../other/endpoint", b="a&bad=true"),
+ "/v1/..%2F..%2Fother%2Fendpoint?query=a%26bad%3Dtrue",
+ ),
+ ("/v1/{val}", dict(val="a/b/c"), "/v1/a%2Fb%2Fc"),
+ ("/v1/{val}", dict(val="a/b/c?query=value"), "/v1/a%2Fb%2Fc%3Fquery=value"),
+ ("/v1/{val}", dict(val="a/b/c?query=value&bad=true"), "/v1/a%2Fb%2Fc%3Fquery=value&bad=true"),
+ ("/v1/{val}", dict(val="%20"), "/v1/%2520"), # escapes escape sequences in input
+ # Query: slash and ? are safe, # is not
+ ("/items?q={v}", dict(v="a/b"), "/items?q=a/b"),
+ ("/items?q={v}", dict(v="a?b"), "/items?q=a?b"),
+ ("/items?q={v}", dict(v="a#b"), "/items?q=a%23b"),
+ ("/items?q={v}", dict(v="a b"), "/items?q=a%20b"),
+ # Fragment: slash and ? are safe
+ ("/docs#{v}", dict(v="a/b"), "/docs#a/b"),
+ ("/docs#{v}", dict(v="a?b"), "/docs#a?b"),
+ # Path: slash, ? and # are all encoded
+ ("/v1/{v}", dict(v="a/b"), "/v1/a%2Fb"),
+ ("/v1/{v}", dict(v="a?b"), "/v1/a%3Fb"),
+ ("/v1/{v}", dict(v="a#b"), "/v1/a%23b"),
+ # same var encoded differently by component
+ (
+ "/v1/{v}?q={v}#{v}",
+ dict(v="a/b?c#d"),
+ "/v1/a%2Fb%3Fc%23d?q=a/b?c%23d#a/b?c%23d",
+ ),
+ ("/v1/{val}", dict(val="x?admin=true"), "/v1/x%3Fadmin=true"), # query injection
+ ("/v1/{val}", dict(val="x#admin"), "/v1/x%23admin"), # fragment injection
+ ],
+)
+def test_interpolation(template: str, kwargs: dict[str, Any], expected: str) -> None:
+ assert path_template(template, **kwargs) == expected
+
+
+def test_missing_kwarg_raises_key_error() -> None:
+ with pytest.raises(KeyError, match="org_id"):
+ path_template("/v1/{org_id}")
+
+
+@pytest.mark.parametrize(
+ "template, kwargs",
+ [
+ ("{a}/path", dict(a=".")),
+ ("{a}/path", dict(a="..")),
+ ("/v1/{a}", dict(a=".")),
+ ("/v1/{a}", dict(a="..")),
+ ("/v1/{a}/path", dict(a=".")),
+ ("/v1/{a}/path", dict(a="..")),
+ ("/v1/{a}{b}", dict(a=".", b=".")), # adjacent vars → ".."
+ ("/v1/{a}.", dict(a=".")), # var + static → ".."
+ ("/v1/{a}{b}", dict(a="", b=".")), # empty + dot → "."
+ ("/v1/%2e/{x}", dict(x="ok")), # encoded dot in static text
+ ("/v1/%2e./{x}", dict(x="ok")), # mixed encoded ".." in static
+ ("/v1/.%2E/{x}", dict(x="ok")), # mixed encoded ".." in static
+ ("/v1/{v}?q=1", dict(v="..")),
+ ("/v1/{v}#frag", dict(v="..")),
+ ],
+)
+def test_dot_segment_rejected(template: str, kwargs: dict[str, Any]) -> None:
+ with pytest.raises(ValueError, match="dot-segment"):
+ path_template(template, **kwargs)