diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ba9deff1..b669a2ae 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,7 +21,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/whopsdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
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
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Rye
run: |
@@ -46,7 +46,7 @@ jobs:
id-token: write
runs-on: ${{ github.repository == 'stainless-sdks/whopsdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Rye
run: |
@@ -65,7 +65,7 @@ jobs:
- name: Get GitHub OIDC Token
if: github.repository == 'stainless-sdks/whopsdk-python'
id: github-oidc
- uses: actions/github-script@v8
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: core.setOutput('github_token', await core.getIDToken());
@@ -83,7 +83,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/whopsdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Rye
run: |
diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml
index 37d87246..bfa16f2b 100644
--- a/.github/workflows/publish-pypi.yml
+++ b/.github/workflows/publish-pypi.yml
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install Rye
run: |
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
index dde36c96..007e38eb 100644
--- a/.github/workflows/release-doctor.yml
+++ b/.github/workflows/release-doctor.yml
@@ -12,7 +12,7 @@ jobs:
if: github.repository == 'whopio/whopsdk-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check release environment
run: |
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index f4cb1d13..3d2ac0bd 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.0.39"
+ ".": "0.1.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 88c851eb..0308bd5a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 212
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc/whopsdk-da82dade0c316b9abd0320bf7b1b5f3472c265106a1c53ffbb78611eacc16617.yml
-openapi_spec_hash: 2454acce3b15eaed1c5ad8554c0d4a2e
-config_hash: b4bea15093f9a57475d1d98f9b8464ca
+configured_endpoints: 216
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc/whopsdk-77d442782c147823e694535b49ff86e2da9fb6ffc967b4da744515d124542ee0.yml
+openapi_spec_hash: 47acea152482ed8697146d2c00952aa7
+config_hash: 64788a41b95ec090d1222da96d7c46d4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bfa4a149..ec03bf53 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,22 @@
# Changelog
+## 0.1.0 (2026-05-21)
+
+Full Changelog: [v0.0.39...v0.1.0](https://github.com/whopio/whopsdk-python/compare/v0.0.39...v0.1.0)
+
+### Features
+
+* **api:** api update ([597a090](https://github.com/whopio/whopsdk-python/commit/597a090c3b9fb3d0c0bcbd2651cd6ed844a531dc))
+* **api:** api update ([f7f9255](https://github.com/whopio/whopsdk-python/commit/f7f92557d76ebcc308c7391784e5274da99dd4ca))
+* **api:** api update ([f24dd5c](https://github.com/whopio/whopsdk-python/commit/f24dd5c1ce252c81c6194563ed0f06146e0723fa))
+* **api:** api update ([4329164](https://github.com/whopio/whopsdk-python/commit/4329164d5d23c20362ee2dad2cab182a2637b449))
+* **api:** api update ([686383a](https://github.com/whopio/whopsdk-python/commit/686383a7a800fdcd2df43f64145d6ef0ab377406))
+* **api:** api update ([d6080a2](https://github.com/whopio/whopsdk-python/commit/d6080a2aff41da44fab43334f3279d8f08a26a70))
+* **api:** api update ([8debdf1](https://github.com/whopio/whopsdk-python/commit/8debdf1e3c142c5c2421351378e54c6379e49b39))
+* **api:** api update ([cdbeba1](https://github.com/whopio/whopsdk-python/commit/cdbeba15f45931f55299108192063c18f3afc17e))
+* **api:** api update ([341bae2](https://github.com/whopio/whopsdk-python/commit/341bae28098d3a4561569ff89a599baf85d25717))
+* **api:** manual updates ([2dff73b](https://github.com/whopio/whopsdk-python/commit/2dff73ba93aa8e9108c0f1fece5ca322246095e0))
+
## 0.0.39 (2026-05-12)
Full Changelog: [v0.0.38...v0.0.39](https://github.com/whopio/whopsdk-python/compare/v0.0.38...v0.0.39)
diff --git a/api.md b/api.md
index 6285ef9b..8fee676c 100644
--- a/api.md
+++ b/api.md
@@ -811,7 +811,7 @@ Methods:
Types:
```python
-from whop_sdk.types import UploadStatus, FileCreateResponse, FileRetrieveResponse
+from whop_sdk.types import FileVisibility, UploadStatus, FileCreateResponse, FileRetrieveResponse
```
Methods:
@@ -1005,22 +1005,16 @@ Methods:
Types:
```python
-from whop_sdk.types import (
- AdCampaignRetrieveResponse,
- AdCampaignUpdateResponse,
- AdCampaignListResponse,
- AdCampaignPauseResponse,
- AdCampaignUnpauseResponse,
-)
+from whop_sdk.types import AdCampaign, AdCampaignPlatform, AdCampaignStatus, AdCampaignListResponse
```
Methods:
-- client.ad_campaigns.retrieve(id) -> AdCampaignRetrieveResponse
-- client.ad_campaigns.update(id, \*\*params) -> AdCampaignUpdateResponse
+- client.ad_campaigns.retrieve(id) -> AdCampaign
+- client.ad_campaigns.update(id, \*\*params) -> AdCampaign
- client.ad_campaigns.list(\*\*params) -> SyncCursorPage[AdCampaignListResponse]
-- client.ad_campaigns.pause(id) -> AdCampaignPauseResponse
-- client.ad_campaigns.unpause(id) -> AdCampaignUnpauseResponse
+- client.ad_campaigns.pause(id) -> AdCampaign
+- client.ad_campaigns.unpause(id) -> AdCampaign
# AdGroups
@@ -1028,8 +1022,9 @@ Types:
```python
from whop_sdk.types import (
- AdGroupRetrieveResponse,
- AdGroupUpdateResponse,
+ AdBudgetType,
+ AdGroup,
+ AdGroupStatus,
AdGroupListResponse,
AdGroupDeleteResponse,
)
@@ -1037,23 +1032,27 @@ from whop_sdk.types import (
Methods:
-- client.ad_groups.retrieve(id) -> AdGroupRetrieveResponse
-- client.ad_groups.update(id, \*\*params) -> AdGroupUpdateResponse
+- client.ad_groups.retrieve(id) -> AdGroup
+- client.ad_groups.update(id, \*\*params) -> AdGroup
- client.ad_groups.list(\*\*params) -> SyncCursorPage[AdGroupListResponse]
- client.ad_groups.delete(id) -> AdGroupDeleteResponse
+- client.ad_groups.pause(id) -> AdGroup
+- client.ad_groups.unpause(id) -> AdGroup
# Ads
Types:
```python
-from whop_sdk.types import AdRetrieveResponse, AdListResponse
+from whop_sdk.types import Ad, ExternalAdStatus, AdListResponse
```
Methods:
-- client.ads.retrieve(id) -> AdRetrieveResponse
+- client.ads.retrieve(id) -> Ad
- client.ads.list(\*\*params) -> SyncCursorPage[AdListResponse]
+- client.ads.pause(id) -> Ad
+- client.ads.unpause(id) -> Ad
# Conversions
@@ -1072,7 +1071,7 @@ Methods:
Types:
```python
-from whop_sdk.types import AdReportRetrieveResponse
+from whop_sdk.types import Granularities, ResultLabelKeys, AdReportRetrieveResponse
```
Methods:
diff --git a/pyproject.toml b/pyproject.toml
index 4846b0bc..9212ce8f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "whop-sdk"
-version = "0.0.39"
+version = "0.1.0"
description = "The official Python library for the Whop API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/whop_sdk/_version.py b/src/whop_sdk/_version.py
index 4a1fb7f2..162053b4 100644
--- a/src/whop_sdk/_version.py
+++ b/src/whop_sdk/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "whop_sdk"
-__version__ = "0.0.39" # x-release-please-version
+__version__ = "0.1.0" # x-release-please-version
diff --git a/src/whop_sdk/resources/ad_campaigns.py b/src/whop_sdk/resources/ad_campaigns.py
index 9c911f3b..b9dba4d7 100644
--- a/src/whop_sdk/resources/ad_campaigns.py
+++ b/src/whop_sdk/resources/ad_campaigns.py
@@ -4,11 +4,10 @@
from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Literal
import httpx
-from ..types import ad_campaign_list_params, ad_campaign_update_params
+from ..types import AdCampaignStatus, ad_campaign_list_params, ad_campaign_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -21,11 +20,9 @@
)
from ..pagination import SyncCursorPage, AsyncCursorPage
from .._base_client import AsyncPaginator, make_request_options
+from ..types.ad_campaign import AdCampaign
+from ..types.ad_campaign_status import AdCampaignStatus
from ..types.ad_campaign_list_response import AdCampaignListResponse
-from ..types.ad_campaign_pause_response import AdCampaignPauseResponse
-from ..types.ad_campaign_update_response import AdCampaignUpdateResponse
-from ..types.ad_campaign_unpause_response import AdCampaignUnpauseResponse
-from ..types.ad_campaign_retrieve_response import AdCampaignRetrieveResponse
__all__ = ["AdCampaignsResource", "AsyncAdCampaignsResource"]
@@ -62,7 +59,7 @@ def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignRetrieveResponse:
+ ) -> AdCampaign:
"""
Retrieves a single ad campaign by its unique identifier.
@@ -86,7 +83,7 @@ def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignRetrieveResponse,
+ cast_to=AdCampaign,
)
def update(
@@ -100,7 +97,7 @@ def update(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignUpdateResponse:
+ ) -> AdCampaign:
"""
Updates an ad campaign synchronously.
@@ -128,7 +125,7 @@ def update(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignUpdateResponse,
+ cast_to=AdCampaign,
)
def list(
@@ -142,7 +139,7 @@ def list(
first: Optional[int] | Omit = omit,
last: Optional[int] | Omit = omit,
query: Optional[str] | Omit = omit,
- status: Optional[Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]] | Omit = omit,
+ status: Optional[AdCampaignStatus] | 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,
@@ -221,7 +218,7 @@ def pause(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignPauseResponse:
+ ) -> AdCampaign:
"""
Pauses an ad campaign, optionally until a specific date.
@@ -245,7 +242,7 @@ def pause(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignPauseResponse,
+ cast_to=AdCampaign,
)
def unpause(
@@ -258,7 +255,7 @@ def unpause(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignUnpauseResponse:
+ ) -> AdCampaign:
"""
Resumes a paused ad campaign.
@@ -282,7 +279,7 @@ def unpause(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignUnpauseResponse,
+ cast_to=AdCampaign,
)
@@ -318,7 +315,7 @@ async def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignRetrieveResponse:
+ ) -> AdCampaign:
"""
Retrieves a single ad campaign by its unique identifier.
@@ -342,7 +339,7 @@ async def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignRetrieveResponse,
+ cast_to=AdCampaign,
)
async def update(
@@ -356,7 +353,7 @@ async def update(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignUpdateResponse:
+ ) -> AdCampaign:
"""
Updates an ad campaign synchronously.
@@ -384,7 +381,7 @@ async def update(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignUpdateResponse,
+ cast_to=AdCampaign,
)
def list(
@@ -398,7 +395,7 @@ def list(
first: Optional[int] | Omit = omit,
last: Optional[int] | Omit = omit,
query: Optional[str] | Omit = omit,
- status: Optional[Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]] | Omit = omit,
+ status: Optional[AdCampaignStatus] | 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,
@@ -477,7 +474,7 @@ async def pause(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignPauseResponse:
+ ) -> AdCampaign:
"""
Pauses an ad campaign, optionally until a specific date.
@@ -501,7 +498,7 @@ async def pause(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignPauseResponse,
+ cast_to=AdCampaign,
)
async def unpause(
@@ -514,7 +511,7 @@ async def unpause(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdCampaignUnpauseResponse:
+ ) -> AdCampaign:
"""
Resumes a paused ad campaign.
@@ -538,7 +535,7 @@ async def unpause(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdCampaignUnpauseResponse,
+ cast_to=AdCampaign,
)
diff --git a/src/whop_sdk/resources/ad_groups.py b/src/whop_sdk/resources/ad_groups.py
index f52c476d..21834e7c 100644
--- a/src/whop_sdk/resources/ad_groups.py
+++ b/src/whop_sdk/resources/ad_groups.py
@@ -4,11 +4,10 @@
from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Literal
import httpx
-from ..types import ad_group_list_params, ad_group_update_params
+from ..types import AdBudgetType, AdGroupStatus, ad_group_list_params, ad_group_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -21,10 +20,11 @@
)
from ..pagination import SyncCursorPage, AsyncCursorPage
from .._base_client import AsyncPaginator, make_request_options
+from ..types.ad_group import AdGroup
+from ..types.ad_budget_type import AdBudgetType
+from ..types.ad_group_status import AdGroupStatus
from ..types.ad_group_list_response import AdGroupListResponse
from ..types.ad_group_delete_response import AdGroupDeleteResponse
-from ..types.ad_group_update_response import AdGroupUpdateResponse
-from ..types.ad_group_retrieve_response import AdGroupRetrieveResponse
__all__ = ["AdGroupsResource", "AsyncAdGroupsResource"]
@@ -61,7 +61,7 @@ def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdGroupRetrieveResponse:
+ ) -> AdGroup:
"""
Retrieves a single ad group by its unique identifier.
@@ -85,7 +85,7 @@ def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdGroupRetrieveResponse,
+ cast_to=AdGroup,
)
def update(
@@ -93,19 +93,19 @@ def update(
id: str,
*,
budget: Optional[float] | Omit = omit,
- budget_type: Optional[Literal["daily", "lifetime"]] | Omit = omit,
+ budget_type: Optional[AdBudgetType] | Omit = omit,
config: Optional[ad_group_update_params.Config] | Omit = omit,
daily_budget: Optional[float] | Omit = omit,
name: Optional[str] | Omit = omit,
platform_config: Optional[ad_group_update_params.PlatformConfig] | Omit = omit,
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]] | Omit = omit,
+ status: Optional[AdGroupStatus] | 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,
- ) -> AdGroupUpdateResponse:
+ ) -> AdGroup:
"""
Updates an existing ad group.
@@ -156,7 +156,7 @@ def update(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdGroupUpdateResponse,
+ cast_to=AdGroup,
)
def list(
@@ -171,7 +171,7 @@ def list(
first: Optional[int] | Omit = omit,
last: Optional[int] | Omit = omit,
query: Optional[str] | Omit = omit,
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]] | Omit = omit,
+ status: Optional[AdGroupStatus] | 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,
@@ -280,6 +280,82 @@ def delete(
cast_to=AdGroupDeleteResponse,
)
+ def pause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AdGroup:
+ """
+ Pauses an ad group.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/ad_groups/{id}/pause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AdGroup,
+ )
+
+ def unpause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AdGroup:
+ """
+ Resumes a paused ad group.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/ad_groups/{id}/unpause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AdGroup,
+ )
+
class AsyncAdGroupsResource(AsyncAPIResource):
"""Ad groups"""
@@ -313,7 +389,7 @@ async def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdGroupRetrieveResponse:
+ ) -> AdGroup:
"""
Retrieves a single ad group by its unique identifier.
@@ -337,7 +413,7 @@ async def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdGroupRetrieveResponse,
+ cast_to=AdGroup,
)
async def update(
@@ -345,19 +421,19 @@ async def update(
id: str,
*,
budget: Optional[float] | Omit = omit,
- budget_type: Optional[Literal["daily", "lifetime"]] | Omit = omit,
+ budget_type: Optional[AdBudgetType] | Omit = omit,
config: Optional[ad_group_update_params.Config] | Omit = omit,
daily_budget: Optional[float] | Omit = omit,
name: Optional[str] | Omit = omit,
platform_config: Optional[ad_group_update_params.PlatformConfig] | Omit = omit,
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]] | Omit = omit,
+ status: Optional[AdGroupStatus] | 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,
- ) -> AdGroupUpdateResponse:
+ ) -> AdGroup:
"""
Updates an existing ad group.
@@ -408,7 +484,7 @@ async def update(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdGroupUpdateResponse,
+ cast_to=AdGroup,
)
def list(
@@ -423,7 +499,7 @@ def list(
first: Optional[int] | Omit = omit,
last: Optional[int] | Omit = omit,
query: Optional[str] | Omit = omit,
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]] | Omit = omit,
+ status: Optional[AdGroupStatus] | 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,
@@ -532,6 +608,82 @@ async def delete(
cast_to=AdGroupDeleteResponse,
)
+ async def pause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AdGroup:
+ """
+ Pauses an ad group.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/ad_groups/{id}/pause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AdGroup,
+ )
+
+ async def unpause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AdGroup:
+ """
+ Resumes a paused ad group.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/ad_groups/{id}/unpause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AdGroup,
+ )
+
class AdGroupsResourceWithRawResponse:
def __init__(self, ad_groups: AdGroupsResource) -> None:
@@ -549,6 +701,12 @@ def __init__(self, ad_groups: AdGroupsResource) -> None:
self.delete = to_raw_response_wrapper(
ad_groups.delete,
)
+ self.pause = to_raw_response_wrapper(
+ ad_groups.pause,
+ )
+ self.unpause = to_raw_response_wrapper(
+ ad_groups.unpause,
+ )
class AsyncAdGroupsResourceWithRawResponse:
@@ -567,6 +725,12 @@ def __init__(self, ad_groups: AsyncAdGroupsResource) -> None:
self.delete = async_to_raw_response_wrapper(
ad_groups.delete,
)
+ self.pause = async_to_raw_response_wrapper(
+ ad_groups.pause,
+ )
+ self.unpause = async_to_raw_response_wrapper(
+ ad_groups.unpause,
+ )
class AdGroupsResourceWithStreamingResponse:
@@ -585,6 +749,12 @@ def __init__(self, ad_groups: AdGroupsResource) -> None:
self.delete = to_streamed_response_wrapper(
ad_groups.delete,
)
+ self.pause = to_streamed_response_wrapper(
+ ad_groups.pause,
+ )
+ self.unpause = to_streamed_response_wrapper(
+ ad_groups.unpause,
+ )
class AsyncAdGroupsResourceWithStreamingResponse:
@@ -603,3 +773,9 @@ def __init__(self, ad_groups: AsyncAdGroupsResource) -> None:
self.delete = async_to_streamed_response_wrapper(
ad_groups.delete,
)
+ self.pause = async_to_streamed_response_wrapper(
+ ad_groups.pause,
+ )
+ self.unpause = async_to_streamed_response_wrapper(
+ ad_groups.unpause,
+ )
diff --git a/src/whop_sdk/resources/ad_reports.py b/src/whop_sdk/resources/ad_reports.py
index 380cb9e8..1c8cbd81 100644
--- a/src/whop_sdk/resources/ad_reports.py
+++ b/src/whop_sdk/resources/ad_reports.py
@@ -4,10 +4,11 @@
from typing import Union, Optional
from datetime import datetime
+from typing_extensions import Literal
import httpx
-from ..types import ad_report_retrieve_params
+from ..types import Granularities, ad_report_retrieve_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -19,6 +20,7 @@
async_to_streamed_response_wrapper,
)
from .._base_client import make_request_options
+from ..types.granularities import Granularities
from ..types.ad_report_retrieve_response import AdReportRetrieveResponse
__all__ = ["AdReportsResource", "AsyncAdReportsResource"]
@@ -54,8 +56,10 @@ def retrieve(
ad_campaign_id: Optional[str] | Omit = omit,
ad_group_id: Optional[str] | Omit = omit,
ad_id: Optional[str] | Omit = omit,
+ breakdown: Optional[Literal["campaign", "ad_group", "ad"]] | Omit = omit,
+ company_id: Optional[str] | Omit = omit,
currency: Optional[str] | Omit = omit,
- include_daily: Optional[bool] | Omit = omit,
+ granularity: Optional[Granularities] | 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,
@@ -63,11 +67,13 @@ def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> AdReportRetrieveResponse:
- """Performance report for an ad campaign, ad group, or ad.
+ """Performance report for a company, ad campaign, ad group, or ad.
- Returns aggregate totals
- and an optional per-day breakdown. Exactly one of `adCampaignId`, `adGroupId`,
- or `adId` must be provided.
+ Always returns
+ aggregate `summary` totals. Set `granularity` (`daily`/`hourly`) to additionally
+ get a time series, or set `breakdown` (`campaign`/`ad_group`/`ad`) to
+ additionally get per-entity rows inside the requested scope. Exactly one of
+ `companyId`, `adCampaignId`, `adGroupId`, or `adId` must be provided.
Required permissions:
@@ -78,19 +84,25 @@ def retrieve(
to: Inclusive end of the reporting window.
- ad_campaign_id: The unique identifier of an ad campaign. Mutually exclusive with `adGroupId` and
- `adId`.
+ ad_campaign_id: The unique identifier of an ad campaign. Mutually exclusive with `companyId`,
+ `adGroupId`, and `adId`.
- ad_group_id: The unique identifier of an ad group. Mutually exclusive with `adCampaignId` and
- `adId`.
+ ad_group_id: The unique identifier of an ad group. Mutually exclusive with `companyId`,
+ `adCampaignId`, and `adId`.
- ad_id: The unique identifier of an ad. Mutually exclusive with `adCampaignId` and
- `adGroupId`.
+ ad_id: The unique identifier of an ad. Mutually exclusive with `companyId`,
+ `adCampaignId`, and `adGroupId`.
+
+ breakdown: Entity level to group an ad report by.
+
+ company_id: The unique identifier of a company. Mutually exclusive with `adCampaignId`,
+ `adGroupId`, and `adId`. Use with `breakdown` to fan out across every campaign,
+ ad group, or ad in the company without paging.
currency: ISO 4217 currency code to report `spend` in. Defaults to the company's ads
reporting currency.
- include_daily: When true, includes a per-day breakdown alongside the summary.
+ granularity: Bucket size for external ad stat rows.
extra_headers: Send extra headers
@@ -114,8 +126,10 @@ def retrieve(
"ad_campaign_id": ad_campaign_id,
"ad_group_id": ad_group_id,
"ad_id": ad_id,
+ "breakdown": breakdown,
+ "company_id": company_id,
"currency": currency,
- "include_daily": include_daily,
+ "granularity": granularity,
},
ad_report_retrieve_params.AdReportRetrieveParams,
),
@@ -154,8 +168,10 @@ async def retrieve(
ad_campaign_id: Optional[str] | Omit = omit,
ad_group_id: Optional[str] | Omit = omit,
ad_id: Optional[str] | Omit = omit,
+ breakdown: Optional[Literal["campaign", "ad_group", "ad"]] | Omit = omit,
+ company_id: Optional[str] | Omit = omit,
currency: Optional[str] | Omit = omit,
- include_daily: Optional[bool] | Omit = omit,
+ granularity: Optional[Granularities] | 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,
@@ -163,11 +179,13 @@ async def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> AdReportRetrieveResponse:
- """Performance report for an ad campaign, ad group, or ad.
+ """Performance report for a company, ad campaign, ad group, or ad.
- Returns aggregate totals
- and an optional per-day breakdown. Exactly one of `adCampaignId`, `adGroupId`,
- or `adId` must be provided.
+ Always returns
+ aggregate `summary` totals. Set `granularity` (`daily`/`hourly`) to additionally
+ get a time series, or set `breakdown` (`campaign`/`ad_group`/`ad`) to
+ additionally get per-entity rows inside the requested scope. Exactly one of
+ `companyId`, `adCampaignId`, `adGroupId`, or `adId` must be provided.
Required permissions:
@@ -178,19 +196,25 @@ async def retrieve(
to: Inclusive end of the reporting window.
- ad_campaign_id: The unique identifier of an ad campaign. Mutually exclusive with `adGroupId` and
- `adId`.
+ ad_campaign_id: The unique identifier of an ad campaign. Mutually exclusive with `companyId`,
+ `adGroupId`, and `adId`.
+
+ ad_group_id: The unique identifier of an ad group. Mutually exclusive with `companyId`,
+ `adCampaignId`, and `adId`.
+
+ ad_id: The unique identifier of an ad. Mutually exclusive with `companyId`,
+ `adCampaignId`, and `adGroupId`.
- ad_group_id: The unique identifier of an ad group. Mutually exclusive with `adCampaignId` and
- `adId`.
+ breakdown: Entity level to group an ad report by.
- ad_id: The unique identifier of an ad. Mutually exclusive with `adCampaignId` and
- `adGroupId`.
+ company_id: The unique identifier of a company. Mutually exclusive with `adCampaignId`,
+ `adGroupId`, and `adId`. Use with `breakdown` to fan out across every campaign,
+ ad group, or ad in the company without paging.
currency: ISO 4217 currency code to report `spend` in. Defaults to the company's ads
reporting currency.
- include_daily: When true, includes a per-day breakdown alongside the summary.
+ granularity: Bucket size for external ad stat rows.
extra_headers: Send extra headers
@@ -214,8 +238,10 @@ async def retrieve(
"ad_campaign_id": ad_campaign_id,
"ad_group_id": ad_group_id,
"ad_id": ad_id,
+ "breakdown": breakdown,
+ "company_id": company_id,
"currency": currency,
- "include_daily": include_daily,
+ "granularity": granularity,
},
ad_report_retrieve_params.AdReportRetrieveParams,
),
diff --git a/src/whop_sdk/resources/ads.py b/src/whop_sdk/resources/ads.py
index 910446f0..883318d6 100644
--- a/src/whop_sdk/resources/ads.py
+++ b/src/whop_sdk/resources/ads.py
@@ -4,14 +4,14 @@
from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Literal
import httpx
-from ..types import ad_list_params
+from ..types import ExternalAdStatus, ad_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import path_template, maybe_transform
from .._compat import cached_property
+from ..types.ad import Ad
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
to_raw_response_wrapper,
@@ -22,7 +22,7 @@
from ..pagination import SyncCursorPage, AsyncCursorPage
from .._base_client import AsyncPaginator, make_request_options
from ..types.ad_list_response import AdListResponse
-from ..types.ad_retrieve_response import AdRetrieveResponse
+from ..types.external_ad_status import ExternalAdStatus
__all__ = ["AdsResource", "AsyncAdsResource"]
@@ -59,7 +59,7 @@ def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdRetrieveResponse:
+ ) -> Ad:
"""
Retrieve an ad by its unique identifier.
@@ -83,7 +83,7 @@ def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdRetrieveResponse,
+ cast_to=Ad,
)
def list(
@@ -98,7 +98,7 @@ def list(
created_before: Union[str, datetime, None] | Omit = omit,
first: Optional[int] | Omit = omit,
last: Optional[int] | Omit = omit,
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]] | Omit = omit,
+ status: Optional[ExternalAdStatus] | 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,
@@ -172,6 +172,82 @@ def list(
model=AdListResponse,
)
+ def pause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Ad:
+ """
+ Pauses an ad.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/ads/{id}/pause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Ad,
+ )
+
+ def unpause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Ad:
+ """
+ Resumes a paused ad.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/ads/{id}/unpause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Ad,
+ )
+
class AsyncAdsResource(AsyncAPIResource):
"""Ads"""
@@ -205,7 +281,7 @@ async def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AdRetrieveResponse:
+ ) -> Ad:
"""
Retrieve an ad by its unique identifier.
@@ -229,7 +305,7 @@ async def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=AdRetrieveResponse,
+ cast_to=Ad,
)
def list(
@@ -244,7 +320,7 @@ def list(
created_before: Union[str, datetime, None] | Omit = omit,
first: Optional[int] | Omit = omit,
last: Optional[int] | Omit = omit,
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]] | Omit = omit,
+ status: Optional[ExternalAdStatus] | 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,
@@ -318,6 +394,82 @@ def list(
model=AdListResponse,
)
+ async def pause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Ad:
+ """
+ Pauses an ad.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/ads/{id}/pause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Ad,
+ )
+
+ async def unpause(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Ad:
+ """
+ Resumes a paused ad.
+
+ Required permissions:
+
+ - `ad_campaign:update`
+ - `ad_campaign:basic:read`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/ads/{id}/unpause", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Ad,
+ )
+
class AdsResourceWithRawResponse:
def __init__(self, ads: AdsResource) -> None:
@@ -329,6 +481,12 @@ def __init__(self, ads: AdsResource) -> None:
self.list = to_raw_response_wrapper(
ads.list,
)
+ self.pause = to_raw_response_wrapper(
+ ads.pause,
+ )
+ self.unpause = to_raw_response_wrapper(
+ ads.unpause,
+ )
class AsyncAdsResourceWithRawResponse:
@@ -341,6 +499,12 @@ def __init__(self, ads: AsyncAdsResource) -> None:
self.list = async_to_raw_response_wrapper(
ads.list,
)
+ self.pause = async_to_raw_response_wrapper(
+ ads.pause,
+ )
+ self.unpause = async_to_raw_response_wrapper(
+ ads.unpause,
+ )
class AdsResourceWithStreamingResponse:
@@ -353,6 +517,12 @@ def __init__(self, ads: AdsResource) -> None:
self.list = to_streamed_response_wrapper(
ads.list,
)
+ self.pause = to_streamed_response_wrapper(
+ ads.pause,
+ )
+ self.unpause = to_streamed_response_wrapper(
+ ads.unpause,
+ )
class AsyncAdsResourceWithStreamingResponse:
@@ -365,3 +535,9 @@ def __init__(self, ads: AsyncAdsResource) -> None:
self.list = async_to_streamed_response_wrapper(
ads.list,
)
+ self.pause = async_to_streamed_response_wrapper(
+ ads.pause,
+ )
+ self.unpause = async_to_streamed_response_wrapper(
+ ads.unpause,
+ )
diff --git a/src/whop_sdk/resources/files.py b/src/whop_sdk/resources/files.py
index a27e5e6b..e12ed960 100644
--- a/src/whop_sdk/resources/files.py
+++ b/src/whop_sdk/resources/files.py
@@ -3,11 +3,10 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import Literal
import httpx
-from ..types import file_create_params
+from ..types import FileVisibility, file_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -19,6 +18,7 @@
async_to_streamed_response_wrapper,
)
from .._base_client import make_request_options
+from ..types.file_visibility import FileVisibility
from ..types.file_create_response import FileCreateResponse
from ..types.file_retrieve_response import FileRetrieveResponse
@@ -49,7 +49,7 @@ def create(
self,
*,
filename: str,
- visibility: Optional[Literal["public", "private"]] | Omit = omit,
+ visibility: Optional[FileVisibility] | 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,
@@ -149,7 +149,7 @@ async def create(
self,
*,
filename: str,
- visibility: Optional[Literal["public", "private"]] | Omit = omit,
+ visibility: Optional[FileVisibility] | 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,
diff --git a/src/whop_sdk/resources/payments.py b/src/whop_sdk/resources/payments.py
index b3435328..207981f5 100644
--- a/src/whop_sdk/resources/payments.py
+++ b/src/whop_sdk/resources/payments.py
@@ -263,6 +263,7 @@ def list(
after: Optional[str] | Omit = omit,
before: Optional[str] | Omit = omit,
billing_reasons: Optional[List[BillingReasons]] | Omit = omit,
+ checkout_configuration_ids: Optional[SequenceNotStr[str]] | Omit = omit,
company_id: Optional[str] | Omit = omit,
created_after: Union[str, datetime, None] | Omit = omit,
created_before: Union[str, datetime, None] | Omit = omit,
@@ -307,6 +308,8 @@ def list(
billing_reasons: Filter payments by their billing reason.
+ checkout_configuration_ids: Only return payments from these checkout configurations.
+
company_id: The unique identifier of the company to list payments for.
created_after: Only return payments created after this timestamp.
@@ -362,6 +365,7 @@ def list(
"after": after,
"before": before,
"billing_reasons": billing_reasons,
+ "checkout_configuration_ids": checkout_configuration_ids,
"company_id": company_id,
"created_after": created_after,
"created_before": created_before,
@@ -826,6 +830,7 @@ def list(
after: Optional[str] | Omit = omit,
before: Optional[str] | Omit = omit,
billing_reasons: Optional[List[BillingReasons]] | Omit = omit,
+ checkout_configuration_ids: Optional[SequenceNotStr[str]] | Omit = omit,
company_id: Optional[str] | Omit = omit,
created_after: Union[str, datetime, None] | Omit = omit,
created_before: Union[str, datetime, None] | Omit = omit,
@@ -870,6 +875,8 @@ def list(
billing_reasons: Filter payments by their billing reason.
+ checkout_configuration_ids: Only return payments from these checkout configurations.
+
company_id: The unique identifier of the company to list payments for.
created_after: Only return payments created after this timestamp.
@@ -925,6 +932,7 @@ def list(
"after": after,
"before": before,
"billing_reasons": billing_reasons,
+ "checkout_configuration_ids": checkout_configuration_ids,
"company_id": company_id,
"created_after": created_after,
"created_before": created_before,
diff --git a/src/whop_sdk/resources/plans.py b/src/whop_sdk/resources/plans.py
index 8885f8b6..0ff46a6f 100644
--- a/src/whop_sdk/resources/plans.py
+++ b/src/whop_sdk/resources/plans.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import List, Union, Iterable, Optional
+from typing import Dict, List, Union, Iterable, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -71,6 +71,7 @@ def create(
initial_price: Optional[float] | Omit = omit,
internal_notes: Optional[str] | Omit = omit,
legacy_payment_method_controls: Optional[bool] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
override_tax_type: Optional[TaxType] | Omit = omit,
payment_method_configuration: Optional[plan_create_params.PaymentMethodConfiguration] | Omit = omit,
plan_type: Optional[PlanType] | Omit = omit,
@@ -132,6 +133,10 @@ def create(
legacy_payment_method_controls: Whether this plan uses legacy payment method controls.
+ metadata: Custom key-value pairs to store on the plan. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
override_tax_type: Whether or not the tax is included in a plan's price (or if it hasn't been set
up)
@@ -184,6 +189,7 @@ def create(
"initial_price": initial_price,
"internal_notes": internal_notes,
"legacy_payment_method_controls": legacy_payment_method_controls,
+ "metadata": metadata,
"override_tax_type": override_tax_type,
"payment_method_configuration": payment_method_configuration,
"plan_type": plan_type,
@@ -256,6 +262,7 @@ def update(
initial_price: Optional[float] | Omit = omit,
internal_notes: Optional[str] | Omit = omit,
legacy_payment_method_controls: Optional[bool] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
offer_cancel_discount: Optional[bool] | Omit = omit,
override_tax_type: Optional[TaxType] | Omit = omit,
payment_method_configuration: Optional[plan_update_params.PaymentMethodConfiguration] | Omit = omit,
@@ -311,6 +318,10 @@ def update(
legacy_payment_method_controls: Whether this plan uses legacy payment method controls.
+ metadata: Custom key-value pairs to store on the plan. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
offer_cancel_discount: Whether to offer a retention discount when a customer attempts to cancel.
override_tax_type: Whether or not the tax is included in a plan's price (or if it hasn't been set
@@ -364,6 +375,7 @@ def update(
"initial_price": initial_price,
"internal_notes": internal_notes,
"legacy_payment_method_controls": legacy_payment_method_controls,
+ "metadata": metadata,
"offer_cancel_discount": offer_cancel_discount,
"override_tax_type": override_tax_type,
"payment_method_configuration": payment_method_configuration,
@@ -557,6 +569,7 @@ async def create(
initial_price: Optional[float] | Omit = omit,
internal_notes: Optional[str] | Omit = omit,
legacy_payment_method_controls: Optional[bool] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
override_tax_type: Optional[TaxType] | Omit = omit,
payment_method_configuration: Optional[plan_create_params.PaymentMethodConfiguration] | Omit = omit,
plan_type: Optional[PlanType] | Omit = omit,
@@ -618,6 +631,10 @@ async def create(
legacy_payment_method_controls: Whether this plan uses legacy payment method controls.
+ metadata: Custom key-value pairs to store on the plan. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
override_tax_type: Whether or not the tax is included in a plan's price (or if it hasn't been set
up)
@@ -670,6 +687,7 @@ async def create(
"initial_price": initial_price,
"internal_notes": internal_notes,
"legacy_payment_method_controls": legacy_payment_method_controls,
+ "metadata": metadata,
"override_tax_type": override_tax_type,
"payment_method_configuration": payment_method_configuration,
"plan_type": plan_type,
@@ -742,6 +760,7 @@ async def update(
initial_price: Optional[float] | Omit = omit,
internal_notes: Optional[str] | Omit = omit,
legacy_payment_method_controls: Optional[bool] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
offer_cancel_discount: Optional[bool] | Omit = omit,
override_tax_type: Optional[TaxType] | Omit = omit,
payment_method_configuration: Optional[plan_update_params.PaymentMethodConfiguration] | Omit = omit,
@@ -797,6 +816,10 @@ async def update(
legacy_payment_method_controls: Whether this plan uses legacy payment method controls.
+ metadata: Custom key-value pairs to store on the plan. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
offer_cancel_discount: Whether to offer a retention discount when a customer attempts to cancel.
override_tax_type: Whether or not the tax is included in a plan's price (or if it hasn't been set
@@ -850,6 +873,7 @@ async def update(
"initial_price": initial_price,
"internal_notes": internal_notes,
"legacy_payment_method_controls": legacy_payment_method_controls,
+ "metadata": metadata,
"offer_cancel_discount": offer_cancel_discount,
"override_tax_type": override_tax_type,
"payment_method_configuration": payment_method_configuration,
diff --git a/src/whop_sdk/resources/products.py b/src/whop_sdk/resources/products.py
index f2dce526..5c4c4d0d 100644
--- a/src/whop_sdk/resources/products.py
+++ b/src/whop_sdk/resources/products.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import List, Union, Iterable, Optional
+from typing import Dict, List, Union, Iterable, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -70,6 +70,7 @@ def create(
headline: Optional[str] | Omit = omit,
member_affiliate_percentage: Optional[float] | Omit = omit,
member_affiliate_status: Optional[GlobalAffiliateStatus] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
plan_options: Optional[product_create_params.PlanOptions] | Omit = omit,
product_tax_code_id: Optional[str] | Omit = omit,
redirect_purchase_url: Optional[str] | Omit = omit,
@@ -125,6 +126,10 @@ def create(
member_affiliate_status: The different statuses of the global affiliate program for a product.
+ metadata: Custom key-value pairs to store on the product. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
plan_options: Configuration for an automatically generated plan to attach to this product.
product_tax_code_id: The unique identifier of the tax classification code to apply to this product.
@@ -163,6 +168,7 @@ def create(
"headline": headline,
"member_affiliate_percentage": member_affiliate_percentage,
"member_affiliate_status": member_affiliate_status,
+ "metadata": metadata,
"plan_options": plan_options,
"product_tax_code_id": product_tax_code_id,
"redirect_purchase_url": redirect_purchase_url,
@@ -230,6 +236,7 @@ def update(
headline: Optional[str] | Omit = omit,
member_affiliate_percentage: Optional[float] | Omit = omit,
member_affiliate_status: Optional[GlobalAffiliateStatus] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
product_tax_code_id: Optional[str] | Omit = omit,
redirect_purchase_url: Optional[str] | Omit = omit,
route: Optional[str] | Omit = omit,
@@ -280,6 +287,10 @@ def update(
member_affiliate_status: The different statuses of the global affiliate program for a product.
+ metadata: Custom key-value pairs to store on the product. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
product_tax_code_id: The unique identifier of the tax classification code to apply to this product.
redirect_purchase_url: A URL to redirect the customer to after completing a purchase.
@@ -320,6 +331,7 @@ def update(
"headline": headline,
"member_affiliate_percentage": member_affiliate_percentage,
"member_affiliate_status": member_affiliate_status,
+ "metadata": metadata,
"product_tax_code_id": product_tax_code_id,
"redirect_purchase_url": redirect_purchase_url,
"route": route,
@@ -498,6 +510,7 @@ async def create(
headline: Optional[str] | Omit = omit,
member_affiliate_percentage: Optional[float] | Omit = omit,
member_affiliate_status: Optional[GlobalAffiliateStatus] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
plan_options: Optional[product_create_params.PlanOptions] | Omit = omit,
product_tax_code_id: Optional[str] | Omit = omit,
redirect_purchase_url: Optional[str] | Omit = omit,
@@ -553,6 +566,10 @@ async def create(
member_affiliate_status: The different statuses of the global affiliate program for a product.
+ metadata: Custom key-value pairs to store on the product. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
plan_options: Configuration for an automatically generated plan to attach to this product.
product_tax_code_id: The unique identifier of the tax classification code to apply to this product.
@@ -591,6 +608,7 @@ async def create(
"headline": headline,
"member_affiliate_percentage": member_affiliate_percentage,
"member_affiliate_status": member_affiliate_status,
+ "metadata": metadata,
"plan_options": plan_options,
"product_tax_code_id": product_tax_code_id,
"redirect_purchase_url": redirect_purchase_url,
@@ -658,6 +676,7 @@ async def update(
headline: Optional[str] | Omit = omit,
member_affiliate_percentage: Optional[float] | Omit = omit,
member_affiliate_status: Optional[GlobalAffiliateStatus] | Omit = omit,
+ metadata: Optional[Dict[str, object]] | Omit = omit,
product_tax_code_id: Optional[str] | Omit = omit,
redirect_purchase_url: Optional[str] | Omit = omit,
route: Optional[str] | Omit = omit,
@@ -708,6 +727,10 @@ async def update(
member_affiliate_status: The different statuses of the global affiliate program for a product.
+ metadata: Custom key-value pairs to store on the product. Included in webhook payloads for
+ payment and membership events. Max 50 keys, 500 chars per key, 5000 chars per
+ value.
+
product_tax_code_id: The unique identifier of the tax classification code to apply to this product.
redirect_purchase_url: A URL to redirect the customer to after completing a purchase.
@@ -748,6 +771,7 @@ async def update(
"headline": headline,
"member_affiliate_percentage": member_affiliate_percentage,
"member_affiliate_status": member_affiliate_status,
+ "metadata": metadata,
"product_tax_code_id": product_tax_code_id,
"redirect_purchase_url": redirect_purchase_url,
"route": route,
diff --git a/src/whop_sdk/resources/refunds.py b/src/whop_sdk/resources/refunds.py
index d845816d..7aa67e77 100644
--- a/src/whop_sdk/resources/refunds.py
+++ b/src/whop_sdk/resources/refunds.py
@@ -64,6 +64,8 @@ def retrieve(
Required permissions:
- `payment:basic:read`
+ - `plan:basic:read`
+ - `access_pass:basic:read`
- `member:email:read`
- `member:basic:read`
- `member:phone:read`
@@ -209,6 +211,8 @@ async def retrieve(
Required permissions:
- `payment:basic:read`
+ - `plan:basic:read`
+ - `access_pass:basic:read`
- `member:email:read`
- `member:basic:read`
- `member:phone:read`
diff --git a/src/whop_sdk/types/__init__.py b/src/whop_sdk/types/__init__.py
index 3329ac6f..727b2d2e 100644
--- a/src/whop_sdk/types/__init__.py
+++ b/src/whop_sdk/types/__init__.py
@@ -2,6 +2,7 @@
from __future__ import annotations
+from .ad import Ad as Ad
from .lead import Lead as Lead
from .user import User as User
from .course import Course as Course
@@ -70,6 +71,7 @@
from .ai_chat import AIChat as AIChat
from .dispute import Dispute as Dispute
from .webhook import Webhook as Webhook
+from .ad_group import AdGroup as AdGroup
from .app_type import AppType as AppType
from .affiliate import Affiliate as Affiliate
from .dm_member import DmMember as DmMember
@@ -78,25 +80,30 @@
from .embed_type import EmbedType as EmbedType
from .promo_code import PromoCode as PromoCode
from .withdrawal import Withdrawal as Withdrawal
+from .ad_campaign import AdCampaign as AdCampaign
from .api_version import APIVersion as APIVersion
from .card_brands import CardBrands as CardBrands
from .lesson_types import LessonTypes as LessonTypes
from .setup_intent import SetupIntent as SetupIntent
from .checkout_font import CheckoutFont as CheckoutFont
+from .granularities import Granularities as Granularities
from .refund_status import RefundStatus as RefundStatus
from .review_status import ReviewStatus as ReviewStatus
from .upload_status import UploadStatus as UploadStatus
from .webhook_event import WebhookEvent as WebhookEvent
+from .ad_budget_type import AdBudgetType as AdBudgetType
from .ad_list_params import AdListParams as AdListParams
from .cancel_options import CancelOptions as CancelOptions
from .checkout_modes import CheckoutModes as CheckoutModes
from .checkout_shape import CheckoutShape as CheckoutShape
from .course_chapter import CourseChapter as CourseChapter
from .promo_duration import PromoDuration as PromoDuration
+from .ad_group_status import AdGroupStatus as AdGroupStatus
from .app_list_params import AppListParams as AppListParams
from .authorized_user import AuthorizedUser as AuthorizedUser
from .billing_reasons import BillingReasons as BillingReasons
from .fee_markup_type import FeeMarkupType as FeeMarkupType
+from .file_visibility import FileVisibility as FileVisibility
from .ad_list_response import AdListResponse as AdListResponse
from .dispute_statuses import DisputeStatuses as DisputeStatuses
from .lead_list_params import LeadListParams as LeadListParams
@@ -109,11 +116,14 @@
from .entry_list_params import EntryListParams as EntryListParams
from .forum_list_params import ForumListParams as ForumListParams
from .promo_code_status import PromoCodeStatus as PromoCodeStatus
+from .result_label_keys import ResultLabelKeys as ResultLabelKeys
from .withdrawal_speeds import WithdrawalSpeeds as WithdrawalSpeeds
from .withdrawal_status import WithdrawalStatus as WithdrawalStatus
+from .ad_campaign_status import AdCampaignStatus as AdCampaignStatus
from .bounty_list_params import BountyListParams as BountyListParams
from .course_list_params import CourseListParams as CourseListParams
from .dispute_alert_type import DisputeAlertType as DisputeAlertType
+from .external_ad_status import ExternalAdStatus as ExternalAdStatus
from .file_create_params import FileCreateParams as FileCreateParams
from .lead_create_params import LeadCreateParams as LeadCreateParams
from .lead_list_response import LeadListResponse as LeadListResponse
@@ -143,8 +153,8 @@
from .topup_create_params import TopupCreateParams as TopupCreateParams
from .verification_status import VerificationStatus as VerificationStatus
from .webhook_list_params import WebhookListParams as WebhookListParams
+from .ad_campaign_platform import AdCampaignPlatform as AdCampaignPlatform
from .ad_group_list_params import AdGroupListParams as AdGroupListParams
-from .ad_retrieve_response import AdRetrieveResponse as AdRetrieveResponse
from .bounty_create_params import BountyCreateParams as BountyCreateParams
from .bounty_list_response import BountyListResponse as BountyListResponse
from .course_create_params import CourseCreateParams as CourseCreateParams
@@ -229,7 +239,6 @@
from .webhook_create_response import WebhookCreateResponse as WebhookCreateResponse
from .webhook_delete_response import WebhookDeleteResponse as WebhookDeleteResponse
from .ad_group_delete_response import AdGroupDeleteResponse as AdGroupDeleteResponse
-from .ad_group_update_response import AdGroupUpdateResponse as AdGroupUpdateResponse
from .bounty_retrieve_response import BountyRetrieveResponse as BountyRetrieveResponse
from .chat_channel_list_params import ChatChannelListParams as ChatChannelListParams
from .conversion_create_params import ConversionCreateParams as ConversionCreateParams
@@ -272,8 +281,6 @@
from .payout_method_list_params import PayoutMethodListParams as PayoutMethodListParams
from .access_token_create_params import AccessTokenCreateParams as AccessTokenCreateParams
from .account_link_create_params import AccountLinkCreateParams as AccountLinkCreateParams
-from .ad_campaign_pause_response import AdCampaignPauseResponse as AdCampaignPauseResponse
-from .ad_group_retrieve_response import AdGroupRetrieveResponse as AdGroupRetrieveResponse
from .affiliate_archive_response import AffiliateArchiveResponse as AffiliateArchiveResponse
from .chat_channel_list_response import ChatChannelListResponse as ChatChannelListResponse
from .chat_channel_update_params import ChatChannelUpdateParams as ChatChannelUpdateParams
@@ -295,7 +302,6 @@
from .setup_intent_list_response import SetupIntentListResponse as SetupIntentListResponse
from .user_check_access_response import UserCheckAccessResponse as UserCheckAccessResponse
from .verification_list_response import VerificationListResponse as VerificationListResponse
-from .ad_campaign_update_response import AdCampaignUpdateResponse as AdCampaignUpdateResponse
from .ad_report_retrieve_response import AdReportRetrieveResponse as AdReportRetrieveResponse
from .authorized_user_list_params import AuthorizedUserListParams as AuthorizedUserListParams
from .course_lesson_create_params import CourseLessonCreateParams as CourseLessonCreateParams
@@ -310,7 +316,6 @@
from .support_channel_list_params import SupportChannelListParams as SupportChannelListParams
from .access_token_create_response import AccessTokenCreateResponse as AccessTokenCreateResponse
from .account_link_create_response import AccountLinkCreateResponse as AccountLinkCreateResponse
-from .ad_campaign_unpause_response import AdCampaignUnpauseResponse as AdCampaignUnpauseResponse
from .affiliate_unarchive_response import AffiliateUnarchiveResponse as AffiliateUnarchiveResponse
from .course_chapter_create_params import CourseChapterCreateParams as CourseChapterCreateParams
from .course_chapter_list_response import CourseChapterListResponse as CourseChapterListResponse
@@ -324,7 +329,6 @@
from .payment_method_list_response import PaymentMethodListResponse as PaymentMethodListResponse
from .refund_created_webhook_event import RefundCreatedWebhookEvent as RefundCreatedWebhookEvent
from .refund_updated_webhook_event import RefundUpdatedWebhookEvent as RefundUpdatedWebhookEvent
-from .ad_campaign_retrieve_response import AdCampaignRetrieveResponse as AdCampaignRetrieveResponse
from .authorized_user_create_params import AuthorizedUserCreateParams as AuthorizedUserCreateParams
from .authorized_user_delete_params import AuthorizedUserDeleteParams as AuthorizedUserDeleteParams
from .authorized_user_list_response import AuthorizedUserListResponse as AuthorizedUserListResponse
diff --git a/src/whop_sdk/types/ad_retrieve_response.py b/src/whop_sdk/types/ad.py
similarity index 80%
rename from src/whop_sdk/types/ad_retrieve_response.py
rename to src/whop_sdk/types/ad.py
index b7f9897c..e2a1a0bd 100644
--- a/src/whop_sdk/types/ad_retrieve_response.py
+++ b/src/whop_sdk/types/ad.py
@@ -2,11 +2,12 @@
from typing import Optional
from datetime import datetime
-from typing_extensions import Literal
from .._models import BaseModel
+from .external_ad_status import ExternalAdStatus
+from .ad_campaign_platform import AdCampaignPlatform
-__all__ = ["AdRetrieveResponse", "AdCampaign", "AdGroup"]
+__all__ = ["Ad", "AdCampaign", "AdGroup"]
class AdCampaign(BaseModel):
@@ -23,7 +24,7 @@ class AdGroup(BaseModel):
"""The unique identifier for this ad group."""
-class AdRetrieveResponse(BaseModel):
+class Ad(BaseModel):
"""An ad belonging to an ad group."""
id: str
@@ -38,10 +39,10 @@ class AdRetrieveResponse(BaseModel):
created_at: datetime
"""When the ad was created."""
- platform: Literal["meta", "tiktok"]
+ platform: AdCampaignPlatform
"""The external ad platform this ad is running on (e.g., meta, tiktok)."""
- status: Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]
+ status: ExternalAdStatus
"""Current delivery status of the ad."""
title: Optional[str] = None
diff --git a/src/whop_sdk/types/ad_budget_type.py b/src/whop_sdk/types/ad_budget_type.py
new file mode 100644
index 00000000..d3eee5dd
--- /dev/null
+++ b/src/whop_sdk/types/ad_budget_type.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["AdBudgetType"]
+
+AdBudgetType: TypeAlias = Literal["daily", "lifetime"]
diff --git a/src/whop_sdk/types/ad_campaign_pause_response.py b/src/whop_sdk/types/ad_campaign.py
similarity index 89%
rename from src/whop_sdk/types/ad_campaign_pause_response.py
rename to src/whop_sdk/types/ad_campaign.py
index 125620f3..6d201157 100644
--- a/src/whop_sdk/types/ad_campaign_pause_response.py
+++ b/src/whop_sdk/types/ad_campaign.py
@@ -5,8 +5,11 @@
from typing_extensions import Literal
from .._models import BaseModel
+from .ad_budget_type import AdBudgetType
+from .ad_campaign_status import AdCampaignStatus
+from .ad_campaign_platform import AdCampaignPlatform
-__all__ = ["AdCampaignPauseResponse", "CreatedByUser", "MetaConfig"]
+__all__ = ["AdCampaign", "CreatedByUser", "MetaConfig"]
class CreatedByUser(BaseModel):
@@ -65,7 +68,7 @@ class MetaConfig(BaseModel):
"""The campaign status as set by the advertiser (active or paused)."""
-class AdCampaignPauseResponse(BaseModel):
+class AdCampaign(BaseModel):
"""An advertising campaign running on an external platform or within Whop."""
id: str
@@ -74,7 +77,7 @@ class AdCampaignPauseResponse(BaseModel):
budget: Optional[float] = None
"""Total budget in dollars."""
- budget_type: Optional[Literal["daily", "lifetime"]] = None
+ budget_type: Optional[AdBudgetType] = None
"""The budget type for an ad campaign or ad group."""
created_at: datetime
@@ -89,10 +92,10 @@ class AdCampaignPauseResponse(BaseModel):
Null for non-Meta campaigns.
"""
- platform: Literal["meta", "tiktok"]
+ platform: AdCampaignPlatform
"""The external ad platform this campaign is running on (e.g., meta, tiktok)."""
- status: Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]
+ status: AdCampaignStatus
"""Current status of the campaign (active, paused, or inactive)."""
title: str
diff --git a/src/whop_sdk/types/ad_campaign_list_params.py b/src/whop_sdk/types/ad_campaign_list_params.py
index 9f983f7d..021afde0 100644
--- a/src/whop_sdk/types/ad_campaign_list_params.py
+++ b/src/whop_sdk/types/ad_campaign_list_params.py
@@ -4,9 +4,10 @@
from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Literal, Required, Annotated, TypedDict
+from typing_extensions import Required, Annotated, TypedDict
from .._utils import PropertyInfo
+from .ad_campaign_status import AdCampaignStatus
__all__ = ["AdCampaignListParams"]
@@ -36,5 +37,5 @@ class AdCampaignListParams(TypedDict, total=False):
query: Optional[str]
"""Case-insensitive substring match against the campaign title."""
- status: Optional[Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]]
+ status: Optional[AdCampaignStatus]
"""The status of an ad campaign."""
diff --git a/src/whop_sdk/types/ad_campaign_list_response.py b/src/whop_sdk/types/ad_campaign_list_response.py
index e99ca67a..7123408d 100644
--- a/src/whop_sdk/types/ad_campaign_list_response.py
+++ b/src/whop_sdk/types/ad_campaign_list_response.py
@@ -2,9 +2,11 @@
from typing import Optional
from datetime import datetime
-from typing_extensions import Literal
from .._models import BaseModel
+from .ad_budget_type import AdBudgetType
+from .ad_campaign_status import AdCampaignStatus
+from .ad_campaign_platform import AdCampaignPlatform
__all__ = ["AdCampaignListResponse"]
@@ -18,16 +20,16 @@ class AdCampaignListResponse(BaseModel):
budget: Optional[float] = None
"""Total budget in dollars."""
- budget_type: Optional[Literal["daily", "lifetime"]] = None
+ budget_type: Optional[AdBudgetType] = None
"""The budget type for an ad campaign or ad group."""
created_at: datetime
"""When the ad campaign was created."""
- platform: Literal["meta", "tiktok"]
+ platform: AdCampaignPlatform
"""The external ad platform this campaign is running on (e.g., meta, tiktok)."""
- status: Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]
+ status: AdCampaignStatus
"""Current status of the campaign (active, paused, or inactive)."""
title: str
diff --git a/src/whop_sdk/types/ad_campaign_platform.py b/src/whop_sdk/types/ad_campaign_platform.py
new file mode 100644
index 00000000..1e841130
--- /dev/null
+++ b/src/whop_sdk/types/ad_campaign_platform.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["AdCampaignPlatform"]
+
+AdCampaignPlatform: TypeAlias = Literal["meta", "tiktok"]
diff --git a/src/whop_sdk/types/ad_campaign_retrieve_response.py b/src/whop_sdk/types/ad_campaign_retrieve_response.py
deleted file mode 100644
index 372ceba0..00000000
--- a/src/whop_sdk/types/ad_campaign_retrieve_response.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["AdCampaignRetrieveResponse", "CreatedByUser", "MetaConfig"]
-
-
-class CreatedByUser(BaseModel):
- """The user who created this ad campaign."""
-
- id: str
- """The unique identifier for the user."""
-
- name: Optional[str] = None
- """The user's display name shown on their public profile."""
-
- username: str
- """The user's unique username shown on their public profile."""
-
-
-class MetaConfig(BaseModel):
- """Meta-specific campaign configuration (objective, budget mode, etc.).
-
- Null for non-Meta campaigns.
- """
-
- bid_amount: Optional[int] = None
- """Bid cap amount in cents. Only used when bid_strategy is bid_cap."""
-
- bid_strategy: Optional[Literal["lowest_cost", "bid_cap", "cost_cap"]] = None
- """The bidding strategy used to optimize spend for this campaign."""
-
- budget_optimization: Optional[bool] = None
- """
- Whether campaign budget optimization (CBO) is enabled, allowing the platform to
- distribute budget across ad groups.
- """
-
- effective_status: Optional[Literal["active", "paused", "deleted", "in_review", "rejected", "with_issues"]] = None
- """
- The actual delivery status, accounting for platform overrides (e.g., in_review,
- rejected).
- """
-
- end_time: Optional[str] = None
- """The scheduled end time of the campaign (ISO8601)."""
-
- objective: Optional[Literal["awareness", "traffic", "engagement", "leads", "sales"]] = None
- """The campaign objective that determines how Meta optimizes delivery."""
-
- special_categories: Optional[List[str]] = None
- """
- Special ad categories required by the platform (e.g., housing, employment,
- credit).
- """
-
- start_time: Optional[str] = None
- """The scheduled start time of the campaign (ISO8601)."""
-
- status: Optional[Literal["active", "paused"]] = None
- """The campaign status as set by the advertiser (active or paused)."""
-
-
-class AdCampaignRetrieveResponse(BaseModel):
- """An advertising campaign running on an external platform or within Whop."""
-
- id: str
- """The unique identifier for this ad campaign."""
-
- budget: Optional[float] = None
- """Total budget in dollars."""
-
- budget_type: Optional[Literal["daily", "lifetime"]] = None
- """The budget type for an ad campaign or ad group."""
-
- created_at: datetime
- """When the ad campaign was created."""
-
- created_by_user: CreatedByUser
- """The user who created this ad campaign."""
-
- meta_config: Optional[MetaConfig] = None
- """Meta-specific campaign configuration (objective, budget mode, etc.).
-
- Null for non-Meta campaigns.
- """
-
- platform: Literal["meta", "tiktok"]
- """The external ad platform this campaign is running on (e.g., meta, tiktok)."""
-
- status: Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]
- """Current status of the campaign (active, paused, or inactive)."""
-
- title: str
- """The campaign name shown in the Whop dashboard."""
-
- total_spend: float
- """Total amount spent in dollars."""
-
- updated_at: datetime
- """When the ad campaign was last updated."""
diff --git a/src/whop_sdk/types/ad_campaign_status.py b/src/whop_sdk/types/ad_campaign_status.py
new file mode 100644
index 00000000..ddfbdf4e
--- /dev/null
+++ b/src/whop_sdk/types/ad_campaign_status.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["AdCampaignStatus"]
+
+AdCampaignStatus: TypeAlias = Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]
diff --git a/src/whop_sdk/types/ad_campaign_unpause_response.py b/src/whop_sdk/types/ad_campaign_unpause_response.py
deleted file mode 100644
index dd83dea4..00000000
--- a/src/whop_sdk/types/ad_campaign_unpause_response.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["AdCampaignUnpauseResponse", "CreatedByUser", "MetaConfig"]
-
-
-class CreatedByUser(BaseModel):
- """The user who created this ad campaign."""
-
- id: str
- """The unique identifier for the user."""
-
- name: Optional[str] = None
- """The user's display name shown on their public profile."""
-
- username: str
- """The user's unique username shown on their public profile."""
-
-
-class MetaConfig(BaseModel):
- """Meta-specific campaign configuration (objective, budget mode, etc.).
-
- Null for non-Meta campaigns.
- """
-
- bid_amount: Optional[int] = None
- """Bid cap amount in cents. Only used when bid_strategy is bid_cap."""
-
- bid_strategy: Optional[Literal["lowest_cost", "bid_cap", "cost_cap"]] = None
- """The bidding strategy used to optimize spend for this campaign."""
-
- budget_optimization: Optional[bool] = None
- """
- Whether campaign budget optimization (CBO) is enabled, allowing the platform to
- distribute budget across ad groups.
- """
-
- effective_status: Optional[Literal["active", "paused", "deleted", "in_review", "rejected", "with_issues"]] = None
- """
- The actual delivery status, accounting for platform overrides (e.g., in_review,
- rejected).
- """
-
- end_time: Optional[str] = None
- """The scheduled end time of the campaign (ISO8601)."""
-
- objective: Optional[Literal["awareness", "traffic", "engagement", "leads", "sales"]] = None
- """The campaign objective that determines how Meta optimizes delivery."""
-
- special_categories: Optional[List[str]] = None
- """
- Special ad categories required by the platform (e.g., housing, employment,
- credit).
- """
-
- start_time: Optional[str] = None
- """The scheduled start time of the campaign (ISO8601)."""
-
- status: Optional[Literal["active", "paused"]] = None
- """The campaign status as set by the advertiser (active or paused)."""
-
-
-class AdCampaignUnpauseResponse(BaseModel):
- """An advertising campaign running on an external platform or within Whop."""
-
- id: str
- """The unique identifier for this ad campaign."""
-
- budget: Optional[float] = None
- """Total budget in dollars."""
-
- budget_type: Optional[Literal["daily", "lifetime"]] = None
- """The budget type for an ad campaign or ad group."""
-
- created_at: datetime
- """When the ad campaign was created."""
-
- created_by_user: CreatedByUser
- """The user who created this ad campaign."""
-
- meta_config: Optional[MetaConfig] = None
- """Meta-specific campaign configuration (objective, budget mode, etc.).
-
- Null for non-Meta campaigns.
- """
-
- platform: Literal["meta", "tiktok"]
- """The external ad platform this campaign is running on (e.g., meta, tiktok)."""
-
- status: Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]
- """Current status of the campaign (active, paused, or inactive)."""
-
- title: str
- """The campaign name shown in the Whop dashboard."""
-
- total_spend: float
- """Total amount spent in dollars."""
-
- updated_at: datetime
- """When the ad campaign was last updated."""
diff --git a/src/whop_sdk/types/ad_campaign_update_response.py b/src/whop_sdk/types/ad_campaign_update_response.py
deleted file mode 100644
index b7f5c437..00000000
--- a/src/whop_sdk/types/ad_campaign_update_response.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["AdCampaignUpdateResponse", "CreatedByUser", "MetaConfig"]
-
-
-class CreatedByUser(BaseModel):
- """The user who created this ad campaign."""
-
- id: str
- """The unique identifier for the user."""
-
- name: Optional[str] = None
- """The user's display name shown on their public profile."""
-
- username: str
- """The user's unique username shown on their public profile."""
-
-
-class MetaConfig(BaseModel):
- """Meta-specific campaign configuration (objective, budget mode, etc.).
-
- Null for non-Meta campaigns.
- """
-
- bid_amount: Optional[int] = None
- """Bid cap amount in cents. Only used when bid_strategy is bid_cap."""
-
- bid_strategy: Optional[Literal["lowest_cost", "bid_cap", "cost_cap"]] = None
- """The bidding strategy used to optimize spend for this campaign."""
-
- budget_optimization: Optional[bool] = None
- """
- Whether campaign budget optimization (CBO) is enabled, allowing the platform to
- distribute budget across ad groups.
- """
-
- effective_status: Optional[Literal["active", "paused", "deleted", "in_review", "rejected", "with_issues"]] = None
- """
- The actual delivery status, accounting for platform overrides (e.g., in_review,
- rejected).
- """
-
- end_time: Optional[str] = None
- """The scheduled end time of the campaign (ISO8601)."""
-
- objective: Optional[Literal["awareness", "traffic", "engagement", "leads", "sales"]] = None
- """The campaign objective that determines how Meta optimizes delivery."""
-
- special_categories: Optional[List[str]] = None
- """
- Special ad categories required by the platform (e.g., housing, employment,
- credit).
- """
-
- start_time: Optional[str] = None
- """The scheduled start time of the campaign (ISO8601)."""
-
- status: Optional[Literal["active", "paused"]] = None
- """The campaign status as set by the advertiser (active or paused)."""
-
-
-class AdCampaignUpdateResponse(BaseModel):
- """An advertising campaign running on an external platform or within Whop."""
-
- id: str
- """The unique identifier for this ad campaign."""
-
- budget: Optional[float] = None
- """Total budget in dollars."""
-
- budget_type: Optional[Literal["daily", "lifetime"]] = None
- """The budget type for an ad campaign or ad group."""
-
- created_at: datetime
- """When the ad campaign was created."""
-
- created_by_user: CreatedByUser
- """The user who created this ad campaign."""
-
- meta_config: Optional[MetaConfig] = None
- """Meta-specific campaign configuration (objective, budget mode, etc.).
-
- Null for non-Meta campaigns.
- """
-
- platform: Literal["meta", "tiktok"]
- """The external ad platform this campaign is running on (e.g., meta, tiktok)."""
-
- status: Literal["active", "paused", "payment_failed", "draft", "in_review", "flagged"]
- """Current status of the campaign (active, paused, or inactive)."""
-
- title: str
- """The campaign name shown in the Whop dashboard."""
-
- total_spend: float
- """Total amount spent in dollars."""
-
- updated_at: datetime
- """When the ad campaign was last updated."""
diff --git a/src/whop_sdk/types/ad_group_update_response.py b/src/whop_sdk/types/ad_group.py
similarity index 76%
rename from src/whop_sdk/types/ad_group_update_response.py
rename to src/whop_sdk/types/ad_group.py
index 5a079222..384dbf5f 100644
--- a/src/whop_sdk/types/ad_group_update_response.py
+++ b/src/whop_sdk/types/ad_group.py
@@ -2,11 +2,13 @@
from typing import Optional
from datetime import datetime
-from typing_extensions import Literal
from .._models import BaseModel
+from .ad_budget_type import AdBudgetType
+from .ad_group_status import AdGroupStatus
+from .ad_campaign_platform import AdCampaignPlatform
-__all__ = ["AdGroupUpdateResponse", "AdCampaign"]
+__all__ = ["AdGroup", "AdCampaign"]
class AdCampaign(BaseModel):
@@ -16,7 +18,7 @@ class AdCampaign(BaseModel):
"""The unique identifier for this ad campaign."""
-class AdGroupUpdateResponse(BaseModel):
+class AdGroup(BaseModel):
"""An ad group (ad set) belonging to an ad campaign."""
id: str
@@ -28,16 +30,16 @@ class AdGroupUpdateResponse(BaseModel):
budget: Optional[float] = None
"""Budget amount in dollars."""
- budget_type: Optional[Literal["daily", "lifetime"]] = None
+ budget_type: Optional[AdBudgetType] = None
"""The budget type for an ad campaign or ad group."""
created_at: datetime
"""When the ad group was created."""
- platform: Literal["meta", "tiktok"]
+ platform: AdCampaignPlatform
"""The external ad platform this ad group is running on (e.g., meta, tiktok)."""
- status: Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]
+ status: AdGroupStatus
"""Current operational status of the ad group."""
title: Optional[str] = None
diff --git a/src/whop_sdk/types/ad_group_list_params.py b/src/whop_sdk/types/ad_group_list_params.py
index cde96fb8..05757db0 100644
--- a/src/whop_sdk/types/ad_group_list_params.py
+++ b/src/whop_sdk/types/ad_group_list_params.py
@@ -4,9 +4,10 @@
from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Literal, Annotated, TypedDict
+from typing_extensions import Annotated, TypedDict
from .._utils import PropertyInfo
+from .ad_group_status import AdGroupStatus
__all__ = ["AdGroupListParams"]
@@ -39,5 +40,5 @@ class AdGroupListParams(TypedDict, total=False):
query: Optional[str]
"""Case-insensitive substring match against the ad group name."""
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]]
+ status: Optional[AdGroupStatus]
"""The status of an external ad group."""
diff --git a/src/whop_sdk/types/ad_group_list_response.py b/src/whop_sdk/types/ad_group_list_response.py
index 093da1e8..dac01854 100644
--- a/src/whop_sdk/types/ad_group_list_response.py
+++ b/src/whop_sdk/types/ad_group_list_response.py
@@ -2,11 +2,20 @@
from typing import Optional
from datetime import datetime
-from typing_extensions import Literal
from .._models import BaseModel
+from .ad_budget_type import AdBudgetType
+from .ad_group_status import AdGroupStatus
+from .ad_campaign_platform import AdCampaignPlatform
-__all__ = ["AdGroupListResponse"]
+__all__ = ["AdGroupListResponse", "AdCampaign"]
+
+
+class AdCampaign(BaseModel):
+ """The ad campaign this ad group belongs to."""
+
+ id: str
+ """The unique identifier for this ad campaign."""
class AdGroupListResponse(BaseModel):
@@ -15,19 +24,22 @@ class AdGroupListResponse(BaseModel):
id: str
"""The unique identifier for this ad group."""
+ ad_campaign: AdCampaign
+ """The ad campaign this ad group belongs to."""
+
budget: Optional[float] = None
"""Budget amount in dollars."""
- budget_type: Optional[Literal["daily", "lifetime"]] = None
+ budget_type: Optional[AdBudgetType] = None
"""The budget type for an ad campaign or ad group."""
created_at: datetime
"""When the ad group was created."""
- platform: Literal["meta", "tiktok"]
+ platform: AdCampaignPlatform
"""The external ad platform this ad group is running on (e.g., meta, tiktok)."""
- status: Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]
+ status: AdGroupStatus
"""Current operational status of the ad group."""
title: Optional[str] = None
diff --git a/src/whop_sdk/types/ad_group_retrieve_response.py b/src/whop_sdk/types/ad_group_retrieve_response.py
deleted file mode 100644
index 7b447725..00000000
--- a/src/whop_sdk/types/ad_group_retrieve_response.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["AdGroupRetrieveResponse", "AdCampaign"]
-
-
-class AdCampaign(BaseModel):
- """The ad campaign this ad group belongs to."""
-
- id: str
- """The unique identifier for this ad campaign."""
-
-
-class AdGroupRetrieveResponse(BaseModel):
- """An ad group (ad set) belonging to an ad campaign."""
-
- id: str
- """The unique identifier for this ad group."""
-
- ad_campaign: AdCampaign
- """The ad campaign this ad group belongs to."""
-
- budget: Optional[float] = None
- """Budget amount in dollars."""
-
- budget_type: Optional[Literal["daily", "lifetime"]] = None
- """The budget type for an ad campaign or ad group."""
-
- created_at: datetime
- """When the ad group was created."""
-
- platform: Literal["meta", "tiktok"]
- """The external ad platform this ad group is running on (e.g., meta, tiktok)."""
-
- status: Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]
- """Current operational status of the ad group."""
-
- title: Optional[str] = None
- """Human-readable name shown on the external platform."""
-
- updated_at: datetime
- """When the ad group was last updated."""
diff --git a/src/whop_sdk/types/ad_group_status.py b/src/whop_sdk/types/ad_group_status.py
new file mode 100644
index 00000000..625dbfda
--- /dev/null
+++ b/src/whop_sdk/types/ad_group_status.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["AdGroupStatus"]
+
+AdGroupStatus: TypeAlias = Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]
diff --git a/src/whop_sdk/types/ad_group_update_params.py b/src/whop_sdk/types/ad_group_update_params.py
index bb7e7265..d97cab88 100644
--- a/src/whop_sdk/types/ad_group_update_params.py
+++ b/src/whop_sdk/types/ad_group_update_params.py
@@ -6,6 +6,8 @@
from typing_extensions import Literal, Required, TypedDict
from .._types import SequenceNotStr
+from .ad_budget_type import AdBudgetType
+from .ad_group_status import AdGroupStatus
__all__ = [
"AdGroupUpdateParams",
@@ -46,7 +48,7 @@ class AdGroupUpdateParams(TypedDict, total=False):
budget: Optional[float]
"""Budget amount in dollars."""
- budget_type: Optional[Literal["daily", "lifetime"]]
+ budget_type: Optional[AdBudgetType]
"""The budget type for an ad campaign or ad group."""
config: Optional[Config]
@@ -61,7 +63,7 @@ class AdGroupUpdateParams(TypedDict, total=False):
platform_config: Optional[PlatformConfig]
"""Platform-specific ad group configuration."""
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]]
+ status: Optional[AdGroupStatus]
"""The status of an external ad group."""
diff --git a/src/whop_sdk/types/ad_list_params.py b/src/whop_sdk/types/ad_list_params.py
index 17c36e1b..febd6591 100644
--- a/src/whop_sdk/types/ad_list_params.py
+++ b/src/whop_sdk/types/ad_list_params.py
@@ -4,9 +4,10 @@
from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Literal, Annotated, TypedDict
+from typing_extensions import Annotated, TypedDict
from .._utils import PropertyInfo
+from .external_ad_status import ExternalAdStatus
__all__ = ["AdListParams"]
@@ -48,5 +49,5 @@ class AdListParams(TypedDict, total=False):
last: Optional[int]
"""Returns the last _n_ elements from the list."""
- status: Optional[Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]]
+ status: Optional[ExternalAdStatus]
"""The status of an external ad."""
diff --git a/src/whop_sdk/types/ad_list_response.py b/src/whop_sdk/types/ad_list_response.py
index 2982e4b1..f6a13bac 100644
--- a/src/whop_sdk/types/ad_list_response.py
+++ b/src/whop_sdk/types/ad_list_response.py
@@ -2,11 +2,26 @@
from typing import Optional
from datetime import datetime
-from typing_extensions import Literal
from .._models import BaseModel
+from .external_ad_status import ExternalAdStatus
+from .ad_campaign_platform import AdCampaignPlatform
-__all__ = ["AdListResponse"]
+__all__ = ["AdListResponse", "AdCampaign", "AdGroup"]
+
+
+class AdCampaign(BaseModel):
+ """The ad campaign this ad belongs to."""
+
+ id: str
+ """The unique identifier for this ad campaign."""
+
+
+class AdGroup(BaseModel):
+ """The parent ad group this ad belongs to."""
+
+ id: str
+ """The unique identifier for this ad group."""
class AdListResponse(BaseModel):
@@ -15,13 +30,19 @@ class AdListResponse(BaseModel):
id: str
"""The unique identifier for this ad."""
+ ad_campaign: AdCampaign
+ """The ad campaign this ad belongs to."""
+
+ ad_group: AdGroup
+ """The parent ad group this ad belongs to."""
+
created_at: datetime
"""When the ad was created."""
- platform: Literal["meta", "tiktok"]
+ platform: AdCampaignPlatform
"""The external ad platform this ad is running on (e.g., meta, tiktok)."""
- status: Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]
+ status: ExternalAdStatus
"""Current delivery status of the ad."""
title: Optional[str] = None
diff --git a/src/whop_sdk/types/ad_report_retrieve_params.py b/src/whop_sdk/types/ad_report_retrieve_params.py
index 87fe683c..9a779523 100644
--- a/src/whop_sdk/types/ad_report_retrieve_params.py
+++ b/src/whop_sdk/types/ad_report_retrieve_params.py
@@ -4,9 +4,10 @@
from typing import Union, Optional
from datetime import datetime
-from typing_extensions import Required, Annotated, TypedDict
+from typing_extensions import Literal, Required, Annotated, TypedDict
from .._utils import PropertyInfo
+from .granularities import Granularities
__all__ = ["AdReportRetrieveParams"]
@@ -21,19 +22,30 @@ class AdReportRetrieveParams(TypedDict, total=False):
ad_campaign_id: Optional[str]
"""The unique identifier of an ad campaign.
- Mutually exclusive with `adGroupId` and `adId`.
+ Mutually exclusive with `companyId`, `adGroupId`, and `adId`.
"""
ad_group_id: Optional[str]
"""The unique identifier of an ad group.
- Mutually exclusive with `adCampaignId` and `adId`.
+ Mutually exclusive with `companyId`, `adCampaignId`, and `adId`.
"""
ad_id: Optional[str]
"""The unique identifier of an ad.
- Mutually exclusive with `adCampaignId` and `adGroupId`.
+ Mutually exclusive with `companyId`, `adCampaignId`, and `adGroupId`.
+ """
+
+ breakdown: Optional[Literal["campaign", "ad_group", "ad"]]
+ """Entity level to group an ad report by."""
+
+ company_id: Optional[str]
+ """The unique identifier of a company.
+
+ Mutually exclusive with `adCampaignId`, `adGroupId`, and `adId`. Use with
+ `breakdown` to fan out across every campaign, ad group, or ad in the company
+ without paging.
"""
currency: Optional[str]
@@ -42,5 +54,5 @@ class AdReportRetrieveParams(TypedDict, total=False):
Defaults to the company's ads reporting currency.
"""
- include_daily: Optional[bool]
- """When true, includes a per-day breakdown alongside the summary."""
+ granularity: Optional[Granularities]
+ """Bucket size for external ad stat rows."""
diff --git a/src/whop_sdk/types/ad_report_retrieve_response.py b/src/whop_sdk/types/ad_report_retrieve_response.py
index 9aaf6599..56bf2ef4 100644
--- a/src/whop_sdk/types/ad_report_retrieve_response.py
+++ b/src/whop_sdk/types/ad_report_retrieve_response.py
@@ -5,54 +5,52 @@
from typing_extensions import Literal
from .._models import BaseModel
+from .granularities import Granularities
from .shared.currency import Currency
+from .result_label_keys import ResultLabelKeys
-__all__ = ["AdReportRetrieveResponse", "Daily", "Summary"]
+__all__ = [
+ "AdReportRetrieveResponse",
+ "Breakdown",
+ "BreakdownGranularity",
+ "BreakdownSummary",
+ "Granularity",
+ "Summary",
+]
-class Daily(BaseModel):
- """Per-day ad performance for an ad campaign, ad group, or ad."""
+class BreakdownGranularity(BaseModel):
+ """Per-bucket ad performance for an ad campaign, ad group, or ad.
+
+ Bucket grain is set by the `ad_report` query's `granularity` argument.
+ """
+
+ bucket_start: datetime
+ """The bucket's start time as a real UTC instant.
+
+ `(statDate, statHour)` resolved in the ad account's reporting timezone — render
+ this in the viewer's local timezone.
+ """
clicks: int
- """Clicks on this date."""
+ """Clicks in this bucket."""
+
+ granularity: Granularities
+ """The bucket size of this row (`daily` or `hourly`)."""
impressions: int
- """Impressions on this date."""
+ """Impressions in this bucket."""
reach: int
- """Unique users reached on this date."""
+ """Unique users reached in this bucket.
+
+ Always `0` for hourly rows (Meta does not return reach at hourly grain).
+ """
result_count: Optional[int] = None
- """Count of the primary optimization result on this date."""
-
- result_label_key: Optional[
- Literal[
- "app_installs",
- "messaging_conversations_started",
- "post_engagement",
- "event_responses",
- "impressions",
- "website_purchases",
- "landing_page_views",
- "leads",
- "link_clicks",
- "quality_calls",
- "appointments_booked",
- "messaging_purchases",
- "page_likes",
- "instagram_profile_visits",
- "reach",
- "reminders_set",
- "new_subscribers",
- "video_views",
- "registrations",
- "content_views",
- "searches",
- "website_schedules",
- "website_submit_applications",
- "custom",
- ]
- ] = None
+ """Count of the primary optimization result in this bucket."""
+
+ result_label_key: Optional[ResultLabelKeys] = None
"""Types of optimization results tracked from external ad platforms"""
result_label_override: Optional[str] = None
@@ -60,7 +58,7 @@ class Daily(BaseModel):
spend: float
"""
- Charged spend on this date in the requested reporting currency — the amount
+ Charged spend in this bucket in the requested reporting currency — the amount
billed including platform fees, not the platform-side net spend.
"""
@@ -68,7 +66,153 @@ class Daily(BaseModel):
"""Currency of the `spend` value."""
stat_date: datetime
- """The date these stats cover (midnight UTC)."""
+ """The date these stats cover (midnight UTC).
+
+ For hourly rows, see `statHour` and `bucketStart`.
+ """
+
+ stat_hour: Optional[int] = None
+ """Hour of the day in the ad account's reporting timezone (0-23).
+
+ `null` for daily rows.
+ """
+
+
+class BreakdownSummary(BaseModel):
+ """Aggregate totals and rates for this entity over the date range."""
+
+ clicks: int
+ """Total clicks over the date range."""
+
+ cost_per_result: Optional[float] = None
+ """Spend divided by `resultCount`. Null when there are no results."""
+
+ cpc: float
+ """Cost per click in the requested reporting currency."""
+
+ cpm: Optional[float] = None
+ """Cost per thousand impressions in the requested reporting currency."""
+
+ ctr: float
+ """Click-through rate (clicks / impressions)."""
+
+ frequency: Optional[float] = None
+ """Average number of times each reached user saw an ad."""
+
+ impressions: int
+ """Total impressions over the date range."""
+
+ reach: int
+ """Unique users reached, deduplicated by the external ad platform."""
+
+ result_count: Optional[int] = None
+ """
+ Count of the campaign's primary optimization result (purchases, clicks, etc.) —
+ see `resultLabelKey`.
+ """
+
+ result_label_key: Optional[ResultLabelKeys] = None
+ """Types of optimization results tracked from external ad platforms"""
+
+ result_label_override: Optional[str] = None
+ """Advertiser-defined label for the result when `resultLabelKey` is `custom`."""
+
+ roas: Optional[float] = None
+ """
+ Alias for `purchaseRoas` — return on ad spend for purchases, as reported by the
+ external ad platform.
+ """
+
+ spend: float
+ """Total spend over the date range in the requested reporting currency."""
+
+ spend_currency: Optional[Currency] = None
+ """The available currencies on the platform"""
+
+
+class Breakdown(BaseModel):
+ """Per-entity ad performance row.
+
+ Returned when the `breakdown` arg on `adReport` is set.
+ """
+
+ id: str
+ """Tag of the entity (ad campaign, ad group, or ad)."""
+
+ granularity: Optional[List[BreakdownGranularity]] = None
+ """
+ Per-bucket time series for this entity over the date range, ordered ascending by
+ `bucketStart`. `null` when the `granularity` arg on `adReport` is omitted;
+ otherwise contains rows at the requested grain (`daily` or `hourly`).
+ """
+
+ level: Literal["campaign", "ad_group", "ad"]
+ """The entity level of this row — matches the `breakdown` arg."""
+
+ name: Optional[str] = None
+ """Display name of the entity, when available."""
+
+ summary: BreakdownSummary
+ """Aggregate totals and rates for this entity over the date range."""
+
+
+class Granularity(BaseModel):
+ """Per-bucket ad performance for an ad campaign, ad group, or ad.
+
+ Bucket grain is set by the `ad_report` query's `granularity` argument.
+ """
+
+ bucket_start: datetime
+ """The bucket's start time as a real UTC instant.
+
+ `(statDate, statHour)` resolved in the ad account's reporting timezone — render
+ this in the viewer's local timezone.
+ """
+
+ clicks: int
+ """Clicks in this bucket."""
+
+ granularity: Granularities
+ """The bucket size of this row (`daily` or `hourly`)."""
+
+ impressions: int
+ """Impressions in this bucket."""
+
+ reach: int
+ """Unique users reached in this bucket.
+
+ Always `0` for hourly rows (Meta does not return reach at hourly grain).
+ """
+
+ result_count: Optional[int] = None
+ """Count of the primary optimization result in this bucket."""
+
+ result_label_key: Optional[ResultLabelKeys] = None
+ """Types of optimization results tracked from external ad platforms"""
+
+ result_label_override: Optional[str] = None
+ """Advertiser-defined label for the result when `resultLabelKey` is `custom`."""
+
+ spend: float
+ """
+ Charged spend in this bucket in the requested reporting currency — the amount
+ billed including platform fees, not the platform-side net spend.
+ """
+
+ spend_currency: Currency
+ """Currency of the `spend` value."""
+
+ stat_date: datetime
+ """The date these stats cover (midnight UTC).
+
+ For hourly rows, see `statHour` and `bucketStart`.
+ """
+
+ stat_hour: Optional[int] = None
+ """Hour of the day in the ad account's reporting timezone (0-23).
+
+ `null` for daily rows.
+ """
class Summary(BaseModel):
@@ -104,34 +248,7 @@ class Summary(BaseModel):
see `resultLabelKey`.
"""
- result_label_key: Optional[
- Literal[
- "app_installs",
- "messaging_conversations_started",
- "post_engagement",
- "event_responses",
- "impressions",
- "website_purchases",
- "landing_page_views",
- "leads",
- "link_clicks",
- "quality_calls",
- "appointments_booked",
- "messaging_purchases",
- "page_likes",
- "instagram_profile_visits",
- "reach",
- "reminders_set",
- "new_subscribers",
- "video_views",
- "registrations",
- "content_views",
- "searches",
- "website_schedules",
- "website_submit_applications",
- "custom",
- ]
- ] = None
+ result_label_key: Optional[ResultLabelKeys] = None
"""Types of optimization results tracked from external ad platforms"""
result_label_override: Optional[str] = None
@@ -153,13 +270,22 @@ class Summary(BaseModel):
class AdReportRetrieveResponse(BaseModel):
"""An ads performance report.
- Returns a summary; daily breakdown is included when `includeDaily` is true.
+ Always returns a summary. The `granularity` field contains a per-bucket time series when the `granularity` arg is set; the `breakdown` field contains per-entity rows when the `breakdown` arg is set.
+ """
+
+ breakdown: Optional[List[Breakdown]] = None
+ """Per-entity rows over the date range.
+
+ `null` when the `breakdown` arg on `adReport` is omitted; otherwise contains one
+ row per ad campaign, ad group, or ad inside the requested scope at the requested
+ level.
"""
- daily: Optional[List[Daily]] = None
- """Per-day breakdown over the date range, ordered ascending.
+ granularity: Optional[List[Granularity]] = None
+ """Per-bucket time series over the date range, ordered ascending by `bucketStart`.
- Null when `includeDaily` is false.
+ `null` when the `granularity` arg on `adReport` is omitted; otherwise contains
+ rows at the requested grain (`daily` or `hourly`).
"""
summary: Summary
diff --git a/src/whop_sdk/types/dispute.py b/src/whop_sdk/types/dispute.py
index 59efd690..b093b0c2 100644
--- a/src/whop_sdk/types/dispute.py
+++ b/src/whop_sdk/types/dispute.py
@@ -154,8 +154,8 @@ class Payment(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
@@ -335,10 +335,7 @@ class Dispute(BaseModel):
"""
editable: Optional[bool] = None
- """Whether the dispute evidence can still be edited and submitted.
-
- Returns true only when the dispute status requires a response.
- """
+ """Whether the dispute evidence can still be edited and submitted."""
needs_response_by: Optional[datetime] = None
"""The deadline by which dispute evidence must be submitted.
diff --git a/src/whop_sdk/types/dispute_alert_created_webhook_event.py b/src/whop_sdk/types/dispute_alert_created_webhook_event.py
index e55b91df..5d527363 100644
--- a/src/whop_sdk/types/dispute_alert_created_webhook_event.py
+++ b/src/whop_sdk/types/dispute_alert_created_webhook_event.py
@@ -109,8 +109,8 @@ class DataPayment(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
diff --git a/src/whop_sdk/types/dispute_alert_retrieve_response.py b/src/whop_sdk/types/dispute_alert_retrieve_response.py
index af101035..a9d78ef8 100644
--- a/src/whop_sdk/types/dispute_alert_retrieve_response.py
+++ b/src/whop_sdk/types/dispute_alert_retrieve_response.py
@@ -100,8 +100,8 @@ class Payment(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
diff --git a/src/whop_sdk/types/dispute_list_response.py b/src/whop_sdk/types/dispute_list_response.py
index 11e58edd..46e665e2 100644
--- a/src/whop_sdk/types/dispute_list_response.py
+++ b/src/whop_sdk/types/dispute_list_response.py
@@ -74,10 +74,7 @@ class DisputeListResponse(BaseModel):
"""The three-letter ISO currency code for the disputed amount."""
editable: Optional[bool] = None
- """Whether the dispute evidence can still be edited and submitted.
-
- Returns true only when the dispute status requires a response.
- """
+ """Whether the dispute evidence can still be edited and submitted."""
needs_response_by: Optional[datetime] = None
"""The deadline by which dispute evidence must be submitted.
diff --git a/src/whop_sdk/types/external_ad_status.py b/src/whop_sdk/types/external_ad_status.py
new file mode 100644
index 00000000..1fa97884
--- /dev/null
+++ b/src/whop_sdk/types/external_ad_status.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["ExternalAdStatus"]
+
+ExternalAdStatus: TypeAlias = Literal["active", "paused", "inactive", "in_review", "rejected", "flagged"]
diff --git a/src/whop_sdk/types/file_create_params.py b/src/whop_sdk/types/file_create_params.py
index 6df14110..9419faf2 100644
--- a/src/whop_sdk/types/file_create_params.py
+++ b/src/whop_sdk/types/file_create_params.py
@@ -3,7 +3,9 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import Literal, Required, TypedDict
+from typing_extensions import Required, TypedDict
+
+from .file_visibility import FileVisibility
__all__ = ["FileCreateParams"]
@@ -15,7 +17,7 @@ class FileCreateParams(TypedDict, total=False):
"document.pdf").
"""
- visibility: Optional[Literal["public", "private"]]
+ visibility: Optional[FileVisibility]
"""
Controls whether an uploaded file is publicly accessible or requires
authentication to access.
diff --git a/src/whop_sdk/types/file_create_response.py b/src/whop_sdk/types/file_create_response.py
index 5c9e2fa4..b35c9d65 100644
--- a/src/whop_sdk/types/file_create_response.py
+++ b/src/whop_sdk/types/file_create_response.py
@@ -1,10 +1,10 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Dict, Optional
-from typing_extensions import Literal
from .._models import BaseModel
from .upload_status import UploadStatus
+from .file_visibility import FileVisibility
__all__ = ["FileCreateResponse"]
@@ -46,5 +46,5 @@ class FileCreateResponse(BaseModel):
signed URL that expires. Null if the file has not finished uploading.
"""
- visibility: Literal["public", "private"]
+ visibility: FileVisibility
"""Whether the file is publicly accessible or requires authentication."""
diff --git a/src/whop_sdk/types/file_retrieve_response.py b/src/whop_sdk/types/file_retrieve_response.py
index c60e895e..27e8b1c0 100644
--- a/src/whop_sdk/types/file_retrieve_response.py
+++ b/src/whop_sdk/types/file_retrieve_response.py
@@ -1,10 +1,10 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
-from typing_extensions import Literal
from .._models import BaseModel
from .upload_status import UploadStatus
+from .file_visibility import FileVisibility
__all__ = ["FileRetrieveResponse"]
@@ -34,5 +34,5 @@ class FileRetrieveResponse(BaseModel):
signed URL that expires. Null if the file has not finished uploading.
"""
- visibility: Literal["public", "private"]
+ visibility: FileVisibility
"""Whether the file is publicly accessible or requires authentication."""
diff --git a/src/whop_sdk/types/file_visibility.py b/src/whop_sdk/types/file_visibility.py
new file mode 100644
index 00000000..7ba3bae2
--- /dev/null
+++ b/src/whop_sdk/types/file_visibility.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["FileVisibility"]
+
+FileVisibility: TypeAlias = Literal["public", "private"]
diff --git a/src/whop_sdk/types/granularities.py b/src/whop_sdk/types/granularities.py
new file mode 100644
index 00000000..1a199166
--- /dev/null
+++ b/src/whop_sdk/types/granularities.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["Granularities"]
+
+Granularities: TypeAlias = Literal["daily", "hourly"]
diff --git a/src/whop_sdk/types/member_list_response.py b/src/whop_sdk/types/member_list_response.py
index e45faf1d..0b3476f9 100644
--- a/src/whop_sdk/types/member_list_response.py
+++ b/src/whop_sdk/types/member_list_response.py
@@ -44,7 +44,10 @@ class MemberListResponse(BaseModel):
"""
company_token_balance: float
- """The member's token balance for this company"""
+ """The member's token balance for this company.
+
+ Computed live from the ledger, not from a cache.
+ """
created_at: datetime
"""The datetime the company member was created."""
diff --git a/src/whop_sdk/types/member_retrieve_response.py b/src/whop_sdk/types/member_retrieve_response.py
index 6f428666..1f513422 100644
--- a/src/whop_sdk/types/member_retrieve_response.py
+++ b/src/whop_sdk/types/member_retrieve_response.py
@@ -60,7 +60,10 @@ class MemberRetrieveResponse(BaseModel):
"""The company for the member."""
company_token_balance: float
- """The member's token balance for this company"""
+ """The member's token balance for this company.
+
+ Computed live from the ledger, not from a cache.
+ """
created_at: datetime
"""The datetime the company member was created."""
diff --git a/src/whop_sdk/types/membership_list_response.py b/src/whop_sdk/types/membership_list_response.py
index 683d67d7..89bccb93 100644
--- a/src/whop_sdk/types/membership_list_response.py
+++ b/src/whop_sdk/types/membership_list_response.py
@@ -37,6 +37,12 @@ class Plan(BaseModel):
id: str
"""The unique identifier for the plan."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
class Product(BaseModel):
"""The product this membership grants access to."""
@@ -44,6 +50,12 @@ class Product(BaseModel):
id: str
"""The unique identifier for the product."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
title: str
"""
The display name of the product shown to customers on the product page and in
diff --git a/src/whop_sdk/types/payment_list_params.py b/src/whop_sdk/types/payment_list_params.py
index 1fcc2a22..16e0cee1 100644
--- a/src/whop_sdk/types/payment_list_params.py
+++ b/src/whop_sdk/types/payment_list_params.py
@@ -27,6 +27,9 @@ class PaymentListParams(TypedDict, total=False):
billing_reasons: Optional[List[BillingReasons]]
"""Filter payments by their billing reason."""
+ checkout_configuration_ids: Optional[SequenceNotStr[str]]
+ """Only return payments from these checkout configurations."""
+
company_id: Optional[str]
"""The unique identifier of the company to list payments for."""
diff --git a/src/whop_sdk/types/payment_list_response.py b/src/whop_sdk/types/payment_list_response.py
index 2af1a1d6..20991eb4 100644
--- a/src/whop_sdk/types/payment_list_response.py
+++ b/src/whop_sdk/types/payment_list_response.py
@@ -160,6 +160,12 @@ class Plan(BaseModel):
internal_notes: Optional[str] = None
"""A personal description or notes section for the business."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
class Product(BaseModel):
"""The product this payment was made for"""
@@ -167,6 +173,12 @@ class Product(BaseModel):
id: str
"""The unique identifier for the product."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
route: str
"""
The URL slug used in the product's public link (e.g., 'my-product' in
@@ -271,8 +283,8 @@ class PaymentListResponse(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
@@ -345,12 +357,8 @@ class PaymentListResponse(BaseModel):
otherwise false. Used to decide if Whop can attempt the charge again.
"""
- settlement_currency: str
- """
- The currency in which the creator receives payouts and fees are charged (e.g.,
- 'usd', 'eur'). For multi-currency payments this differs from the payment
- currency.
- """
+ settlement_currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
status: Optional[ReceiptStatus] = None
"""The status of a receipt"""
diff --git a/src/whop_sdk/types/plan_create_params.py b/src/whop_sdk/types/plan_create_params.py
index c0d6f89c..1a9d20b5 100644
--- a/src/whop_sdk/types/plan_create_params.py
+++ b/src/whop_sdk/types/plan_create_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import List, Iterable, Optional
+from typing import Dict, List, Iterable, Optional
from typing_extensions import Literal, Required, TypedDict
from .checkout_font import CheckoutFont
@@ -71,6 +71,13 @@ class PlanCreateParams(TypedDict, total=False):
legacy_payment_method_controls: Optional[bool]
"""Whether this plan uses legacy payment method controls."""
+ metadata: Optional[Dict[str, object]]
+ """Custom key-value pairs to store on the plan.
+
+ Included in webhook payloads for payment and membership events. Max 50 keys, 500
+ chars per key, 5000 chars per value.
+ """
+
override_tax_type: Optional[TaxType]
"""
Whether or not the tax is included in a plan's price (or if it hasn't been set
diff --git a/src/whop_sdk/types/plan_list_response.py b/src/whop_sdk/types/plan_list_response.py
index b034018e..08ab9df8 100644
--- a/src/whop_sdk/types/plan_list_response.py
+++ b/src/whop_sdk/types/plan_list_response.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 .._models import BaseModel
@@ -152,6 +152,12 @@ class PlanListResponse(BaseModel):
Only visible to authorized team members.
"""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
payment_method_configuration: Optional[PaymentMethodConfiguration] = None
"""
The explicit payment method configuration specifying which payment methods are
diff --git a/src/whop_sdk/types/plan_update_params.py b/src/whop_sdk/types/plan_update_params.py
index d150d067..6707cead 100644
--- a/src/whop_sdk/types/plan_update_params.py
+++ b/src/whop_sdk/types/plan_update_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import List, Iterable, Optional
+from typing import Dict, List, Iterable, Optional
from typing_extensions import Literal, Required, TypedDict
from .checkout_font import CheckoutFont
@@ -61,6 +61,13 @@ class PlanUpdateParams(TypedDict, total=False):
legacy_payment_method_controls: Optional[bool]
"""Whether this plan uses legacy payment method controls."""
+ metadata: Optional[Dict[str, object]]
+ """Custom key-value pairs to store on the plan.
+
+ Included in webhook payloads for payment and membership events. Max 50 keys, 500
+ chars per key, 5000 chars per value.
+ """
+
offer_cancel_discount: Optional[bool]
"""Whether to offer a retention discount when a customer attempts to cancel."""
diff --git a/src/whop_sdk/types/product_create_params.py b/src/whop_sdk/types/product_create_params.py
index ed4c851c..103fbc3d 100644
--- a/src/whop_sdk/types/product_create_params.py
+++ b/src/whop_sdk/types/product_create_params.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
@@ -69,6 +69,13 @@ class ProductCreateParams(TypedDict, total=False):
member_affiliate_status: Optional[GlobalAffiliateStatus]
"""The different statuses of the global affiliate program for a product."""
+ metadata: Optional[Dict[str, object]]
+ """Custom key-value pairs to store on the product.
+
+ Included in webhook payloads for payment and membership events. Max 50 keys, 500
+ chars per key, 5000 chars per value.
+ """
+
plan_options: Optional[PlanOptions]
"""Configuration for an automatically generated plan to attach to this product."""
diff --git a/src/whop_sdk/types/product_update_params.py b/src/whop_sdk/types/product_update_params.py
index 6082edf2..64a7c8c1 100644
--- a/src/whop_sdk/types/product_update_params.py
+++ b/src/whop_sdk/types/product_update_params.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Iterable, Optional
+from typing import Dict, Iterable, Optional
from typing_extensions import Required, TypedDict
from .shared.custom_cta import CustomCta
@@ -59,6 +59,13 @@ class ProductUpdateParams(TypedDict, total=False):
member_affiliate_status: Optional[GlobalAffiliateStatus]
"""The different statuses of the global affiliate program for a product."""
+ metadata: Optional[Dict[str, object]]
+ """Custom key-value pairs to store on the product.
+
+ Included in webhook payloads for payment and membership events. Max 50 keys, 500
+ chars per key, 5000 chars per value.
+ """
+
product_tax_code_id: Optional[str]
"""The unique identifier of the tax classification code to apply to this product."""
diff --git a/src/whop_sdk/types/refund_created_webhook_event.py b/src/whop_sdk/types/refund_created_webhook_event.py
index cd83e28c..ccf930c2 100644
--- a/src/whop_sdk/types/refund_created_webhook_event.py
+++ b/src/whop_sdk/types/refund_created_webhook_event.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import Dict, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -21,6 +21,8 @@
"DataPayment",
"DataPaymentMember",
"DataPaymentMembership",
+ "DataPaymentPlan",
+ "DataPaymentProduct",
"DataPaymentUser",
]
@@ -45,6 +47,32 @@ class DataPaymentMembership(BaseModel):
"""The state of the membership."""
+class DataPaymentPlan(BaseModel):
+ """The plan attached to this payment."""
+
+ id: str
+ """The unique identifier for the plan."""
+
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
+
+class DataPaymentProduct(BaseModel):
+ """The product this payment was made for"""
+
+ id: str
+ """The unique identifier for the product."""
+
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
+
class DataPaymentUser(BaseModel):
"""The user that made this payment."""
@@ -88,8 +116,8 @@ class DataPayment(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
@@ -100,6 +128,13 @@ class DataPayment(BaseModel):
membership: Optional[DataPaymentMembership] = None
"""The membership attached to this payment."""
+ metadata: Optional[Dict[str, object]] = None
+ """The custom metadata stored on this payment.
+
+ This will be copied over to the checkout configuration for which this payment
+ was made
+ """
+
paid_at: Optional[datetime] = None
"""The time at which this payment was successfully collected.
@@ -109,6 +144,12 @@ class DataPayment(BaseModel):
payment_method_type: Optional[PaymentMethodTypes] = None
"""The different types of payment methods that can be used."""
+ plan: Optional[DataPaymentPlan] = None
+ """The plan attached to this payment."""
+
+ product: Optional[DataPaymentProduct] = None
+ """The product this payment was made for"""
+
subtotal: Optional[float] = None
"""The subtotal to show to the creator (excluding buyer fees)."""
diff --git a/src/whop_sdk/types/refund_retrieve_response.py b/src/whop_sdk/types/refund_retrieve_response.py
index 973ec6c3..209d6d6d 100644
--- a/src/whop_sdk/types/refund_retrieve_response.py
+++ b/src/whop_sdk/types/refund_retrieve_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import Dict, Optional
from datetime import datetime
from .._models import BaseModel
@@ -14,7 +14,15 @@
from .refund_reference_status import RefundReferenceStatus
from .shared.membership_status import MembershipStatus
-__all__ = ["RefundRetrieveResponse", "Payment", "PaymentMember", "PaymentMembership", "PaymentUser"]
+__all__ = [
+ "RefundRetrieveResponse",
+ "Payment",
+ "PaymentMember",
+ "PaymentMembership",
+ "PaymentPlan",
+ "PaymentProduct",
+ "PaymentUser",
+]
class PaymentMember(BaseModel):
@@ -37,6 +45,32 @@ class PaymentMembership(BaseModel):
"""The state of the membership."""
+class PaymentPlan(BaseModel):
+ """The plan attached to this payment."""
+
+ id: str
+ """The unique identifier for the plan."""
+
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
+
+class PaymentProduct(BaseModel):
+ """The product this payment was made for"""
+
+ id: str
+ """The unique identifier for the product."""
+
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
+
class PaymentUser(BaseModel):
"""The user that made this payment."""
@@ -80,8 +114,8 @@ class Payment(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
@@ -92,6 +126,13 @@ class Payment(BaseModel):
membership: Optional[PaymentMembership] = None
"""The membership attached to this payment."""
+ metadata: Optional[Dict[str, object]] = None
+ """The custom metadata stored on this payment.
+
+ This will be copied over to the checkout configuration for which this payment
+ was made
+ """
+
paid_at: Optional[datetime] = None
"""The time at which this payment was successfully collected.
@@ -101,6 +142,12 @@ class Payment(BaseModel):
payment_method_type: Optional[PaymentMethodTypes] = None
"""The different types of payment methods that can be used."""
+ plan: Optional[PaymentPlan] = None
+ """The plan attached to this payment."""
+
+ product: Optional[PaymentProduct] = None
+ """The product this payment was made for"""
+
subtotal: Optional[float] = None
"""The subtotal to show to the creator (excluding buyer fees)."""
diff --git a/src/whop_sdk/types/refund_updated_webhook_event.py b/src/whop_sdk/types/refund_updated_webhook_event.py
index c7d7c86e..6650626c 100644
--- a/src/whop_sdk/types/refund_updated_webhook_event.py
+++ b/src/whop_sdk/types/refund_updated_webhook_event.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import Dict, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -21,6 +21,8 @@
"DataPayment",
"DataPaymentMember",
"DataPaymentMembership",
+ "DataPaymentPlan",
+ "DataPaymentProduct",
"DataPaymentUser",
]
@@ -45,6 +47,32 @@ class DataPaymentMembership(BaseModel):
"""The state of the membership."""
+class DataPaymentPlan(BaseModel):
+ """The plan attached to this payment."""
+
+ id: str
+ """The unique identifier for the plan."""
+
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
+
+class DataPaymentProduct(BaseModel):
+ """The product this payment was made for"""
+
+ id: str
+ """The unique identifier for the product."""
+
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
+
class DataPaymentUser(BaseModel):
"""The user that made this payment."""
@@ -88,8 +116,8 @@ class DataPayment(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
@@ -100,6 +128,13 @@ class DataPayment(BaseModel):
membership: Optional[DataPaymentMembership] = None
"""The membership attached to this payment."""
+ metadata: Optional[Dict[str, object]] = None
+ """The custom metadata stored on this payment.
+
+ This will be copied over to the checkout configuration for which this payment
+ was made
+ """
+
paid_at: Optional[datetime] = None
"""The time at which this payment was successfully collected.
@@ -109,6 +144,12 @@ class DataPayment(BaseModel):
payment_method_type: Optional[PaymentMethodTypes] = None
"""The different types of payment methods that can be used."""
+ plan: Optional[DataPaymentPlan] = None
+ """The plan attached to this payment."""
+
+ product: Optional[DataPaymentProduct] = None
+ """The product this payment was made for"""
+
subtotal: Optional[float] = None
"""The subtotal to show to the creator (excluding buyer fees)."""
diff --git a/src/whop_sdk/types/resolution_center_case_platform_response.py b/src/whop_sdk/types/resolution_center_case_platform_response.py
index 0dce38a9..e039d6f0 100644
--- a/src/whop_sdk/types/resolution_center_case_platform_response.py
+++ b/src/whop_sdk/types/resolution_center_case_platform_response.py
@@ -5,5 +5,5 @@
__all__ = ["ResolutionCenterCasePlatformResponse"]
ResolutionCenterCasePlatformResponse: TypeAlias = Literal[
- "request_buyer_info", "request_merchant_info", "merchant_wins", "platform_refund", "merchant_refund"
+ "request_buyer_info", "request_merchant_info", "merchant_wins", "merchant_refund"
]
diff --git a/src/whop_sdk/types/result_label_keys.py b/src/whop_sdk/types/result_label_keys.py
new file mode 100644
index 00000000..4a4d4657
--- /dev/null
+++ b/src/whop_sdk/types/result_label_keys.py
@@ -0,0 +1,32 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["ResultLabelKeys"]
+
+ResultLabelKeys: TypeAlias = Literal[
+ "app_installs",
+ "messaging_conversations_started",
+ "post_engagement",
+ "event_responses",
+ "impressions",
+ "website_purchases",
+ "landing_page_views",
+ "leads",
+ "link_clicks",
+ "quality_calls",
+ "appointments_booked",
+ "messaging_purchases",
+ "page_likes",
+ "instagram_profile_visits",
+ "reach",
+ "reminders_set",
+ "new_subscribers",
+ "video_views",
+ "registrations",
+ "content_views",
+ "searches",
+ "website_schedules",
+ "website_submit_applications",
+ "custom",
+]
diff --git a/src/whop_sdk/types/shared/membership.py b/src/whop_sdk/types/shared/membership.py
index c2bcea69..4f8d3fd0 100644
--- a/src/whop_sdk/types/shared/membership.py
+++ b/src/whop_sdk/types/shared/membership.py
@@ -50,6 +50,12 @@ class Plan(BaseModel):
id: str
"""The unique identifier for the plan."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
class Product(BaseModel):
"""The product this membership grants access to."""
@@ -57,6 +63,12 @@ class Product(BaseModel):
id: str
"""The unique identifier for the product."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
title: str
"""
The display name of the product shown to customers on the product page and in
diff --git a/src/whop_sdk/types/shared/payment.py b/src/whop_sdk/types/shared/payment.py
index bc9a6dcb..d424133c 100644
--- a/src/whop_sdk/types/shared/payment.py
+++ b/src/whop_sdk/types/shared/payment.py
@@ -114,10 +114,7 @@ class Dispute(BaseModel):
"""The three-letter ISO currency code for the disputed amount."""
editable: Optional[bool] = None
- """Whether the dispute evidence can still be edited and submitted.
-
- Returns true only when the dispute status requires a response.
- """
+ """Whether the dispute evidence can still be edited and submitted."""
needs_response_by: Optional[datetime] = None
"""The deadline by which dispute evidence must be submitted.
@@ -256,6 +253,12 @@ class Plan(BaseModel):
internal_notes: Optional[str] = None
"""A personal description or notes section for the business."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
class Product(BaseModel):
"""The product this payment was made for"""
@@ -263,6 +266,12 @@ class Product(BaseModel):
id: str
"""The unique identifier for the product."""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
route: str
"""
The URL slug used in the product's public link (e.g., 'my-product' in
@@ -409,8 +418,8 @@ class Payment(BaseModel):
created_at: datetime
"""The datetime the payment was created."""
- currency: Optional[Currency] = None
- """The available currencies on the platform"""
+ currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
dispute_alerted_at: Optional[datetime] = None
"""When an alert came in that this transaction will be disputed"""
@@ -510,22 +519,15 @@ class Payment(BaseModel):
settlement_amount: float
"""
- The payment amount in the creator's settlement currency (what the creator priced
- in). Equal to final_amount for single-currency payments.
+ The total amount charged to the customer for this payment, including taxes and
+ after any discounts. In the currency specified by the currency field.
"""
- settlement_currency: str
- """
- The currency in which the creator receives payouts and fees are charged (e.g.,
- 'usd', 'eur'). For multi-currency payments this differs from the payment
- currency.
- """
+ settlement_currency: Currency
+ """The three-letter ISO currency code for this payment (e.g., 'usd', 'eur')."""
settlement_exchange_rate: Optional[float] = None
- """
- The locked exchange rate used to convert from the buyer's payment currency to
- the creator's settlement currency. Null for single-currency payments.
- """
+ """Deprecated. Always returns null."""
status: Optional[ReceiptStatus] = None
"""The status of a receipt"""
diff --git a/src/whop_sdk/types/shared/plan.py b/src/whop_sdk/types/shared/plan.py
index c603ac95..7651e947 100644
--- a/src/whop_sdk/types/shared/plan.py
+++ b/src/whop_sdk/types/shared/plan.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 typing_extensions import Literal
@@ -188,6 +188,12 @@ class Plan(BaseModel):
Only visible to authorized team members.
"""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the plan.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
payment_method_configuration: Optional[PaymentMethodConfiguration] = None
"""
The explicit payment method configuration specifying which payment methods are
diff --git a/src/whop_sdk/types/shared/product.py b/src/whop_sdk/types/shared/product.py
index 5410a7c0..ce6299b8 100644
--- a/src/whop_sdk/types/shared/product.py
+++ b/src/whop_sdk/types/shared/product.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 typing_extensions import Literal
@@ -159,6 +159,12 @@ class Product(BaseModel):
Returns 0 if the company has disabled public member counts.
"""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
owner_user: OwnerUser
"""The user who owns the company that sells this product."""
diff --git a/src/whop_sdk/types/shared/product_list_item.py b/src/whop_sdk/types/shared/product_list_item.py
index e0afce7f..af1e59d5 100644
--- a/src/whop_sdk/types/shared/product_list_item.py
+++ b/src/whop_sdk/types/shared/product_list_item.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import Dict, Optional
from datetime import datetime
from ..._models import BaseModel
@@ -37,6 +37,12 @@ class ProductListItem(BaseModel):
Returns 0 if the company has disabled public member counts.
"""
+ metadata: Optional[Dict[str, object]] = None
+ """Custom key-value pairs stored on the product.
+
+ Included in webhook payloads for payment and membership events.
+ """
+
published_reviews_count: int
"""The total number of published customer reviews for this product's company."""
diff --git a/tests/api_resources/test_ad_campaigns.py b/tests/api_resources/test_ad_campaigns.py
index 63f382a7..cee5f625 100644
--- a/tests/api_resources/test_ad_campaigns.py
+++ b/tests/api_resources/test_ad_campaigns.py
@@ -10,11 +10,8 @@
from whop_sdk import Whop, AsyncWhop
from tests.utils import assert_matches_type
from whop_sdk.types import (
+ AdCampaign,
AdCampaignListResponse,
- AdCampaignPauseResponse,
- AdCampaignUpdateResponse,
- AdCampaignUnpauseResponse,
- AdCampaignRetrieveResponse,
)
from whop_sdk._utils import parse_datetime
from whop_sdk.pagination import SyncCursorPage, AsyncCursorPage
@@ -31,7 +28,7 @@ def test_method_retrieve(self, client: Whop) -> None:
ad_campaign = client.ad_campaigns.retrieve(
"adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignRetrieveResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -43,7 +40,7 @@ def test_raw_response_retrieve(self, client: Whop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignRetrieveResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -55,7 +52,7 @@ def test_streaming_response_retrieve(self, client: Whop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignRetrieveResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -73,7 +70,7 @@ def test_method_update(self, client: Whop) -> None:
ad_campaign = client.ad_campaigns.update(
id="adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -82,7 +79,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None:
id="adcamp_xxxxxxxxxxx",
budget=6.9,
)
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -94,7 +91,7 @@ def test_raw_response_update(self, client: Whop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -106,7 +103,7 @@ def test_streaming_response_update(self, client: Whop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -174,7 +171,7 @@ def test_method_pause(self, client: Whop) -> None:
ad_campaign = client.ad_campaigns.pause(
"adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignPauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -186,7 +183,7 @@ def test_raw_response_pause(self, client: Whop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignPauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -198,7 +195,7 @@ def test_streaming_response_pause(self, client: Whop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignPauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -216,7 +213,7 @@ def test_method_unpause(self, client: Whop) -> None:
ad_campaign = client.ad_campaigns.unpause(
"adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignUnpauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -228,7 +225,7 @@ def test_raw_response_unpause(self, client: Whop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignUnpauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -240,7 +237,7 @@ def test_streaming_response_unpause(self, client: Whop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = response.parse()
- assert_matches_type(AdCampaignUnpauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -264,7 +261,7 @@ async def test_method_retrieve(self, async_client: AsyncWhop) -> None:
ad_campaign = await async_client.ad_campaigns.retrieve(
"adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignRetrieveResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -276,7 +273,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncWhop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignRetrieveResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -288,7 +285,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncWhop) -> Non
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignRetrieveResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -306,7 +303,7 @@ async def test_method_update(self, async_client: AsyncWhop) -> None:
ad_campaign = await async_client.ad_campaigns.update(
id="adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -315,7 +312,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N
id="adcamp_xxxxxxxxxxx",
budget=6.9,
)
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -327,7 +324,7 @@ async def test_raw_response_update(self, async_client: AsyncWhop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -339,7 +336,7 @@ async def test_streaming_response_update(self, async_client: AsyncWhop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignUpdateResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -407,7 +404,7 @@ async def test_method_pause(self, async_client: AsyncWhop) -> None:
ad_campaign = await async_client.ad_campaigns.pause(
"adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignPauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -419,7 +416,7 @@ async def test_raw_response_pause(self, async_client: AsyncWhop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignPauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -431,7 +428,7 @@ async def test_streaming_response_pause(self, async_client: AsyncWhop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignPauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -449,7 +446,7 @@ async def test_method_unpause(self, async_client: AsyncWhop) -> None:
ad_campaign = await async_client.ad_campaigns.unpause(
"adcamp_xxxxxxxxxxx",
)
- assert_matches_type(AdCampaignUnpauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -461,7 +458,7 @@ async def test_raw_response_unpause(self, async_client: AsyncWhop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignUnpauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -473,7 +470,7 @@ async def test_streaming_response_unpause(self, async_client: AsyncWhop) -> None
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_campaign = await response.parse()
- assert_matches_type(AdCampaignUnpauseResponse, ad_campaign, path=["response"])
+ assert_matches_type(AdCampaign, ad_campaign, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_ad_groups.py b/tests/api_resources/test_ad_groups.py
index 038841b8..023fd6b5 100644
--- a/tests/api_resources/test_ad_groups.py
+++ b/tests/api_resources/test_ad_groups.py
@@ -10,10 +10,9 @@
from whop_sdk import Whop, AsyncWhop
from tests.utils import assert_matches_type
from whop_sdk.types import (
+ AdGroup,
AdGroupListResponse,
AdGroupDeleteResponse,
- AdGroupUpdateResponse,
- AdGroupRetrieveResponse,
)
from whop_sdk._utils import parse_datetime
from whop_sdk.pagination import SyncCursorPage, AsyncCursorPage
@@ -30,7 +29,7 @@ def test_method_retrieve(self, client: Whop) -> None:
ad_group = client.ad_groups.retrieve(
"adgrp_xxxxxxxxxxxx",
)
- assert_matches_type(AdGroupRetrieveResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -42,7 +41,7 @@ def test_raw_response_retrieve(self, client: Whop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = response.parse()
- assert_matches_type(AdGroupRetrieveResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -54,7 +53,7 @@ def test_streaming_response_retrieve(self, client: Whop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = response.parse()
- assert_matches_type(AdGroupRetrieveResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -72,7 +71,7 @@ def test_method_update(self, client: Whop) -> None:
ad_group = client.ad_groups.update(
id="adgrp_xxxxxxxxxxxx",
)
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -421,7 +420,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None:
},
status="active",
)
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -433,7 +432,7 @@ def test_raw_response_update(self, client: Whop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = response.parse()
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -445,7 +444,7 @@ def test_streaming_response_update(self, client: Whop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = response.parse()
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -544,6 +543,90 @@ def test_path_params_delete(self, client: Whop) -> None:
"",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_pause(self, client: Whop) -> None:
+ ad_group = client.ad_groups.pause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_pause(self, client: Whop) -> None:
+ response = client.ad_groups.with_raw_response.pause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad_group = response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_pause(self, client: Whop) -> None:
+ with client.ad_groups.with_streaming_response.pause(
+ "adgrp_xxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad_group = response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_pause(self, client: Whop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.ad_groups.with_raw_response.pause(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_unpause(self, client: Whop) -> None:
+ ad_group = client.ad_groups.unpause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_unpause(self, client: Whop) -> None:
+ response = client.ad_groups.with_raw_response.unpause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad_group = response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_unpause(self, client: Whop) -> None:
+ with client.ad_groups.with_streaming_response.unpause(
+ "adgrp_xxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad_group = response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_unpause(self, client: Whop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.ad_groups.with_raw_response.unpause(
+ "",
+ )
+
class TestAsyncAdGroups:
parametrize = pytest.mark.parametrize(
@@ -556,7 +639,7 @@ async def test_method_retrieve(self, async_client: AsyncWhop) -> None:
ad_group = await async_client.ad_groups.retrieve(
"adgrp_xxxxxxxxxxxx",
)
- assert_matches_type(AdGroupRetrieveResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -568,7 +651,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncWhop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = await response.parse()
- assert_matches_type(AdGroupRetrieveResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -580,7 +663,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncWhop) -> Non
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = await response.parse()
- assert_matches_type(AdGroupRetrieveResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -598,7 +681,7 @@ async def test_method_update(self, async_client: AsyncWhop) -> None:
ad_group = await async_client.ad_groups.update(
id="adgrp_xxxxxxxxxxxx",
)
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -947,7 +1030,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N
},
status="active",
)
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -959,7 +1042,7 @@ async def test_raw_response_update(self, async_client: AsyncWhop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = await response.parse()
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -971,7 +1054,7 @@ async def test_streaming_response_update(self, async_client: AsyncWhop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad_group = await response.parse()
- assert_matches_type(AdGroupUpdateResponse, ad_group, path=["response"])
+ assert_matches_type(AdGroup, ad_group, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -1069,3 +1152,87 @@ async def test_path_params_delete(self, async_client: AsyncWhop) -> None:
await async_client.ad_groups.with_raw_response.delete(
"",
)
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_pause(self, async_client: AsyncWhop) -> None:
+ ad_group = await async_client.ad_groups.pause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_pause(self, async_client: AsyncWhop) -> None:
+ response = await async_client.ad_groups.with_raw_response.pause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad_group = await response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_pause(self, async_client: AsyncWhop) -> None:
+ async with async_client.ad_groups.with_streaming_response.pause(
+ "adgrp_xxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad_group = await response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_pause(self, async_client: AsyncWhop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.ad_groups.with_raw_response.pause(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_unpause(self, async_client: AsyncWhop) -> None:
+ ad_group = await async_client.ad_groups.unpause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_unpause(self, async_client: AsyncWhop) -> None:
+ response = await async_client.ad_groups.with_raw_response.unpause(
+ "adgrp_xxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad_group = await response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_unpause(self, async_client: AsyncWhop) -> None:
+ async with async_client.ad_groups.with_streaming_response.unpause(
+ "adgrp_xxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad_group = await response.parse()
+ assert_matches_type(AdGroup, ad_group, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_unpause(self, async_client: AsyncWhop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.ad_groups.with_raw_response.unpause(
+ "",
+ )
diff --git a/tests/api_resources/test_ad_reports.py b/tests/api_resources/test_ad_reports.py
index ea37e037..a5b76624 100644
--- a/tests/api_resources/test_ad_reports.py
+++ b/tests/api_resources/test_ad_reports.py
@@ -36,8 +36,10 @@ def test_method_retrieve_with_all_params(self, client: Whop) -> None:
ad_campaign_id="ad_campaign_id",
ad_group_id="ad_group_id",
ad_id="ad_id",
+ breakdown="campaign",
+ company_id="biz_xxxxxxxxxxxxxx",
currency="currency",
- include_daily=True,
+ granularity="daily",
)
assert_matches_type(AdReportRetrieveResponse, ad_report, path=["response"])
@@ -93,8 +95,10 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncWhop) ->
ad_campaign_id="ad_campaign_id",
ad_group_id="ad_group_id",
ad_id="ad_id",
+ breakdown="campaign",
+ company_id="biz_xxxxxxxxxxxxxx",
currency="currency",
- include_daily=True,
+ granularity="daily",
)
assert_matches_type(AdReportRetrieveResponse, ad_report, path=["response"])
diff --git a/tests/api_resources/test_ads.py b/tests/api_resources/test_ads.py
index 68180402..2753ef42 100644
--- a/tests/api_resources/test_ads.py
+++ b/tests/api_resources/test_ads.py
@@ -9,7 +9,7 @@
from whop_sdk import Whop, AsyncWhop
from tests.utils import assert_matches_type
-from whop_sdk.types import AdListResponse, AdRetrieveResponse
+from whop_sdk.types import Ad, AdListResponse
from whop_sdk._utils import parse_datetime
from whop_sdk.pagination import SyncCursorPage, AsyncCursorPage
@@ -25,7 +25,7 @@ def test_method_retrieve(self, client: Whop) -> None:
ad = client.ads.retrieve(
"ad_xxxxxxxxxxxxxxx",
)
- assert_matches_type(AdRetrieveResponse, ad, path=["response"])
+ assert_matches_type(Ad, ad, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -37,7 +37,7 @@ def test_raw_response_retrieve(self, client: Whop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad = response.parse()
- assert_matches_type(AdRetrieveResponse, ad, path=["response"])
+ assert_matches_type(Ad, ad, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -49,7 +49,7 @@ def test_streaming_response_retrieve(self, client: Whop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad = response.parse()
- assert_matches_type(AdRetrieveResponse, ad, path=["response"])
+ assert_matches_type(Ad, ad, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -106,6 +106,90 @@ def test_streaming_response_list(self, client: Whop) -> None:
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_pause(self, client: Whop) -> None:
+ ad = client.ads.pause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_pause(self, client: Whop) -> None:
+ response = client.ads.with_raw_response.pause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad = response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_pause(self, client: Whop) -> None:
+ with client.ads.with_streaming_response.pause(
+ "ad_xxxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad = response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_pause(self, client: Whop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.ads.with_raw_response.pause(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_unpause(self, client: Whop) -> None:
+ ad = client.ads.unpause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_unpause(self, client: Whop) -> None:
+ response = client.ads.with_raw_response.unpause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad = response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_unpause(self, client: Whop) -> None:
+ with client.ads.with_streaming_response.unpause(
+ "ad_xxxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad = response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_unpause(self, client: Whop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.ads.with_raw_response.unpause(
+ "",
+ )
+
class TestAsyncAds:
parametrize = pytest.mark.parametrize(
@@ -118,7 +202,7 @@ async def test_method_retrieve(self, async_client: AsyncWhop) -> None:
ad = await async_client.ads.retrieve(
"ad_xxxxxxxxxxxxxxx",
)
- assert_matches_type(AdRetrieveResponse, ad, path=["response"])
+ assert_matches_type(Ad, ad, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -130,7 +214,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncWhop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad = await response.parse()
- assert_matches_type(AdRetrieveResponse, ad, path=["response"])
+ assert_matches_type(Ad, ad, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -142,7 +226,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncWhop) -> Non
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
ad = await response.parse()
- assert_matches_type(AdRetrieveResponse, ad, path=["response"])
+ assert_matches_type(Ad, ad, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -198,3 +282,87 @@ async def test_streaming_response_list(self, async_client: AsyncWhop) -> None:
assert_matches_type(AsyncCursorPage[AdListResponse], ad, path=["response"])
assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_pause(self, async_client: AsyncWhop) -> None:
+ ad = await async_client.ads.pause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_pause(self, async_client: AsyncWhop) -> None:
+ response = await async_client.ads.with_raw_response.pause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad = await response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_pause(self, async_client: AsyncWhop) -> None:
+ async with async_client.ads.with_streaming_response.pause(
+ "ad_xxxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad = await response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_pause(self, async_client: AsyncWhop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.ads.with_raw_response.pause(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_unpause(self, async_client: AsyncWhop) -> None:
+ ad = await async_client.ads.unpause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_unpause(self, async_client: AsyncWhop) -> None:
+ response = await async_client.ads.with_raw_response.unpause(
+ "ad_xxxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ad = await response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_unpause(self, async_client: AsyncWhop) -> None:
+ async with async_client.ads.with_streaming_response.unpause(
+ "ad_xxxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ad = await response.parse()
+ assert_matches_type(Ad, ad, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_unpause(self, async_client: AsyncWhop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.ads.with_raw_response.unpause(
+ "",
+ )
diff --git a/tests/api_resources/test_payments.py b/tests/api_resources/test_payments.py
index 628f7f75..fcdf8af8 100644
--- a/tests/api_resources/test_payments.py
+++ b/tests/api_resources/test_payments.py
@@ -217,6 +217,7 @@ def test_method_list_with_all_params(self, client: Whop) -> None:
after="after",
before="before",
billing_reasons=["subscription_create"],
+ checkout_configuration_ids=["string"],
company_id="biz_xxxxxxxxxxxxxx",
created_after=parse_datetime("2023-12-01T05:00:00.401Z"),
created_before=parse_datetime("2023-12-01T05:00:00.401Z"),
@@ -647,6 +648,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncWhop) -> Non
after="after",
before="before",
billing_reasons=["subscription_create"],
+ checkout_configuration_ids=["string"],
company_id="biz_xxxxxxxxxxxxxx",
created_after=parse_datetime("2023-12-01T05:00:00.401Z"),
created_before=parse_datetime("2023-12-01T05:00:00.401Z"),
diff --git a/tests/api_resources/test_plans.py b/tests/api_resources/test_plans.py
index fbe3db1b..ae35df9a 100644
--- a/tests/api_resources/test_plans.py
+++ b/tests/api_resources/test_plans.py
@@ -63,6 +63,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None:
initial_price=6.9,
internal_notes="internal_notes",
legacy_payment_method_controls=True,
+ metadata={"foo": "bar"},
override_tax_type="inclusive",
payment_method_configuration={
"disabled": ["acss_debit"],
@@ -189,6 +190,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None:
initial_price=6.9,
internal_notes="internal_notes",
legacy_payment_method_controls=True,
+ metadata={"foo": "bar"},
offer_cancel_discount=True,
override_tax_type="inclusive",
payment_method_configuration={
@@ -383,6 +385,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N
initial_price=6.9,
internal_notes="internal_notes",
legacy_payment_method_controls=True,
+ metadata={"foo": "bar"},
override_tax_type="inclusive",
payment_method_configuration={
"disabled": ["acss_debit"],
@@ -509,6 +512,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N
initial_price=6.9,
internal_notes="internal_notes",
legacy_payment_method_controls=True,
+ metadata={"foo": "bar"},
offer_cancel_discount=True,
override_tax_type="inclusive",
payment_method_configuration={
diff --git a/tests/api_resources/test_products.py b/tests/api_resources/test_products.py
index 19403ed1..b9a1c329 100644
--- a/tests/api_resources/test_products.py
+++ b/tests/api_resources/test_products.py
@@ -48,6 +48,7 @@ def test_method_create_with_all_params(self, client: Whop) -> None:
headline="headline",
member_affiliate_percentage=6.9,
member_affiliate_status="enabled",
+ metadata={"foo": "bar"},
plan_options={
"base_currency": "usd",
"billing_period": 42,
@@ -169,6 +170,7 @@ def test_method_update_with_all_params(self, client: Whop) -> None:
headline="headline",
member_affiliate_percentage=6.9,
member_affiliate_status="enabled",
+ metadata={"foo": "bar"},
product_tax_code_id="ptc_xxxxxxxxxxxxxx",
redirect_purchase_url="redirect_purchase_url",
route="route",
@@ -342,6 +344,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N
headline="headline",
member_affiliate_percentage=6.9,
member_affiliate_status="enabled",
+ metadata={"foo": "bar"},
plan_options={
"base_currency": "usd",
"billing_period": 42,
@@ -463,6 +466,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N
headline="headline",
member_affiliate_percentage=6.9,
member_affiliate_status="enabled",
+ metadata={"foo": "bar"},
product_tax_code_id="ptc_xxxxxxxxxxxxxx",
redirect_purchase_url="redirect_purchase_url",
route="route",