Skip to content

Commit 4284f14

Browse files
author
bird-release[bot]
committed
Release v0.60.0 (sdk-python/v0.60.0)
1 parent 27389b1 commit 4284f14

11 files changed

Lines changed: 1694 additions & 7 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.60.0
4+
5+
- Add `whatsapp.stats` reads over the workspace's own WhatsApp traffic: the period summary, the daily and hourly series, and breakdowns by template, template category, phone number, error code, tag, and destination country, with received-message counts under `whatsapp.stats.inbound`.
6+
37
## 0.59.0
48

59
- Add the whatsapp.reacted webhook event, raised when a contact places, changes or takes back a reaction on a message.

‎examples/examples.gen.py‎

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,41 +1030,121 @@ async def _ex_155() -> None:
10301030

10311031

10321032
async def _ex_156() -> None:
1033+
stats = client.whatsapp.stats.by_country(from_="2026-08-01", to="2026-08-31")
1034+
for row in stats.data or []:
1035+
print(row.country, row.delivery)
1036+
1037+
1038+
async def _ex_157() -> None:
1039+
stats = client.whatsapp.stats.by_error_code(from_="2026-08-01", to="2026-08-31")
1040+
for row in stats.data or []:
1041+
print(row.error_code, row.count)
1042+
1043+
1044+
async def _ex_158() -> None:
1045+
stats = client.whatsapp.stats.by_phone_number(from_="2026-08-01", to="2026-08-31")
1046+
for row in stats.data or []:
1047+
print(row.phone_number, row.delivery)
1048+
1049+
1050+
async def _ex_159() -> None:
1051+
stats = client.whatsapp.stats.by_tag(from_="2026-08-01", to="2026-08-31")
1052+
for row in stats.data or []:
1053+
print(row.tag, row.delivery)
1054+
1055+
1056+
async def _ex_160() -> None:
1057+
stats = client.whatsapp.stats.by_template(from_="2026-08-01", to="2026-08-31")
1058+
for row in stats.data or []:
1059+
print(row.template_id, row.delivery)
1060+
1061+
1062+
async def _ex_161() -> None:
1063+
stats = client.whatsapp.stats.by_template_category(from_="2026-08-01", to="2026-08-31")
1064+
for row in stats.data or []:
1065+
print(row.category, row.delivery)
1066+
1067+
1068+
async def _ex_162() -> None:
1069+
stats = client.whatsapp.stats.daily(from_="2026-08-01", to="2026-08-31")
1070+
for point in stats.data or []:
1071+
print(point.bucket, point.delivery)
1072+
1073+
1074+
async def _ex_163() -> None:
1075+
stats = client.whatsapp.stats.hourly(from_="2026-08-30T00:00:00Z", to="2026-08-31T00:00:00Z")
1076+
for point in stats.data or []:
1077+
print(point.bucket, point.delivery)
1078+
1079+
1080+
async def _ex_164() -> None:
1081+
stats = client.whatsapp.stats.inbound.by_phone_number(from_="2026-05-01", to="2026-05-31")
1082+
for row in stats.data or []:
1083+
print(row.phone_number, row.received)
1084+
1085+
1086+
async def _ex_165() -> None:
1087+
stats = client.whatsapp.stats.inbound.daily(from_="2026-05-01", to="2026-05-31")
1088+
for point in stats.data or []:
1089+
print(point.bucket, point.received)
1090+
1091+
1092+
async def _ex_166() -> None:
1093+
stats = client.whatsapp.stats.inbound.hourly(
1094+
from_="2026-05-30T00:00:00Z", to="2026-05-31T00:00:00Z"
1095+
)
1096+
for point in stats.data or []:
1097+
print(point.bucket, point.received)
1098+
1099+
1100+
async def _ex_167() -> None:
1101+
summary = client.whatsapp.stats.inbound.summary(from_="2026-05-01", to="2026-05-31")
1102+
print(summary.received)
1103+
1104+
1105+
async def _ex_168() -> None:
1106+
summary = client.whatsapp.stats.summary(
1107+
from_="2026-08-01", to="2026-08-31", timezone="Europe/Amsterdam"
1108+
)
1109+
print(summary.delivery, summary.latency)
1110+
1111+
1112+
async def _ex_169() -> None:
10331113
tpl = client.whatsapp.templates.get("bird_otp")
10341114
print(tpl.default_language, tpl.available_languages)
10351115

10361116

1037-
async def _ex_157() -> None:
1117+
async def _ex_170() -> None:
10381118
for tpl in client.whatsapp.templates.list():
10391119
print(tpl.slug, tpl.status)
10401120

10411121

1042-
async def _ex_158() -> None:
1122+
async def _ex_171() -> None:
10431123
version = client.whatsapp.templates.versions.get("bird_otp", "wav_01ky4x8e4genzb7way45txfkm1")
10441124
print(version.id, list(version.languages))
10451125

10461126

1047-
async def _ex_159() -> None:
1127+
async def _ex_172() -> None:
10481128
language = client.whatsapp.templates.versions.languages.get(
10491129
"bird_otp", "wav_01ky4x8e4genzb7way45txfkm1", "nl-BE"
10501130
)
10511131
for component in language.components:
10521132
print(component.type)
10531133

10541134

1055-
async def _ex_160() -> None:
1135+
async def _ex_173() -> None:
10561136
languages = client.whatsapp.templates.versions.languages.list(
10571137
"bird_otp", "wav_01ky4x8e4genzb7way45txfkm1"
10581138
)
10591139
for language in languages.data:
10601140
print(language.language, language.status)
10611141

10621142

1063-
async def _ex_161() -> None:
1143+
async def _ex_174() -> None:
10641144
for version in client.whatsapp.templates.versions.list("bird_otp"):
10651145
print(version.id, version.version_number)
10661146

10671147

1068-
async def _ex_162() -> None:
1148+
async def _ex_175() -> None:
10691149
workspace = client.workspace.get()
10701150
print(workspace.id, workspace.name)

‎examples/reference/whatsapp.py‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,83 @@ def whatsapp_templates_versions_languages_get() -> None:
8181
)
8282
for component in language.components:
8383
print(component.type)
84+
85+
86+
def whatsapp_stats_summary() -> None:
87+
summary = client.whatsapp.stats.summary(
88+
from_="2026-08-01", to="2026-08-31", timezone="Europe/Amsterdam"
89+
)
90+
print(summary.delivery, summary.latency)
91+
92+
93+
def whatsapp_stats_daily() -> None:
94+
stats = client.whatsapp.stats.daily(from_="2026-08-01", to="2026-08-31")
95+
for point in stats.data or []:
96+
print(point.bucket, point.delivery)
97+
98+
99+
def whatsapp_stats_hourly() -> None:
100+
stats = client.whatsapp.stats.hourly(from_="2026-08-30T00:00:00Z", to="2026-08-31T00:00:00Z")
101+
for point in stats.data or []:
102+
print(point.bucket, point.delivery)
103+
104+
105+
def whatsapp_stats_by_error_code() -> None:
106+
stats = client.whatsapp.stats.by_error_code(from_="2026-08-01", to="2026-08-31")
107+
for row in stats.data or []:
108+
print(row.error_code, row.count)
109+
110+
111+
def whatsapp_stats_by_template() -> None:
112+
stats = client.whatsapp.stats.by_template(from_="2026-08-01", to="2026-08-31")
113+
for row in stats.data or []:
114+
print(row.template_id, row.delivery)
115+
116+
117+
def whatsapp_stats_by_template_category() -> None:
118+
stats = client.whatsapp.stats.by_template_category(from_="2026-08-01", to="2026-08-31")
119+
for row in stats.data or []:
120+
print(row.category, row.delivery)
121+
122+
123+
def whatsapp_stats_by_tag() -> None:
124+
stats = client.whatsapp.stats.by_tag(from_="2026-08-01", to="2026-08-31")
125+
for row in stats.data or []:
126+
print(row.tag, row.delivery)
127+
128+
129+
def whatsapp_stats_by_phone_number() -> None:
130+
stats = client.whatsapp.stats.by_phone_number(from_="2026-08-01", to="2026-08-31")
131+
for row in stats.data or []:
132+
print(row.phone_number, row.delivery)
133+
134+
135+
def whatsapp_stats_by_country() -> None:
136+
stats = client.whatsapp.stats.by_country(from_="2026-08-01", to="2026-08-31")
137+
for row in stats.data or []:
138+
print(row.country, row.delivery)
139+
140+
141+
def whatsapp_stats_inbound_summary() -> None:
142+
summary = client.whatsapp.stats.inbound.summary(from_="2026-05-01", to="2026-05-31")
143+
print(summary.received)
144+
145+
146+
def whatsapp_stats_inbound_daily() -> None:
147+
stats = client.whatsapp.stats.inbound.daily(from_="2026-05-01", to="2026-05-31")
148+
for point in stats.data or []:
149+
print(point.bucket, point.received)
150+
151+
152+
def whatsapp_stats_inbound_hourly() -> None:
153+
stats = client.whatsapp.stats.inbound.hourly(
154+
from_="2026-05-30T00:00:00Z", to="2026-05-31T00:00:00Z"
155+
)
156+
for point in stats.data or []:
157+
print(point.bucket, point.received)
158+
159+
160+
def whatsapp_stats_inbound_by_phone_number() -> None:
161+
stats = client.whatsapp.stats.inbound.by_phone_number(from_="2026-05-01", to="2026-05-31")
162+
for row in stats.data or []:
163+
print(row.phone_number, row.received)

‎scripts/surface_ops.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@
6262
"/v1/whatsapp/templates/{template_ref}/versions/{version_id}": {"get"},
6363
"/v1/whatsapp/templates/{template_ref}/versions/{version_id}/languages": {"get"},
6464
"/v1/whatsapp/templates/{template_ref}/versions/{version_id}/languages/{language}": {"get"},
65+
"/v1/whatsapp/stats/summary": {"get"},
66+
"/v1/whatsapp/stats/daily": {"get"},
67+
"/v1/whatsapp/stats/hourly": {"get"},
68+
"/v1/whatsapp/stats/error-codes": {"get"},
69+
"/v1/whatsapp/stats/templates": {"get"},
70+
"/v1/whatsapp/stats/template-categories": {"get"},
71+
"/v1/whatsapp/stats/tags": {"get"},
72+
"/v1/whatsapp/stats/phone-numbers": {"get"},
73+
"/v1/whatsapp/stats/countries": {"get"},
74+
"/v1/whatsapp/stats/inbound/summary": {"get"},
75+
"/v1/whatsapp/stats/inbound/daily": {"get"},
76+
"/v1/whatsapp/stats/inbound/hourly": {"get"},
77+
"/v1/whatsapp/stats/inbound/phone-numbers": {"get"},
6578
"/v1/voice/calls": {"get"},
6679
"/v1/voice/calls/{call_id}": {"get"},
6780
"/v1/verify/verifications": {"post"},

0 commit comments

Comments
 (0)