Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.47.0"
".": "0.48.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 138
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-69a49371271acbb8de23d4d5336746b1487a5fb9b30189ec74f6a74a8a487951.yml
openapi_spec_hash: 05122bf62f2a0ba6f1948eb97f1af7fb
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/zavu/zavudev-3a307b6fa4a6fc0199acbf0660fd1e5ca0ac68082b073b74dbd22e70f3a9ea6e.yml
openapi_spec_hash: a9a255215f69ae2c4abbef59b07f08ea
config_hash: 70a26cd21f0ca1b34242677b831603db
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 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)

### Features

* **api:** api update ([f1dc343](https://github.com/zavudev/sdk-python/commit/f1dc3438dcf4bf96037f6d1a01aad8309ba08857))
* **api:** api update ([0546196](https://github.com/zavudev/sdk-python/commit/054619616c3c3068170d13e0970bcf9afda85782))
* **api:** api update ([4a47dca](https://github.com/zavudev/sdk-python/commit/4a47dca13b67b2be25881bf728170497be72e4cc))

## 0.47.0 (2026-08-02)

Full Changelog: [v0.46.0...v0.47.0](https://github.com/zavudev/sdk-python/compare/v0.46.0...v0.47.0)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "zavudev"
version = "0.47.0"
version = "0.48.0"
description = "The official Python library for the zavudev API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/zavudev/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "zavudev"
__version__ = "0.47.0" # x-release-please-version
__version__ = "0.48.0" # x-release-please-version
10 changes: 10 additions & 0 deletions src/zavudev/resources/functions/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ def create(

source_code: TypeScript source code for the function entry point (max ~900KB).

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
holds up the reply, and a function exposed over HTTP is additionally bounded by
the platform's HTTP response limit.

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand Down Expand Up @@ -461,6 +466,11 @@ async def create(

source_code: TypeScript source code for the function entry point (max ~900KB).

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
holds up the reply, and a function exposed over HTTP is additionally bounded by
the platform's HTTP response limit.

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand Down
10 changes: 6 additions & 4 deletions src/zavudev/resources/phone_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,9 @@ def purchase(
) -> PhoneNumberPurchaseResponse:
"""Purchase an available phone number.

The first US phone number is free for each
team.
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.

Args:
phone_number: Phone number in E.164 format.
Expand Down Expand Up @@ -537,8 +538,9 @@ async def purchase(
) -> PhoneNumberPurchaseResponse:
"""Purchase an available phone number.

The first US phone number is free for each
team.
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.

Args:
phone_number: Phone number in E.164 format.
Expand Down
22 changes: 20 additions & 2 deletions src/zavudev/resources/senders/agent/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,16 @@ def test(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ToolTestResponse:
"""
Test a tool by triggering its webhook with test parameters.
Run a tool with the parameters you supply and return what it answered.

The call is synchronous: the response carries the tool's status, body, and
duration, so a green result is evidence the tool ran rather than evidence it was
accepted. Each run is also recorded and readable afterwards via
`GET /v1/senders/{senderId}/agent/tools/{toolId}/test-runs`.

A tool that answers with an error is reported as a run with `success: false` —
the endpoint itself still returns 200. This fires the tool's real webhook, so a
test has whatever side effects the tool has.

Args:
test_params: Parameters to pass to the tool for testing.
Expand Down Expand Up @@ -587,7 +596,16 @@ async def test(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ToolTestResponse:
"""
Test a tool by triggering its webhook with test parameters.
Run a tool with the parameters you supply and return what it answered.

The call is synchronous: the response carries the tool's status, body, and
duration, so a green result is evidence the tool ran rather than evidence it was
accepted. Each run is also recorded and readable afterwards via
`GET /v1/senders/{senderId}/agent/tools/{toolId}/test-runs`.

A tool that answers with an error is reported as a run with `success: false` —
the endpoint itself still returns 200. This fires the tool's real webhook, so a
test has whatever side effects the tool has.

Args:
test_params: Parameters to pass to the tool for testing.
Expand Down
26 changes: 26 additions & 0 deletions src/zavudev/resources/senders/senders.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def create(
email_domain_id: str | Omit = omit,
email_from_name: str | Omit = omit,
email_receiving_enabled: bool | Omit = omit,
enable_sms_oneway: bool | Omit = omit,
enable_voice: bool | Omit = omit,
phone_number: str | Omit = omit,
set_as_default: bool | Omit = omit,
Expand Down Expand Up @@ -119,6 +120,11 @@ def create(
email_receiving_enabled: Enable inbound email receiving on this sender. Requires a verified MX record on
the domain; ignored otherwise.

enable_sms_oneway: Enable the one-way SMS channel (`sms_oneway`). Needs nothing else — no phone
number, no credential — so it is the fastest way to get a sender that can send.
Recipients cannot reply. Confirm with `sms_oneway` in the `channels` array on
the response.

enable_voice: Let this sender place and answer phone calls. Requires `phoneNumber`; enabling
it without one returns 400. Check the `channels` array on the response to
confirm `voice` is on.
Expand Down Expand Up @@ -150,6 +156,7 @@ def create(
"email_domain_id": email_domain_id,
"email_from_name": email_from_name,
"email_receiving_enabled": email_receiving_enabled,
"enable_sms_oneway": enable_sms_oneway,
"enable_voice": enable_voice,
"phone_number": phone_number,
"set_as_default": set_as_default,
Expand Down Expand Up @@ -206,6 +213,7 @@ def update(
email_domain_id: str | Omit = omit,
email_from_name: str | Omit = omit,
email_receiving_enabled: bool | Omit = omit,
enable_sms_oneway: bool | Omit = omit,
enable_voice: bool | Omit = omit,
name: str | Omit = omit,
set_as_default: bool | Omit = omit,
Expand Down Expand Up @@ -237,6 +245,10 @@ def update(

email_receiving_enabled: Enable or disable inbound email receiving for this sender.

enable_sms_oneway: Turn the one-way SMS channel on or off. Enabling needs nothing else and takes
effect immediately; disabling removes the channel from the sender. Confirm with
the `channels` array on the response.

enable_voice: Turn the voice channel on or off. The sender must already have a phone number
provisioned for calls; enabling it otherwise returns 400 instead of storing a
flag that changes nothing. Confirm with the `channels` array on the response.
Expand Down Expand Up @@ -266,6 +278,7 @@ def update(
"email_domain_id": email_domain_id,
"email_from_name": email_from_name,
"email_receiving_enabled": email_receiving_enabled,
"enable_sms_oneway": enable_sms_oneway,
"enable_voice": enable_voice,
"name": name,
"set_as_default": set_as_default,
Expand Down Expand Up @@ -577,6 +590,7 @@ async def create(
email_domain_id: str | Omit = omit,
email_from_name: str | Omit = omit,
email_receiving_enabled: bool | Omit = omit,
enable_sms_oneway: bool | Omit = omit,
enable_voice: bool | Omit = omit,
phone_number: str | Omit = omit,
set_as_default: bool | Omit = omit,
Expand Down Expand Up @@ -606,6 +620,11 @@ async def create(
email_receiving_enabled: Enable inbound email receiving on this sender. Requires a verified MX record on
the domain; ignored otherwise.

enable_sms_oneway: Enable the one-way SMS channel (`sms_oneway`). Needs nothing else — no phone
number, no credential — so it is the fastest way to get a sender that can send.
Recipients cannot reply. Confirm with `sms_oneway` in the `channels` array on
the response.

enable_voice: Let this sender place and answer phone calls. Requires `phoneNumber`; enabling
it without one returns 400. Check the `channels` array on the response to
confirm `voice` is on.
Expand Down Expand Up @@ -637,6 +656,7 @@ async def create(
"email_domain_id": email_domain_id,
"email_from_name": email_from_name,
"email_receiving_enabled": email_receiving_enabled,
"enable_sms_oneway": enable_sms_oneway,
"enable_voice": enable_voice,
"phone_number": phone_number,
"set_as_default": set_as_default,
Expand Down Expand Up @@ -693,6 +713,7 @@ async def update(
email_domain_id: str | Omit = omit,
email_from_name: str | Omit = omit,
email_receiving_enabled: bool | Omit = omit,
enable_sms_oneway: bool | Omit = omit,
enable_voice: bool | Omit = omit,
name: str | Omit = omit,
set_as_default: bool | Omit = omit,
Expand Down Expand Up @@ -724,6 +745,10 @@ async def update(

email_receiving_enabled: Enable or disable inbound email receiving for this sender.

enable_sms_oneway: Turn the one-way SMS channel on or off. Enabling needs nothing else and takes
effect immediately; disabling removes the channel from the sender. Confirm with
the `channels` array on the response.

enable_voice: Turn the voice channel on or off. The sender must already have a phone number
provisioned for calls; enabling it otherwise returns 400 instead of storing a
flag that changes nothing. Confirm with the `channels` array on the response.
Expand Down Expand Up @@ -753,6 +778,7 @@ async def update(
"email_domain_id": email_domain_id,
"email_from_name": email_from_name,
"email_receiving_enabled": email_receiving_enabled,
"enable_sms_oneway": enable_sms_oneway,
"enable_voice": enable_voice,
"name": name,
"set_as_default": set_as_default,
Expand Down
6 changes: 6 additions & 0 deletions src/zavudev/types/function_create_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ class FunctionCreateParams(TypedDict, total=False):
"""TypeScript source code for the function entry point (max ~900KB)."""

timeout_sec: Annotated[int, PropertyInfo(alias="timeoutSec")]
"""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 holds up the reply, and a function
exposed over HTTP is additionally bounded by the platform's HTTP response limit.
"""
5 changes: 4 additions & 1 deletion src/zavudev/types/phone_number_pricing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@

class PhoneNumberPricing(BaseModel):
is_free_eligible: Optional[bool] = FieldInfo(alias="isFreeEligible", default=None)
"""Whether this number qualifies for the free first US number offer."""
"""
Whether this number qualifies as the plan-included first US number on paid
plans.
"""

monthly_price: Optional[float] = FieldInfo(alias="monthlyPrice", default=None)
"""Monthly price in USD."""
Expand Down
8 changes: 8 additions & 0 deletions src/zavudev/types/sender_create_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ class SenderCreateParams(TypedDict, total=False):
Requires a verified MX record on the domain; ignored otherwise.
"""

enable_sms_oneway: Annotated[bool, PropertyInfo(alias="enableSmsOneway")]
"""Enable the one-way SMS channel (`sms_oneway`).

Needs nothing else — no phone number, no credential — so it is the fastest way
to get a sender that can send. Recipients cannot reply. Confirm with
`sms_oneway` in the `channels` array on the response.
"""

enable_voice: Annotated[bool, PropertyInfo(alias="enableVoice")]
"""Let this sender place and answer phone calls.

Expand Down
7 changes: 7 additions & 0 deletions src/zavudev/types/sender_update_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ class SenderUpdateParams(TypedDict, total=False):
email_receiving_enabled: Annotated[bool, PropertyInfo(alias="emailReceivingEnabled")]
"""Enable or disable inbound email receiving for this sender."""

enable_sms_oneway: Annotated[bool, PropertyInfo(alias="enableSmsOneway")]
"""Turn the one-way SMS channel on or off.

Enabling needs nothing else and takes effect immediately; disabling removes the
channel from the sender. Confirm with the `channels` array on the response.
"""

enable_voice: Annotated[bool, PropertyInfo(alias="enableVoice")]
"""Turn the voice channel on or off.

Expand Down
51 changes: 49 additions & 2 deletions src/zavudev/types/senders/agent/tool_test_response.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,56 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Dict, Optional
from datetime import datetime

from pydantic import Field as FieldInfo

from ...._models import BaseModel

__all__ = ["ToolTestResponse"]
__all__ = ["ToolTestResponse", "Run"]


class Run(BaseModel):
"""One run of a tool triggered from the test endpoint.

Recorded so a test is verifiable after the fact rather than only visible in the response.
"""

id: str

created_at: datetime = FieldInfo(alias="createdAt")

duration_ms: int = FieldInfo(alias="durationMs")

success: bool
"""Whether the tool returned without error.

A tool that answered with a non-2xx status is a failed run, not an error of this
endpoint.
"""

tool_id: str = FieldInfo(alias="toolId")

error: Optional[str] = None
"""Why the run failed, when it did."""

params: Optional[Dict[str, object]] = None
"""The parameters the tool was called with."""

response: Optional[str] = None
"""The tool's response body, truncated."""

status_code: Optional[int] = FieldInfo(alias="statusCode", default=None)
"""HTTP status the tool's webhook returned.

Absent for tools that do not go over HTTP.
"""


class ToolTestResponse(BaseModel):
scheduled: bool
run: Run
"""One run of a tool triggered from the test endpoint.

Recorded so a test is verifiable after the fact rather than only visible in the
response.
"""
9 changes: 9 additions & 0 deletions src/zavudev/types/senders/agent_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,12 @@ class AgentExecution(BaseModel):
response_message_id: Optional[str] = FieldInfo(alias="responseMessageId", default=None)

response_text: Optional[str] = FieldInfo(alias="responseText", default=None)

tool_calls: Optional[int] = FieldInfo(alias="toolCalls", default=None)
"""Tools the agent called while producing this reply.

Zero on an agent that has tools configured means it answered without calling any
— the case where a reply says it will look something up and nothing ever reaches
your endpoint. Absent on executions recorded before this field existed, which is
not the same as zero.
"""
4 changes: 4 additions & 0 deletions tests/api_resources/test_senders.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def test_method_create_with_all_params(self, client: Zavudev) -> None:
email_domain_id="emailDomainId",
email_from_name="emailFromName",
email_receiving_enabled=True,
enable_sms_oneway=True,
enable_voice=True,
phone_number="phoneNumber",
set_as_default=True,
Expand Down Expand Up @@ -135,6 +136,7 @@ def test_method_update_with_all_params(self, client: Zavudev) -> None:
email_domain_id="emailDomainId",
email_from_name="emailFromName",
email_receiving_enabled=True,
enable_sms_oneway=True,
enable_voice=True,
name="name",
set_as_default=True,
Expand Down Expand Up @@ -470,6 +472,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncZavudev) -
email_domain_id="emailDomainId",
email_from_name="emailFromName",
email_receiving_enabled=True,
enable_sms_oneway=True,
enable_voice=True,
phone_number="phoneNumber",
set_as_default=True,
Expand Down Expand Up @@ -564,6 +567,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncZavudev) -
email_domain_id="emailDomainId",
email_from_name="emailFromName",
email_receiving_enabled=True,
enable_sms_oneway=True,
enable_voice=True,
name="name",
set_as_default=True,
Expand Down
Loading