From 142b83f6f2e703f635a1cbf83400af6fba5fc419 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:24:56 +0000 Subject: [PATCH 01/14] feat(api): api update --- .stats.yml | 4 +- .../resources/broadcasts/broadcasts.py | 54 ++++++++++++++----- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/.stats.yml b/.stats.yml index d4b4e6b..7c37412 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-3a307b6fa4a6fc0199acbf0660fd1e5ca0ac68082b073b74dbd22e70f3a9ea6e.yml -openapi_spec_hash: a9a255215f69ae2c4abbef59b07f08ea +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-9672c8fdf00ad965526252003bd8aedee96dd9cff6a57efb79f42a4d0085c071.yml +openapi_spec_hash: e6e2307ad07db87f4c3ce852c691c818 config_hash: 70a26cd21f0ca1b34242677b831603db diff --git a/src/zavudev/resources/broadcasts/broadcasts.py b/src/zavudev/resources/broadcasts/broadcasts.py index 294ca65..4f2b2bd 100644 --- a/src/zavudev/resources/broadcasts/broadcasts.py +++ b/src/zavudev/resources/broadcasts/broadcasts.py @@ -513,12 +513,27 @@ def send( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BroadcastSendResponse: - """Start sending the broadcast immediately or schedule for later. - - Broadcasts go - through automated AI content review before sending. If the review passes, the - broadcast proceeds. If rejected, use PATCH to edit content, then call POST - /retry-review. Reserves the estimated cost from your balance. + """ + Start sending the broadcast immediately or schedule for later. + + **Verification is required to send, and there are two of them.** The team must + have completed both identity verification (KYC) and business verification (KYB); + passing one is not enough. Drafts can be created, edited and kept without + either. Every send path — dashboard, API and CLI alike — enforces both, + returning `403` with code `kyc_required` or `kyb_required` for whichever is + outstanding. + + **Review depends on the channel, and cannot be bypassed.** A draft is submitted + to automated content review here; it does not go straight out. A WhatsApp + broadcast built on a Meta-approved template skips review (Meta already vetted + the content) and begins sending. An email broadcast sends as soon as the + automated review passes. Every other channel moves to `pending_admin_review` and + waits for a person. If the review rejects it, use PATCH to edit the content then + call POST /retry-review. + + Calling this on a broadcast that is already `approved` or `scheduled` sends or + reschedules it directly, since it has already been reviewed. Reserves the + estimated cost from your balance. Args: scheduled_at: Schedule for future delivery. Omit to send immediately. @@ -1003,12 +1018,27 @@ async def send( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BroadcastSendResponse: - """Start sending the broadcast immediately or schedule for later. - - Broadcasts go - through automated AI content review before sending. If the review passes, the - broadcast proceeds. If rejected, use PATCH to edit content, then call POST - /retry-review. Reserves the estimated cost from your balance. + """ + Start sending the broadcast immediately or schedule for later. + + **Verification is required to send, and there are two of them.** The team must + have completed both identity verification (KYC) and business verification (KYB); + passing one is not enough. Drafts can be created, edited and kept without + either. Every send path — dashboard, API and CLI alike — enforces both, + returning `403` with code `kyc_required` or `kyb_required` for whichever is + outstanding. + + **Review depends on the channel, and cannot be bypassed.** A draft is submitted + to automated content review here; it does not go straight out. A WhatsApp + broadcast built on a Meta-approved template skips review (Meta already vetted + the content) and begins sending. An email broadcast sends as soon as the + automated review passes. Every other channel moves to `pending_admin_review` and + waits for a person. If the review rejects it, use PATCH to edit the content then + call POST /retry-review. + + Calling this on a broadcast that is already `approved` or `scheduled` sends or + reschedules it directly, since it has already been reviewed. Reserves the + estimated cost from your balance. Args: scheduled_at: Schedule for future delivery. Omit to send immediately. From 4219934a39d21c244328b7f64ab0554669eb06df Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 22:11:13 +0000 Subject: [PATCH 02/14] feat(api): api update --- .stats.yml | 4 +- src/zavudev/resources/senders/agent/tools.py | 8 ++- src/zavudev/resources/senders/senders.py | 60 +++++++++++++++++++ src/zavudev/types/sender_create_params.py | 17 +++++- src/zavudev/types/sender_update_params.py | 17 +++++- src/zavudev/types/sender_webhook.py | 18 ++++++ src/zavudev/types/senders/agent/agent_tool.py | 12 ++++ .../types/senders/agent/tool_create_params.py | 6 +- tests/api_resources/test_senders.py | 4 ++ 9 files changed, 139 insertions(+), 7 deletions(-) diff --git a/.stats.yml b/.stats.yml index 7c37412..8626f6f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-9672c8fdf00ad965526252003bd8aedee96dd9cff6a57efb79f42a4d0085c071.yml -openapi_spec_hash: e6e2307ad07db87f4c3ce852c691c818 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-892ed683498d6496c48ff8cda5b7ea069882d3f4462201c9fbe75ef5c37338ca.yml +openapi_spec_hash: 1884a0767683f4b7b96c474ef4bb72e7 config_hash: 70a26cd21f0ca1b34242677b831603db diff --git a/src/zavudev/resources/senders/agent/tools.py b/src/zavudev/resources/senders/agent/tools.py index bd916f5..11448ba 100644 --- a/src/zavudev/resources/senders/agent/tools.py +++ b/src/zavudev/resources/senders/agent/tools.py @@ -78,7 +78,9 @@ def create( Args: webhook_url: Must be HTTPS. - webhook_secret: Optional secret for webhook signature verification. + webhook_secret: Signing secret for the webhook. Optional: Zavu generates one when omitted and + returns it on this response only. Supply your own if you already have a secret + you want reused. extra_headers: Send extra headers @@ -377,7 +379,9 @@ async def create( Args: webhook_url: Must be HTTPS. - webhook_secret: Optional secret for webhook signature verification. + webhook_secret: Signing secret for the webhook. Optional: Zavu generates one when omitted and + returns it on this response only. Supply your own if you already have a secret + you want reused. extra_headers: Send extra headers diff --git a/src/zavudev/resources/senders/senders.py b/src/zavudev/resources/senders/senders.py index 0510e80..5abd856 100644 --- a/src/zavudev/resources/senders/senders.py +++ b/src/zavudev/resources/senders/senders.py @@ -95,6 +95,7 @@ def create( phone_number: str | Omit = omit, set_as_default: bool | Omit = omit, webhook_events: List[WebhookEvent] | Omit = omit, + webhook_signature_version: Literal["v1", "v1+v2", "v2"] | Omit = omit, webhook_url: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -137,6 +138,19 @@ def create( webhook_events: Events to subscribe to. + webhook_signature_version: Which `X-Zavu-Signature` scheme this receiver is sent. + + - `v1`: `v1=HMAC_SHA256(secret, body)`. The scheme used before this was + configurable. Existing webhooks stay on it until you move them. + - `v2`: `v2=HMAC_SHA256(secret, "{t}.{body}")`. The current scheme, and the + default for new senders. It signs the timestamp together with the body. + - `v1+v2`: both signatures, sharing one `t`. The migration setting: a receiver + reading either one works, so you can deploy and confirm your new verifier + before switching over. + + Moving from `v1` straight to `v2` returns `400`. Set `v1+v2` first. See + https://docs.zavu.dev/guides/receiving-messages/signature-migration + webhook_url: HTTPS URL for webhook events. extra_headers: Send extra headers @@ -161,6 +175,7 @@ def create( "phone_number": phone_number, "set_as_default": set_as_default, "webhook_events": webhook_events, + "webhook_signature_version": webhook_signature_version, "webhook_url": webhook_url, }, sender_create_params.SenderCreateParams, @@ -219,6 +234,7 @@ def update( set_as_default: bool | Omit = omit, webhook_active: bool | Omit = omit, webhook_events: List[WebhookEvent] | Omit = omit, + webhook_signature_version: Literal["v1", "v1+v2", "v2"] | Omit = omit, webhook_url: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -257,6 +273,19 @@ def update( webhook_events: Events to subscribe to. + webhook_signature_version: Which `X-Zavu-Signature` scheme this receiver is sent. + + - `v1`: `v1=HMAC_SHA256(secret, body)`. The scheme used before this was + configurable. Existing webhooks stay on it until you move them. + - `v2`: `v2=HMAC_SHA256(secret, "{t}.{body}")`. The current scheme, and the + default for new senders. It signs the timestamp together with the body. + - `v1+v2`: both signatures, sharing one `t`. The migration setting: a receiver + reading either one works, so you can deploy and confirm your new verifier + before switching over. + + Moving from `v1` straight to `v2` returns `400`. Set `v1+v2` first. See + https://docs.zavu.dev/guides/receiving-messages/signature-migration + webhook_url: HTTPS URL for webhook events. Set to null to remove webhook. extra_headers: Send extra headers @@ -284,6 +313,7 @@ def update( "set_as_default": set_as_default, "webhook_active": webhook_active, "webhook_events": webhook_events, + "webhook_signature_version": webhook_signature_version, "webhook_url": webhook_url, }, sender_update_params.SenderUpdateParams, @@ -595,6 +625,7 @@ async def create( phone_number: str | Omit = omit, set_as_default: bool | Omit = omit, webhook_events: List[WebhookEvent] | Omit = omit, + webhook_signature_version: Literal["v1", "v1+v2", "v2"] | Omit = omit, webhook_url: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -637,6 +668,19 @@ async def create( webhook_events: Events to subscribe to. + webhook_signature_version: Which `X-Zavu-Signature` scheme this receiver is sent. + + - `v1`: `v1=HMAC_SHA256(secret, body)`. The scheme used before this was + configurable. Existing webhooks stay on it until you move them. + - `v2`: `v2=HMAC_SHA256(secret, "{t}.{body}")`. The current scheme, and the + default for new senders. It signs the timestamp together with the body. + - `v1+v2`: both signatures, sharing one `t`. The migration setting: a receiver + reading either one works, so you can deploy and confirm your new verifier + before switching over. + + Moving from `v1` straight to `v2` returns `400`. Set `v1+v2` first. See + https://docs.zavu.dev/guides/receiving-messages/signature-migration + webhook_url: HTTPS URL for webhook events. extra_headers: Send extra headers @@ -661,6 +705,7 @@ async def create( "phone_number": phone_number, "set_as_default": set_as_default, "webhook_events": webhook_events, + "webhook_signature_version": webhook_signature_version, "webhook_url": webhook_url, }, sender_create_params.SenderCreateParams, @@ -719,6 +764,7 @@ async def update( set_as_default: bool | Omit = omit, webhook_active: bool | Omit = omit, webhook_events: List[WebhookEvent] | Omit = omit, + webhook_signature_version: Literal["v1", "v1+v2", "v2"] | Omit = omit, webhook_url: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -757,6 +803,19 @@ async def update( webhook_events: Events to subscribe to. + webhook_signature_version: Which `X-Zavu-Signature` scheme this receiver is sent. + + - `v1`: `v1=HMAC_SHA256(secret, body)`. The scheme used before this was + configurable. Existing webhooks stay on it until you move them. + - `v2`: `v2=HMAC_SHA256(secret, "{t}.{body}")`. The current scheme, and the + default for new senders. It signs the timestamp together with the body. + - `v1+v2`: both signatures, sharing one `t`. The migration setting: a receiver + reading either one works, so you can deploy and confirm your new verifier + before switching over. + + Moving from `v1` straight to `v2` returns `400`. Set `v1+v2` first. See + https://docs.zavu.dev/guides/receiving-messages/signature-migration + webhook_url: HTTPS URL for webhook events. Set to null to remove webhook. extra_headers: Send extra headers @@ -784,6 +843,7 @@ async def update( "set_as_default": set_as_default, "webhook_active": webhook_active, "webhook_events": webhook_events, + "webhook_signature_version": webhook_signature_version, "webhook_url": webhook_url, }, sender_update_params.SenderUpdateParams, diff --git a/src/zavudev/types/sender_create_params.py b/src/zavudev/types/sender_create_params.py index b17db04..8bfb662 100644 --- a/src/zavudev/types/sender_create_params.py +++ b/src/zavudev/types/sender_create_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import List -from typing_extensions import Required, Annotated, TypedDict +from typing_extensions import Literal, Required, Annotated, TypedDict from .._utils import PropertyInfo from .webhook_event import WebhookEvent @@ -65,5 +65,20 @@ class SenderCreateParams(TypedDict, total=False): webhook_events: Annotated[List[WebhookEvent], PropertyInfo(alias="webhookEvents")] """Events to subscribe to.""" + webhook_signature_version: Annotated[Literal["v1", "v1+v2", "v2"], PropertyInfo(alias="webhookSignatureVersion")] + """Which `X-Zavu-Signature` scheme this receiver is sent. + + - `v1`: `v1=HMAC_SHA256(secret, body)`. The scheme used before this was + configurable. Existing webhooks stay on it until you move them. + - `v2`: `v2=HMAC_SHA256(secret, "{t}.{body}")`. The current scheme, and the + default for new senders. It signs the timestamp together with the body. + - `v1+v2`: both signatures, sharing one `t`. The migration setting: a receiver + reading either one works, so you can deploy and confirm your new verifier + before switching over. + + Moving from `v1` straight to `v2` returns `400`. Set `v1+v2` first. See + https://docs.zavu.dev/guides/receiving-messages/signature-migration + """ + webhook_url: Annotated[str, PropertyInfo(alias="webhookUrl")] """HTTPS URL for webhook events.""" diff --git a/src/zavudev/types/sender_update_params.py b/src/zavudev/types/sender_update_params.py index 3b6d96a..3e7e87d 100644 --- a/src/zavudev/types/sender_update_params.py +++ b/src/zavudev/types/sender_update_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import List, Optional -from typing_extensions import Annotated, TypedDict +from typing_extensions import Literal, Annotated, TypedDict from .._utils import PropertyInfo from .webhook_event import WebhookEvent @@ -64,5 +64,20 @@ class SenderUpdateParams(TypedDict, total=False): webhook_events: Annotated[List[WebhookEvent], PropertyInfo(alias="webhookEvents")] """Events to subscribe to.""" + webhook_signature_version: Annotated[Literal["v1", "v1+v2", "v2"], PropertyInfo(alias="webhookSignatureVersion")] + """Which `X-Zavu-Signature` scheme this receiver is sent. + + - `v1`: `v1=HMAC_SHA256(secret, body)`. The scheme used before this was + configurable. Existing webhooks stay on it until you move them. + - `v2`: `v2=HMAC_SHA256(secret, "{t}.{body}")`. The current scheme, and the + default for new senders. It signs the timestamp together with the body. + - `v1+v2`: both signatures, sharing one `t`. The migration setting: a receiver + reading either one works, so you can deploy and confirm your new verifier + before switching over. + + Moving from `v1` straight to `v2` returns `400`. Set `v1+v2` first. See + https://docs.zavu.dev/guides/receiving-messages/signature-migration + """ + webhook_url: Annotated[Optional[str], PropertyInfo(alias="webhookUrl")] """HTTPS URL for webhook events. Set to null to remove webhook.""" diff --git a/src/zavudev/types/sender_webhook.py b/src/zavudev/types/sender_webhook.py index e6ef71c..4d07bab 100644 --- a/src/zavudev/types/sender_webhook.py +++ b/src/zavudev/types/sender_webhook.py @@ -1,6 +1,9 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo from .._models import BaseModel from .webhook_event import WebhookEvent @@ -17,6 +20,21 @@ class SenderWebhook(BaseModel): events: List[WebhookEvent] """List of events the webhook is subscribed to.""" + signature_version: Literal["v1", "v1+v2", "v2"] = FieldInfo(alias="signatureVersion") + """Which `X-Zavu-Signature` scheme this receiver is sent. + + - `v1`: `v1=HMAC_SHA256(secret, body)`. The scheme used before this was + configurable. Existing webhooks stay on it until you move them. + - `v2`: `v2=HMAC_SHA256(secret, "{t}.{body}")`. The current scheme, and the + default for new senders. It signs the timestamp together with the body. + - `v1+v2`: both signatures, sharing one `t`. The migration setting: a receiver + reading either one works, so you can deploy and confirm your new verifier + before switching over. + + Moving from `v1` straight to `v2` returns `400`. Set `v1+v2` first. See + https://docs.zavu.dev/guides/receiving-messages/signature-migration + """ + url: str """HTTPS URL that will receive webhook events.""" diff --git a/src/zavudev/types/senders/agent/agent_tool.py b/src/zavudev/types/senders/agent/agent_tool.py index 98fdfb5..5a62e91 100644 --- a/src/zavudev/types/senders/agent/agent_tool.py +++ b/src/zavudev/types/senders/agent/agent_tool.py @@ -1,5 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from typing import Optional from datetime import datetime from pydantic import Field as FieldInfo @@ -30,3 +31,14 @@ class AgentTool(BaseModel): webhook_url: str = FieldInfo(alias="webhookUrl") """HTTPS URL to call when the tool is executed.""" + + webhook_secret: Optional[str] = FieldInfo(alias="webhookSecret", default=None) + """Signing secret for this tool's webhook. + + **Returned only when the tool is created**, never on a later read. + + Zavu generates one if you do not supply it, and signs every call to this tool + with it: `X-Zavu-Signature: `, the HMAC-SHA256 of the request body. Verify + it before trusting the call. Lost it? Rotate with + `POST /v1/senders/{senderId}/agent/tools/{toolId}/webhook/secret`. + """ diff --git a/src/zavudev/types/senders/agent/tool_create_params.py b/src/zavudev/types/senders/agent/tool_create_params.py index 2f306ee..c1da1b9 100644 --- a/src/zavudev/types/senders/agent/tool_create_params.py +++ b/src/zavudev/types/senders/agent/tool_create_params.py @@ -23,4 +23,8 @@ class ToolCreateParams(TypedDict, total=False): enabled: bool webhook_secret: Annotated[str, PropertyInfo(alias="webhookSecret")] - """Optional secret for webhook signature verification.""" + """Signing secret for the webhook. + + Optional: Zavu generates one when omitted and returns it on this response only. + Supply your own if you already have a secret you want reused. + """ diff --git a/tests/api_resources/test_senders.py b/tests/api_resources/test_senders.py index 2683d35..91ae14a 100644 --- a/tests/api_resources/test_senders.py +++ b/tests/api_resources/test_senders.py @@ -46,6 +46,7 @@ def test_method_create_with_all_params(self, client: Zavudev) -> None: phone_number="phoneNumber", set_as_default=True, webhook_events=["message.queued"], + webhook_signature_version="v2", webhook_url="https://example.com", ) assert_matches_type(Sender, sender, path=["response"]) @@ -142,6 +143,7 @@ def test_method_update_with_all_params(self, client: Zavudev) -> None: set_as_default=True, webhook_active=True, webhook_events=["message.queued"], + webhook_signature_version="v2", webhook_url="https://example.com", ) assert_matches_type(Sender, sender, path=["response"]) @@ -477,6 +479,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncZavudev) - phone_number="phoneNumber", set_as_default=True, webhook_events=["message.queued"], + webhook_signature_version="v2", webhook_url="https://example.com", ) assert_matches_type(Sender, sender, path=["response"]) @@ -573,6 +576,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncZavudev) - set_as_default=True, webhook_active=True, webhook_events=["message.queued"], + webhook_signature_version="v2", webhook_url="https://example.com", ) assert_matches_type(Sender, sender, path=["response"]) From c92da9bfaba8125d1e0d3ce70067eccfdb538f9e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 8 Aug 2026 04:46:11 +0000 Subject: [PATCH 03/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8626f6f..7228ab6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-892ed683498d6496c48ff8cda5b7ea069882d3f4462201c9fbe75ef5c37338ca.yml -openapi_spec_hash: 1884a0767683f4b7b96c474ef4bb72e7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-02b9f038069495d4393c2e2c2656c56d902c73537212dbc75c983384ef328acf.yml +openapi_spec_hash: 7c74393cc7a3e514ba0fd481c83fc53b config_hash: 70a26cd21f0ca1b34242677b831603db From 5865991f97c6d500533d3178525eae3dfc2d5b0a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 8 Aug 2026 17:59:38 +0000 Subject: [PATCH 04/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 7228ab6..6b904bf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-02b9f038069495d4393c2e2c2656c56d902c73537212dbc75c983384ef328acf.yml -openapi_spec_hash: 7c74393cc7a3e514ba0fd481c83fc53b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-03646d6907027c09de7217fb9e31380612db62dca05c86075edd7aa10c8d52ed.yml +openapi_spec_hash: 4f5ad200aeb12ea6f3e1e8c3207eaf5f config_hash: 70a26cd21f0ca1b34242677b831603db From 9b7009ebf8feb54d716c24fec138eb8e06609b10 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 19:46:35 +0000 Subject: [PATCH 05/14] feat(api): api update --- .stats.yml | 4 ++-- src/zavudev/resources/phone_numbers.py | 10 ++++++++-- src/zavudev/types/phone_number_pricing.py | 7 ++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6b904bf..abf0c0c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-03646d6907027c09de7217fb9e31380612db62dca05c86075edd7aa10c8d52ed.yml -openapi_spec_hash: 4f5ad200aeb12ea6f3e1e8c3207eaf5f +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-43404ccf22ca6be7000adbd626e7b5eaecd517e7c43503c1b3d804340b41ae49.yml +openapi_spec_hash: 6b119a3213e324f3826453deca57f10b config_hash: 70a26cd21f0ca1b34242677b831603db diff --git a/src/zavudev/resources/phone_numbers.py b/src/zavudev/resources/phone_numbers.py index 61b71b1..cd0ee4a 100644 --- a/src/zavudev/resources/phone_numbers.py +++ b/src/zavudev/resources/phone_numbers.py @@ -203,7 +203,10 @@ def purchase( Requires a paid plan: the Free plan cannot purchase phone numbers and receives `402` with code `paid_plan_required`. Paid - plans include the first US number at no charge. + plans include one US number at no charge. The included number is one per account + and is granted once: claiming it spends the benefit for good, so releasing that + number does not make another one free, and numbers the account already bought do + not consume it. Args: phone_number: Phone number in E.164 format. @@ -540,7 +543,10 @@ async def purchase( Requires a paid plan: the Free plan cannot purchase phone numbers and receives `402` with code `paid_plan_required`. Paid - plans include the first US number at no charge. + plans include one US number at no charge. The included number is one per account + and is granted once: claiming it spends the benefit for good, so releasing that + number does not make another one free, and numbers the account already bought do + not consume it. Args: phone_number: Phone number in E.164 format. diff --git a/src/zavudev/types/phone_number_pricing.py b/src/zavudev/types/phone_number_pricing.py index 661b5ad..0dc1b8a 100644 --- a/src/zavudev/types/phone_number_pricing.py +++ b/src/zavudev/types/phone_number_pricing.py @@ -11,9 +11,10 @@ class PhoneNumberPricing(BaseModel): is_free_eligible: Optional[bool] = FieldInfo(alias="isFreeEligible", default=None) - """ - Whether this number qualifies as the plan-included first US number on paid - plans. + """Whether this number qualifies as the plan-included US number on paid plans. + + The benefit is one per account: it is never offered again once claimed, not even + after the number is released. """ monthly_price: Optional[float] = FieldInfo(alias="monthlyPrice", default=None) From f175b2ec7d84d605b6c2c38d79442a9b366317de Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:45:53 +0000 Subject: [PATCH 06/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index abf0c0c..4c021c1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-43404ccf22ca6be7000adbd626e7b5eaecd517e7c43503c1b3d804340b41ae49.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-722f1deadb9046d6c3dd01a7ea4022c276f4675bf24b56cd6cab6fe7f7b82d26.yml openapi_spec_hash: 6b119a3213e324f3826453deca57f10b -config_hash: 70a26cd21f0ca1b34242677b831603db +config_hash: 2cb79865930afed7a1592e2c19b61397 From d005ad27fdb3b572d597283fabd9f11d5d8415d4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:46:15 +0000 Subject: [PATCH 07/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 4c021c1..eafac8f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-722f1deadb9046d6c3dd01a7ea4022c276f4675bf24b56cd6cab6fe7f7b82d26.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-376a9a6c6be14b4fd16c9f62d7bafef25df560ffe79ca7085fd0ba8d70540267.yml openapi_spec_hash: 6b119a3213e324f3826453deca57f10b -config_hash: 2cb79865930afed7a1592e2c19b61397 +config_hash: 21a91c7ecc39df58cb3ee0779a5915ef From a1cfb1ee7a654d2650e795eee8fb226d24957a8c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:46:38 +0000 Subject: [PATCH 08/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index eafac8f..8413cc3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-376a9a6c6be14b4fd16c9f62d7bafef25df560ffe79ca7085fd0ba8d70540267.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-fa2ec1f359f9ed18ba4e00d8d1edb2a10a50c02b4efd9f20736cedbefb39cc47.yml openapi_spec_hash: 6b119a3213e324f3826453deca57f10b -config_hash: 21a91c7ecc39df58cb3ee0779a5915ef +config_hash: d5d02dfde2ea057fdcf5b26e3a921f7a From 0f863911b673b91defc3eccd9e96e88496c223b6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:50:13 +0000 Subject: [PATCH 09/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8413cc3..037d39e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-fa2ec1f359f9ed18ba4e00d8d1edb2a10a50c02b4efd9f20736cedbefb39cc47.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-ce051733263f4e5809b254dbe76a500eb4101355b294decac25dfd0b31509908.yml openapi_spec_hash: 6b119a3213e324f3826453deca57f10b -config_hash: d5d02dfde2ea057fdcf5b26e3a921f7a +config_hash: a541f8cf3cf7c3035a581a022d87dc0e From 1081ba2c32b2a584f2f9fcf3a0a1d82892150aa4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:50:35 +0000 Subject: [PATCH 10/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 037d39e..46aef62 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-ce051733263f4e5809b254dbe76a500eb4101355b294decac25dfd0b31509908.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-7e8b631015f94fd76c51f5c435bc3a22a858d1e40b89c0daf4ae8f1324412fa8.yml openapi_spec_hash: 6b119a3213e324f3826453deca57f10b -config_hash: a541f8cf3cf7c3035a581a022d87dc0e +config_hash: ef364b35e7dbd38ff92ce0ddaf429906 From b4f3f2bb7fb8f8b7d76dc75ab95751decf3e686c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:50:58 +0000 Subject: [PATCH 11/14] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 46aef62..754d90b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-7e8b631015f94fd76c51f5c435bc3a22a858d1e40b89c0daf4ae8f1324412fa8.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-86aec85be1021cea51f9fc0bb95248276c8b85e3ac0fd810490114599ed7cf00.yml openapi_spec_hash: 6b119a3213e324f3826453deca57f10b -config_hash: ef364b35e7dbd38ff92ce0ddaf429906 +config_hash: 7fca08d9dae18513f5d7451cea11e34c From 6d5a3ca83b4b43226a3309ac2f0a95f88f155cf8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 02:43:23 +0000 Subject: [PATCH 12/14] feat(api): api update --- .stats.yml | 4 +- src/zavudev/resources/functions/functions.py | 114 +++++++++++++++++- src/zavudev/types/function_create_params.py | 21 +++- src/zavudev/types/function_deploy_params.py | 21 +++- src/zavudev/types/function_deploy_response.py | 2 + .../types/function_get_deployment_response.py | 2 + src/zavudev/types/function_update_params.py | 21 +++- tests/api_resources/test_functions.py | 30 +++++ 8 files changed, 204 insertions(+), 11 deletions(-) diff --git a/.stats.yml b/.stats.yml index 754d90b..484237c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-86aec85be1021cea51f9fc0bb95248276c8b85e3ac0fd810490114599ed7cf00.yml -openapi_spec_hash: 6b119a3213e324f3826453deca57f10b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-21db15ab8c7fc4a95f96e62e9ae84d4db9696f41adf62806c9be4043268b0fad.yml +openapi_spec_hash: f5928b2d6fc0d6f10ea63acac9dead60 config_hash: 7fca08d9dae18513f5d7451cea11e34c diff --git a/src/zavudev/resources/functions/functions.py b/src/zavudev/resources/functions/functions.py index 6bef2dd..5b5e86f 100644 --- a/src/zavudev/resources/functions/functions.py +++ b/src/zavudev/resources/functions/functions.py @@ -69,6 +69,8 @@ def create( slug: str, dependencies: Dict[str, str] | Omit = omit, description: str | Omit = omit, + entrypoint: str | Omit = omit, + files: Dict[str, str] | Omit = omit, http_enabled: bool | Omit = omit, memory_mb: Literal[128, 256, 512, 1024] | Omit = omit, runtime: Literal["nodejs24"] | Omit = omit, @@ -95,11 +97,24 @@ def create( dependencies: npm dependencies. Keys are package names, values are semver ranges. + entrypoint: Which file in `files` is the entry point. Defaults to `index.ts`. + + files: The project's source files, keyed by path relative to the project root (e.g. + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + http_enabled: Whether to expose a public HTTPS URL for this function. runtime: Runtime the function is deployed on. - source_code: TypeScript source code for the function entry point (max ~900KB). + source_code: Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. timeout_sec: Per-invocation timeout in seconds. Event and cron invocations are asynchronous, so a long timeout only bounds cost; a tool called during a live conversation @@ -122,6 +137,8 @@ def create( "slug": slug, "dependencies": dependencies, "description": description, + "entrypoint": entrypoint, + "files": files, "http_enabled": http_enabled, "memory_mb": memory_mb, "runtime": runtime, @@ -174,6 +191,8 @@ def update( function_id: str, *, dependencies: Dict[str, str] | Omit = omit, + entrypoint: str | Omit = omit, + files: Dict[str, str] | Omit = omit, http_enabled: bool | Omit = omit, source_code: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -194,11 +213,24 @@ def update( Args: dependencies: New dependency map (replaces existing dependencies). + entrypoint: Which file in `files` is the entry point. Defaults to `index.ts`. + + files: The project's source files, keyed by path relative to the project root (e.g. + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + http_enabled: Expose the function on its public HTTPS URL, or take it down. Applies to the already-deployed function without redeploying; the URL is returned as `publicUrl`. - source_code: New source code for the draft (replaces it). + source_code: Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. extra_headers: Send extra headers @@ -215,6 +247,8 @@ def update( body=maybe_transform( { "dependencies": dependencies, + "entrypoint": entrypoint, + "files": files, "http_enabled": http_enabled, "source_code": source_code, }, @@ -266,6 +300,8 @@ def deploy( function_id: str, *, dependencies: Dict[str, str] | Omit = omit, + entrypoint: str | Omit = omit, + files: Dict[str, str] | Omit = omit, source_code: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -284,7 +320,20 @@ def deploy( Args: dependencies: New dependency map (replaces existing dependencies). - source_code: New source code to publish (replaces the draft). + entrypoint: Which file in `files` is the entry point. Defaults to `index.ts`. + + files: The project's source files, keyed by path relative to the project root (e.g. + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + + source_code: Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. extra_headers: Send extra headers @@ -301,6 +350,8 @@ def deploy( body=maybe_transform( { "dependencies": dependencies, + "entrypoint": entrypoint, + "files": files, "source_code": source_code, }, function_deploy_params.FunctionDeployParams, @@ -434,6 +485,8 @@ async def create( slug: str, dependencies: Dict[str, str] | Omit = omit, description: str | Omit = omit, + entrypoint: str | Omit = omit, + files: Dict[str, str] | Omit = omit, http_enabled: bool | Omit = omit, memory_mb: Literal[128, 256, 512, 1024] | Omit = omit, runtime: Literal["nodejs24"] | Omit = omit, @@ -460,11 +513,24 @@ async def create( dependencies: npm dependencies. Keys are package names, values are semver ranges. + entrypoint: Which file in `files` is the entry point. Defaults to `index.ts`. + + files: The project's source files, keyed by path relative to the project root (e.g. + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + http_enabled: Whether to expose a public HTTPS URL for this function. runtime: Runtime the function is deployed on. - source_code: TypeScript source code for the function entry point (max ~900KB). + source_code: Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. timeout_sec: Per-invocation timeout in seconds. Event and cron invocations are asynchronous, so a long timeout only bounds cost; a tool called during a live conversation @@ -487,6 +553,8 @@ async def create( "slug": slug, "dependencies": dependencies, "description": description, + "entrypoint": entrypoint, + "files": files, "http_enabled": http_enabled, "memory_mb": memory_mb, "runtime": runtime, @@ -539,6 +607,8 @@ async def update( function_id: str, *, dependencies: Dict[str, str] | Omit = omit, + entrypoint: str | Omit = omit, + files: Dict[str, str] | Omit = omit, http_enabled: bool | Omit = omit, source_code: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -559,11 +629,24 @@ async def update( Args: dependencies: New dependency map (replaces existing dependencies). + entrypoint: Which file in `files` is the entry point. Defaults to `index.ts`. + + files: The project's source files, keyed by path relative to the project root (e.g. + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + http_enabled: Expose the function on its public HTTPS URL, or take it down. Applies to the already-deployed function without redeploying; the URL is returned as `publicUrl`. - source_code: New source code for the draft (replaces it). + source_code: Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. extra_headers: Send extra headers @@ -580,6 +663,8 @@ async def update( body=await async_maybe_transform( { "dependencies": dependencies, + "entrypoint": entrypoint, + "files": files, "http_enabled": http_enabled, "source_code": source_code, }, @@ -631,6 +716,8 @@ async def deploy( function_id: str, *, dependencies: Dict[str, str] | Omit = omit, + entrypoint: str | Omit = omit, + files: Dict[str, str] | Omit = omit, source_code: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -649,7 +736,20 @@ async def deploy( Args: dependencies: New dependency map (replaces existing dependencies). - source_code: New source code to publish (replaces the draft). + entrypoint: Which file in `files` is the entry point. Defaults to `index.ts`. + + files: The project's source files, keyed by path relative to the project root (e.g. + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + + source_code: Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. extra_headers: Send extra headers @@ -666,6 +766,8 @@ async def deploy( body=await async_maybe_transform( { "dependencies": dependencies, + "entrypoint": entrypoint, + "files": files, "source_code": source_code, }, function_deploy_params.FunctionDeployParams, diff --git a/src/zavudev/types/function_create_params.py b/src/zavudev/types/function_create_params.py index 336a028..38f9026 100644 --- a/src/zavudev/types/function_create_params.py +++ b/src/zavudev/types/function_create_params.py @@ -21,6 +21,21 @@ class FunctionCreateParams(TypedDict, total=False): description: str + entrypoint: str + """Which file in `files` is the entry point. Defaults to `index.ts`.""" + + files: Dict[str, str] + """The project's source files, keyed by path relative to the project root (e.g. + + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + """ + http_enabled: Annotated[bool, PropertyInfo(alias="httpEnabled")] """Whether to expose a public HTTPS URL for this function.""" @@ -30,7 +45,11 @@ class FunctionCreateParams(TypedDict, total=False): """Runtime the function is deployed on.""" source_code: Annotated[str, PropertyInfo(alias="sourceCode")] - """TypeScript source code for the function entry point (max ~900KB).""" + """ + Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. + """ timeout_sec: Annotated[int, PropertyInfo(alias="timeoutSec")] """Per-invocation timeout in seconds. diff --git a/src/zavudev/types/function_deploy_params.py b/src/zavudev/types/function_deploy_params.py index cfc6d80..cf7d143 100644 --- a/src/zavudev/types/function_deploy_params.py +++ b/src/zavudev/types/function_deploy_params.py @@ -14,5 +14,24 @@ class FunctionDeployParams(TypedDict, total=False): dependencies: Dict[str, str] """New dependency map (replaces existing dependencies).""" + entrypoint: str + """Which file in `files` is the entry point. Defaults to `index.ts`.""" + + files: Dict[str, str] + """The project's source files, keyed by path relative to the project root (e.g. + + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + """ + source_code: Annotated[str, PropertyInfo(alias="sourceCode")] - """New source code to publish (replaces the draft).""" + """ + Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. + """ diff --git a/src/zavudev/types/function_deploy_response.py b/src/zavudev/types/function_deploy_response.py index 3aea2b0..42ed579 100644 --- a/src/zavudev/types/function_deploy_response.py +++ b/src/zavudev/types/function_deploy_response.py @@ -25,6 +25,7 @@ class Deployment(BaseModel): """Monotonically increasing deployment version, starting at 1.""" bundle_bytes: Optional[int] = FieldInfo(alias="bundleBytes", default=None) + """Size of the built bundle in bytes. Null until the build finishes.""" deployed_at: Optional[datetime] = FieldInfo(alias="deployedAt", default=None) @@ -32,6 +33,7 @@ class Deployment(BaseModel): """Failure reason when status is 'failed'.""" source_code_bytes: Optional[int] = FieldInfo(alias="sourceCodeBytes", default=None) + """Total size of the deployed source tree in bytes.""" class FunctionDeployResponse(BaseModel): diff --git a/src/zavudev/types/function_get_deployment_response.py b/src/zavudev/types/function_get_deployment_response.py index 1da6db7..612d626 100644 --- a/src/zavudev/types/function_get_deployment_response.py +++ b/src/zavudev/types/function_get_deployment_response.py @@ -25,6 +25,7 @@ class Deployment(BaseModel): """Monotonically increasing deployment version, starting at 1.""" bundle_bytes: Optional[int] = FieldInfo(alias="bundleBytes", default=None) + """Size of the built bundle in bytes. Null until the build finishes.""" deployed_at: Optional[datetime] = FieldInfo(alias="deployedAt", default=None) @@ -32,6 +33,7 @@ class Deployment(BaseModel): """Failure reason when status is 'failed'.""" source_code_bytes: Optional[int] = FieldInfo(alias="sourceCodeBytes", default=None) + """Total size of the deployed source tree in bytes.""" class FunctionGetDeploymentResponse(BaseModel): diff --git a/src/zavudev/types/function_update_params.py b/src/zavudev/types/function_update_params.py index 65a687b..85a732d 100644 --- a/src/zavudev/types/function_update_params.py +++ b/src/zavudev/types/function_update_params.py @@ -14,6 +14,21 @@ class FunctionUpdateParams(TypedDict, total=False): dependencies: Dict[str, str] """New dependency map (replaces existing dependencies).""" + entrypoint: str + """Which file in `files` is the entry point. Defaults to `index.ts`.""" + + files: Dict[str, str] + """The project's source files, keyed by path relative to the project root (e.g. + + `index.ts`, `lib/orders.ts`). Imports between them are resolved when the + function is built, so a function can be split across as many files as it needs. + + Paths must be relative and use forward slashes; `..`, `node_modules/` and + `package.json` are rejected. npm packages are not uploaded here — declare them + under `dependencies` and Zavu installs them. Limits: 200 files and 900,000 bytes + for the whole tree. + """ + http_enabled: Annotated[bool, PropertyInfo(alias="httpEnabled")] """Expose the function on its public HTTPS URL, or take it down. @@ -22,4 +37,8 @@ class FunctionUpdateParams(TypedDict, total=False): """ source_code: Annotated[str, PropertyInfo(alias="sourceCode")] - """New source code for the draft (replaces it).""" + """ + Shortcut for a single-file function: exactly equivalent to sending `files` with + one entry named after `entrypoint` (`index.ts` by default). Fully supported — + use whichever fits. If both are sent, `files` wins. + """ diff --git a/tests/api_resources/test_functions.py b/tests/api_resources/test_functions.py index 140fae2..162babc 100644 --- a/tests/api_resources/test_functions.py +++ b/tests/api_resources/test_functions.py @@ -42,6 +42,11 @@ def test_method_create_with_all_params(self, client: Zavudev) -> None: slug="order-bot", dependencies={"openai": "^4.20.0"}, description="Replies to order status questions on WhatsApp.", + entrypoint="index.ts", + files={ + "index.ts": "import { formatOrder } from './lib/orders';\n\nexport default async function handler(event) {\n return { statusCode: 200, body: formatOrder(event) };\n}\n", + "lib/orders.ts": "export function formatOrder(event) {\n return JSON.stringify(event);\n}\n", + }, http_enabled=True, memory_mb=128, runtime="nodejs24", @@ -134,6 +139,11 @@ def test_method_update_with_all_params(self, client: Zavudev) -> None: function = client.functions.update( function_id="functionId", dependencies={"foo": "string"}, + entrypoint="index.ts", + files={ + "index.ts": "import { formatOrder } from './lib/orders';\n\nexport default async function handler(event) {\n return { statusCode: 200, body: formatOrder(event) };\n}\n", + "lib/orders.ts": "export function formatOrder(event) {\n return JSON.stringify(event);\n}\n", + }, http_enabled=True, source_code="sourceCode", ) @@ -229,6 +239,11 @@ def test_method_deploy_with_all_params(self, client: Zavudev) -> None: function = client.functions.deploy( function_id="functionId", dependencies={"foo": "string"}, + entrypoint="index.ts", + files={ + "index.ts": "import { formatOrder } from './lib/orders';\n\nexport default async function handler(event) {\n return { statusCode: 200, body: formatOrder(event) };\n}\n", + "lib/orders.ts": "export function formatOrder(event) {\n return JSON.stringify(event);\n}\n", + }, source_code="sourceCode", ) assert_matches_type(FunctionDeployResponse, function, path=["response"]) @@ -387,6 +402,11 @@ async def test_method_create_with_all_params(self, async_client: AsyncZavudev) - slug="order-bot", dependencies={"openai": "^4.20.0"}, description="Replies to order status questions on WhatsApp.", + entrypoint="index.ts", + files={ + "index.ts": "import { formatOrder } from './lib/orders';\n\nexport default async function handler(event) {\n return { statusCode: 200, body: formatOrder(event) };\n}\n", + "lib/orders.ts": "export function formatOrder(event) {\n return JSON.stringify(event);\n}\n", + }, http_enabled=True, memory_mb=128, runtime="nodejs24", @@ -479,6 +499,11 @@ async def test_method_update_with_all_params(self, async_client: AsyncZavudev) - function = await async_client.functions.update( function_id="functionId", dependencies={"foo": "string"}, + entrypoint="index.ts", + files={ + "index.ts": "import { formatOrder } from './lib/orders';\n\nexport default async function handler(event) {\n return { statusCode: 200, body: formatOrder(event) };\n}\n", + "lib/orders.ts": "export function formatOrder(event) {\n return JSON.stringify(event);\n}\n", + }, http_enabled=True, source_code="sourceCode", ) @@ -574,6 +599,11 @@ async def test_method_deploy_with_all_params(self, async_client: AsyncZavudev) - function = await async_client.functions.deploy( function_id="functionId", dependencies={"foo": "string"}, + entrypoint="index.ts", + files={ + "index.ts": "import { formatOrder } from './lib/orders';\n\nexport default async function handler(event) {\n return { statusCode: 200, body: formatOrder(event) };\n}\n", + "lib/orders.ts": "export function formatOrder(event) {\n return JSON.stringify(event);\n}\n", + }, source_code="sourceCode", ) assert_matches_type(FunctionDeployResponse, function, path=["response"]) From f90d54e6f49ebed82447a815d8c80aecc023b937 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 03:47:59 +0000 Subject: [PATCH 13/14] feat(api): api update --- .stats.yml | 4 ++-- src/zavudev/types/function_deploy_response.py | 9 +++++++++ src/zavudev/types/function_get_deployment_response.py | 9 +++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 484237c..0b60fcc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 138 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-21db15ab8c7fc4a95f96e62e9ae84d4db9696f41adf62806c9be4043268b0fad.yml -openapi_spec_hash: f5928b2d6fc0d6f10ea63acac9dead60 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-e4987140138afb7287e25f31dc8cff94c6b11975e460e0c19d54ec457d009a1b.yml +openapi_spec_hash: d20e1b8d0a9a7a65dc8a21e3a151111e config_hash: 7fca08d9dae18513f5d7451cea11e34c diff --git a/src/zavudev/types/function_deploy_response.py b/src/zavudev/types/function_deploy_response.py index 42ed579..4622399 100644 --- a/src/zavudev/types/function_deploy_response.py +++ b/src/zavudev/types/function_deploy_response.py @@ -24,6 +24,15 @@ class Deployment(BaseModel): version: int """Monotonically increasing deployment version, starting at 1.""" + build_logs: Optional[str] = FieldInfo(alias="buildLogs", default=None) + """ + What the build printed: dependency installation, the bundler's output, and the + compiler's message when it failed. Returned when fetching a single deployment, + omitted from the list. Read this first when a deploy fails — `errorMessage` is + often the outer wrapper's summary, and the line that names the broken import or + the syntax error is here. + """ + bundle_bytes: Optional[int] = FieldInfo(alias="bundleBytes", default=None) """Size of the built bundle in bytes. Null until the build finishes.""" diff --git a/src/zavudev/types/function_get_deployment_response.py b/src/zavudev/types/function_get_deployment_response.py index 612d626..c0301bc 100644 --- a/src/zavudev/types/function_get_deployment_response.py +++ b/src/zavudev/types/function_get_deployment_response.py @@ -24,6 +24,15 @@ class Deployment(BaseModel): version: int """Monotonically increasing deployment version, starting at 1.""" + build_logs: Optional[str] = FieldInfo(alias="buildLogs", default=None) + """ + What the build printed: dependency installation, the bundler's output, and the + compiler's message when it failed. Returned when fetching a single deployment, + omitted from the list. Read this first when a deploy fails — `errorMessage` is + often the outer wrapper's summary, and the line that names the broken import or + the syntax error is here. + """ + bundle_bytes: Optional[int] = FieldInfo(alias="bundleBytes", default=None) """Size of the built bundle in bytes. Null until the build finishes.""" From 144728f999be3e0f53e396c3e79aaaff12f163f6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 03:48:22 +0000 Subject: [PATCH 14/14] release: 0.49.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 12 ++++++++++++ pyproject.toml | 2 +- src/zavudev/_version.py | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ff66120..dd7ced1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.48.0" + ".": "0.49.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f02dd90..d09a2ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.49.0 (2026-08-11) + +Full Changelog: [v0.48.0...v0.49.0](https://github.com/zavudev/sdk-python/compare/v0.48.0...v0.49.0) + +### Features + +* **api:** api update ([f90d54e](https://github.com/zavudev/sdk-python/commit/f90d54e6f49ebed82447a815d8c80aecc023b937)) +* **api:** api update ([6d5a3ca](https://github.com/zavudev/sdk-python/commit/6d5a3ca83b4b43226a3309ac2f0a95f88f155cf8)) +* **api:** api update ([9b7009e](https://github.com/zavudev/sdk-python/commit/9b7009ebf8feb54d716c24fec138eb8e06609b10)) +* **api:** api update ([4219934](https://github.com/zavudev/sdk-python/commit/4219934a39d21c244328b7f64ab0554669eb06df)) +* **api:** api update ([142b83f](https://github.com/zavudev/sdk-python/commit/142b83f6f2e703f635a1cbf83400af6fba5fc419)) + ## 0.48.0 (2026-08-05) Full Changelog: [v0.47.0...v0.48.0](https://github.com/zavudev/sdk-python/compare/v0.47.0...v0.48.0) diff --git a/pyproject.toml b/pyproject.toml index 2f4c054..c789218 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "zavudev" -version = "0.48.0" +version = "0.49.0" description = "The official Python library for the zavudev API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/zavudev/_version.py b/src/zavudev/_version.py index 919a552..2b6c575 100644 --- a/src/zavudev/_version.py +++ b/src/zavudev/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "zavudev" -__version__ = "0.48.0" # x-release-please-version +__version__ = "0.49.0" # x-release-please-version