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.19.0"
".": "0.20.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: 40
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sent%2Fsent-dm-f35f1b37bbee180194767c8644de479a1ce7166e863c4cc22f76115a7adac08f.yml
openapi_spec_hash: b62ddef06e729720dbae93de3efa0898
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sent%2Fsent-dm-896acb6fa28beb028545f1950f0b9b05c6269e9970ab47339e7722d72c62caee.yml
openapi_spec_hash: 1a0fb1b91891b2102228b3fb217e0412
config_hash: 405ade725d72d542c60de821a127411b
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.20.0 (2026-04-21)

Full Changelog: [v0.19.0...v0.20.0](https://github.com/sentdm/sent-dm-python/compare/v0.19.0...v0.20.0)

### Features

* **api:** api update ([3525281](https://github.com/sentdm/sent-dm-python/commit/3525281751a4ae6b2e310ed9cedd6b75c13d6875))

## 0.19.0 (2026-04-20)

Full Changelog: [v0.18.3...v0.19.0](https://github.com/sentdm/sent-dm-python/compare/v0.18.3...v0.19.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 = "sentdm"
version = "0.19.0"
version = "0.20.0"
description = "The official Python library for the Sent API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/sent_dm/_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__ = "sent_dm"
__version__ = "0.19.0" # x-release-please-version
__version__ = "0.20.0" # x-release-please-version
20 changes: 19 additions & 1 deletion src/sent_dm/resources/contacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from typing import Optional
from typing import Dict, Optional

import httpx

Expand Down Expand Up @@ -144,6 +144,7 @@ def update(
self,
id: str,
*,
channel_consent: Optional[Dict[str, str]] | Omit = omit,
default_channel: Optional[str] | Omit = omit,
opt_out: Optional[bool] | Omit = omit,
sandbox: bool | Omit = omit,
Expand All @@ -162,6 +163,13 @@ def update(
cannot be updated.

Args:
channel_consent: Consent status by channel. Keys: "sms", "whatsapp". Values: "opted_in",
"opted_out". All entries must have the same status — mixed values (e.g., sms:
opted_out + whatsapp: opted_in) are rejected with 400. The provided status is
applied to ALL channels regardless of which keys are specified, because consent
is global across channels. When provided, takes precedence over the opt_out
field.

default_channel: Default messaging channel: "sms" or "whatsapp"

opt_out: Whether the contact has opted out of messaging
Expand Down Expand Up @@ -192,6 +200,7 @@ def update(
path_template("/v3/contacts/{id}", id=id),
body=maybe_transform(
{
"channel_consent": channel_consent,
"default_channel": default_channel,
"opt_out": opt_out,
"sandbox": sandbox,
Expand Down Expand Up @@ -429,6 +438,7 @@ async def update(
self,
id: str,
*,
channel_consent: Optional[Dict[str, str]] | Omit = omit,
default_channel: Optional[str] | Omit = omit,
opt_out: Optional[bool] | Omit = omit,
sandbox: bool | Omit = omit,
Expand All @@ -447,6 +457,13 @@ async def update(
cannot be updated.

Args:
channel_consent: Consent status by channel. Keys: "sms", "whatsapp". Values: "opted_in",
"opted_out". All entries must have the same status — mixed values (e.g., sms:
opted_out + whatsapp: opted_in) are rejected with 400. The provided status is
applied to ALL channels regardless of which keys are specified, because consent
is global across channels. When provided, takes precedence over the opt_out
field.

default_channel: Default messaging channel: "sms" or "whatsapp"

opt_out: Whether the contact has opted out of messaging
Expand Down Expand Up @@ -477,6 +494,7 @@ async def update(
path_template("/v3/contacts/{id}", id=id),
body=await async_maybe_transform(
{
"channel_consent": channel_consent,
"default_channel": default_channel,
"opt_out": opt_out,
"sandbox": sandbox,
Expand Down
10 changes: 9 additions & 1 deletion src/sent_dm/types/contact_response.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -20,6 +20,14 @@ class ContactResponse(BaseModel):
available_channels: Optional[str] = None
"""Comma-separated list of available messaging channels (e.g., "sms,whatsapp")"""

channel_consent: Optional[Dict[str, str]] = None
"""Consent status by channel.

Keys: "sms", "whatsapp". Values: "opted_in", "opted_out". All channels will have
the same status because consent is global across channels. A STOP on any channel
opts out of all channels; a START opts in to all.
"""

country_code: Optional[str] = None
"""Country calling code (e.g., 1 for US/Canada)"""

Expand Down
12 changes: 11 additions & 1 deletion src/sent_dm/types/contact_update_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from typing import Optional
from typing import Dict, Optional
from typing_extensions import Annotated, TypedDict

from .._utils import PropertyInfo
Expand All @@ -11,6 +11,16 @@


class ContactUpdateParams(TypedDict, total=False):
channel_consent: Optional[Dict[str, str]]
"""Consent status by channel.

Keys: "sms", "whatsapp". Values: "opted_in", "opted_out". All entries must have
the same status — mixed values (e.g., sms: opted_out + whatsapp: opted_in) are
rejected with 400. The provided status is applied to ALL channels regardless of
which keys are specified, because consent is global across channels. When
provided, takes precedence over the opt_out field.
"""

default_channel: Optional[str]
"""Default messaging channel: "sms" or "whatsapp" """

Expand Down
2 changes: 2 additions & 0 deletions src/sent_dm/types/message_retrieve_status_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class Data(BaseModel):

customer_id: Optional[str] = None

direction: Optional[str] = None

events: Optional[List[DataEvent]] = None

message_body: Optional[DataMessageBody] = None
Expand Down
2 changes: 2 additions & 0 deletions tests/api_resources/test_contacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def test_method_update(self, client: Sent) -> None:
def test_method_update_with_all_params(self, client: Sent) -> None:
contact = client.contacts.update(
id="6ba7b810-9dad-11d1-80b4-00c04fd430c8",
channel_consent={"foo": "string"},
default_channel="whatsapp",
opt_out=False,
sandbox=False,
Expand Down Expand Up @@ -380,6 +381,7 @@ async def test_method_update(self, async_client: AsyncSent) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncSent) -> None:
contact = await async_client.contacts.update(
id="6ba7b810-9dad-11d1-80b4-00c04fd430c8",
channel_consent={"foo": "string"},
default_channel="whatsapp",
opt_out=False,
sandbox=False,
Expand Down
Loading