dodopayments 1.51.1__py3-none-any.whl → 1.56.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. dodopayments/__init__.py +5 -1
  2. dodopayments/_base_client.py +12 -12
  3. dodopayments/_client.py +52 -14
  4. dodopayments/_compat.py +48 -48
  5. dodopayments/_exceptions.py +4 -0
  6. dodopayments/_models.py +50 -44
  7. dodopayments/_qs.py +7 -7
  8. dodopayments/_streaming.py +4 -6
  9. dodopayments/_types.py +18 -11
  10. dodopayments/_utils/__init__.py +8 -2
  11. dodopayments/_utils/_compat.py +45 -0
  12. dodopayments/_utils/_datetime_parse.py +136 -0
  13. dodopayments/_utils/_transform.py +13 -3
  14. dodopayments/_utils/_typing.py +1 -1
  15. dodopayments/_utils/_utils.py +5 -6
  16. dodopayments/_version.py +1 -1
  17. dodopayments/resources/__init__.py +28 -0
  18. dodopayments/resources/addons.py +29 -29
  19. dodopayments/resources/brands.py +29 -29
  20. dodopayments/resources/checkout_sessions.py +110 -27
  21. dodopayments/resources/customers/__init__.py +14 -0
  22. dodopayments/resources/customers/customer_portal.py +5 -5
  23. dodopayments/resources/customers/customers.py +53 -21
  24. dodopayments/resources/customers/wallets/__init__.py +33 -0
  25. dodopayments/resources/customers/wallets/ledger_entries.py +318 -0
  26. dodopayments/resources/customers/wallets/wallets.py +191 -0
  27. dodopayments/resources/discounts.py +44 -44
  28. dodopayments/resources/disputes.py +19 -19
  29. dodopayments/resources/invoices/payments.py +83 -3
  30. dodopayments/resources/license_key_instances.py +13 -13
  31. dodopayments/resources/license_keys.py +23 -23
  32. dodopayments/resources/licenses.py +14 -14
  33. dodopayments/resources/meters.py +554 -0
  34. dodopayments/resources/misc.py +3 -3
  35. dodopayments/resources/payments.py +49 -41
  36. dodopayments/resources/payouts.py +26 -7
  37. dodopayments/resources/products/images.py +5 -5
  38. dodopayments/resources/products/products.py +82 -82
  39. dodopayments/resources/refunds.py +39 -30
  40. dodopayments/resources/subscriptions.py +316 -73
  41. dodopayments/resources/usage_events.py +597 -0
  42. dodopayments/resources/webhooks/headers.py +5 -5
  43. dodopayments/resources/webhooks/webhooks.py +119 -44
  44. dodopayments/types/__init__.py +48 -0
  45. dodopayments/types/add_meter_to_price.py +29 -0
  46. dodopayments/types/add_meter_to_price_param.py +30 -0
  47. dodopayments/types/checkout_session_create_params.py +6 -0
  48. dodopayments/types/checkout_session_status.py +35 -0
  49. dodopayments/types/customer_limited_details.py +5 -0
  50. dodopayments/types/customers/__init__.py +2 -0
  51. dodopayments/types/customers/customer_wallet.py +20 -0
  52. dodopayments/types/customers/wallet_list_response.py +15 -0
  53. dodopayments/types/customers/wallets/__init__.py +7 -0
  54. dodopayments/types/customers/wallets/customer_wallet_transaction.py +38 -0
  55. dodopayments/types/customers/wallets/ledger_entry_create_params.py +25 -0
  56. dodopayments/types/customers/wallets/ledger_entry_list_params.py +18 -0
  57. dodopayments/types/discount_create_params.py +3 -2
  58. dodopayments/types/discount_update_params.py +3 -2
  59. dodopayments/types/dispute_accepted_webhook_event.py +29 -0
  60. dodopayments/types/dispute_accepted_webhook_event1.py +29 -0
  61. dodopayments/types/dispute_cancelled_webhook_event.py +29 -0
  62. dodopayments/types/dispute_cancelled_webhook_event1.py +29 -0
  63. dodopayments/types/dispute_challenged_webhook_event.py +29 -0
  64. dodopayments/types/dispute_challenged_webhook_event1.py +29 -0
  65. dodopayments/types/dispute_expired_webhook_event.py +29 -0
  66. dodopayments/types/dispute_expired_webhook_event1.py +29 -0
  67. dodopayments/types/dispute_lost_webhook_event.py +29 -0
  68. dodopayments/types/dispute_lost_webhook_event1.py +29 -0
  69. dodopayments/types/dispute_opened_webhook_event.py +29 -0
  70. dodopayments/types/dispute_opened_webhook_event1.py +29 -0
  71. dodopayments/types/dispute_won_webhook_event.py +29 -0
  72. dodopayments/types/dispute_won_webhook_event1.py +29 -0
  73. dodopayments/types/event.py +26 -0
  74. dodopayments/types/event_input_param.py +38 -0
  75. dodopayments/types/license_activate_response.py +40 -0
  76. dodopayments/types/license_key_created_webhook_event.py +29 -0
  77. dodopayments/types/license_key_created_webhook_event1.py +29 -0
  78. dodopayments/types/meter.py +40 -0
  79. dodopayments/types/meter_aggregation.py +16 -0
  80. dodopayments/types/meter_aggregation_param.py +16 -0
  81. dodopayments/types/meter_create_params.py +31 -0
  82. dodopayments/types/meter_filter.py +131 -0
  83. dodopayments/types/meter_filter_param.py +143 -0
  84. dodopayments/types/meter_list_params.py +18 -0
  85. dodopayments/types/new_customer_param.py +7 -1
  86. dodopayments/types/payment.py +37 -2
  87. dodopayments/types/payment_cancelled_webhook_event.py +29 -0
  88. dodopayments/types/payment_cancelled_webhook_event1.py +29 -0
  89. dodopayments/types/payment_create_params.py +3 -0
  90. dodopayments/types/payment_failed_webhook_event.py +29 -0
  91. dodopayments/types/payment_failed_webhook_event1.py +29 -0
  92. dodopayments/types/payment_method_types.py +1 -0
  93. dodopayments/types/payment_processing_webhook_event.py +29 -0
  94. dodopayments/types/payment_processing_webhook_event1.py +29 -0
  95. dodopayments/types/payment_succeeded_webhook_event.py +29 -0
  96. dodopayments/types/payment_succeeded_webhook_event1.py +29 -0
  97. dodopayments/types/payout_list_params.py +11 -1
  98. dodopayments/types/price.py +52 -5
  99. dodopayments/types/price_param.py +52 -5
  100. dodopayments/types/product_create_params.py +3 -2
  101. dodopayments/types/product_update_params.py +4 -3
  102. dodopayments/types/refund.py +8 -1
  103. dodopayments/types/refund_create_params.py +4 -1
  104. dodopayments/types/refund_failed_webhook_event.py +29 -0
  105. dodopayments/types/refund_failed_webhook_event1.py +29 -0
  106. dodopayments/types/refund_list_response.py +39 -0
  107. dodopayments/types/refund_succeeded_webhook_event.py +29 -0
  108. dodopayments/types/refund_succeeded_webhook_event1.py +29 -0
  109. dodopayments/types/subscription.py +23 -1
  110. dodopayments/types/subscription_active_webhook_event.py +29 -0
  111. dodopayments/types/subscription_active_webhook_event1.py +29 -0
  112. dodopayments/types/subscription_cancelled_webhook_event.py +29 -0
  113. dodopayments/types/subscription_cancelled_webhook_event1.py +29 -0
  114. dodopayments/types/subscription_charge_params.py +12 -1
  115. dodopayments/types/subscription_create_params.py +3 -0
  116. dodopayments/types/subscription_expired_webhook_event.py +29 -0
  117. dodopayments/types/subscription_expired_webhook_event1.py +29 -0
  118. dodopayments/types/subscription_failed_webhook_event.py +29 -0
  119. dodopayments/types/subscription_failed_webhook_event1.py +29 -0
  120. dodopayments/types/subscription_list_response.py +3 -0
  121. dodopayments/types/subscription_on_hold_webhook_event.py +29 -0
  122. dodopayments/types/subscription_on_hold_webhook_event1.py +29 -0
  123. dodopayments/types/subscription_plan_changed_webhook_event.py +29 -0
  124. dodopayments/types/subscription_plan_changed_webhook_event1.py +29 -0
  125. dodopayments/types/subscription_renewed_webhook_event.py +29 -0
  126. dodopayments/types/subscription_renewed_webhook_event1.py +29 -0
  127. dodopayments/types/subscription_retrieve_usage_history_params.py +28 -0
  128. dodopayments/types/subscription_retrieve_usage_history_response.py +46 -0
  129. dodopayments/types/subscription_update_params.py +2 -0
  130. dodopayments/types/unsafe_unwrap_webhook_event.py +52 -0
  131. dodopayments/types/unwrap_webhook_event.py +52 -0
  132. dodopayments/types/usage_event_ingest_params.py +15 -0
  133. dodopayments/types/usage_event_ingest_response.py +9 -0
  134. dodopayments/types/usage_event_list_params.py +42 -0
  135. {dodopayments-1.51.1.dist-info → dodopayments-1.56.5.dist-info}/METADATA +6 -4
  136. dodopayments-1.56.5.dist-info/RECORD +239 -0
  137. dodopayments-1.51.1.dist-info/RECORD +0 -163
  138. {dodopayments-1.51.1.dist-info → dodopayments-1.56.5.dist-info}/WHEEL +0 -0
  139. {dodopayments-1.51.1.dist-info → dodopayments-1.56.5.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,597 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Union, Iterable
6
+ from datetime import datetime
7
+
8
+ import httpx
9
+
10
+ from ..types import usage_event_list_params, usage_event_ingest_params
11
+ from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
12
+ from .._utils import maybe_transform, async_maybe_transform
13
+ from .._compat import cached_property
14
+ from .._resource import SyncAPIResource, AsyncAPIResource
15
+ from .._response import (
16
+ to_raw_response_wrapper,
17
+ to_streamed_response_wrapper,
18
+ async_to_raw_response_wrapper,
19
+ async_to_streamed_response_wrapper,
20
+ )
21
+ from ..pagination import SyncDefaultPageNumberPagination, AsyncDefaultPageNumberPagination
22
+ from ..types.event import Event
23
+ from .._base_client import AsyncPaginator, make_request_options
24
+ from ..types.event_input_param import EventInputParam
25
+ from ..types.usage_event_ingest_response import UsageEventIngestResponse
26
+
27
+ __all__ = ["UsageEventsResource", "AsyncUsageEventsResource"]
28
+
29
+
30
+ class UsageEventsResource(SyncAPIResource):
31
+ @cached_property
32
+ def with_raw_response(self) -> UsageEventsResourceWithRawResponse:
33
+ """
34
+ This property can be used as a prefix for any HTTP method call to return
35
+ the raw response object instead of the parsed content.
36
+
37
+ For more information, see https://www.github.com/dodopayments/dodopayments-python#accessing-raw-response-data-eg-headers
38
+ """
39
+ return UsageEventsResourceWithRawResponse(self)
40
+
41
+ @cached_property
42
+ def with_streaming_response(self) -> UsageEventsResourceWithStreamingResponse:
43
+ """
44
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
45
+
46
+ For more information, see https://www.github.com/dodopayments/dodopayments-python#with_streaming_response
47
+ """
48
+ return UsageEventsResourceWithStreamingResponse(self)
49
+
50
+ def retrieve(
51
+ self,
52
+ event_id: str,
53
+ *,
54
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
55
+ # The extra values given here take precedence over values defined on the client or passed to this method.
56
+ extra_headers: Headers | None = None,
57
+ extra_query: Query | None = None,
58
+ extra_body: Body | None = None,
59
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
60
+ ) -> Event:
61
+ """Fetch detailed information about a single event using its unique event ID.
62
+
63
+ This
64
+ endpoint is useful for:
65
+
66
+ - Debugging specific event ingestion issues
67
+ - Retrieving event details for customer support
68
+ - Validating that events were processed correctly
69
+ - Getting the complete metadata for an event
70
+
71
+ ## Event ID Format:
72
+
73
+ The event ID should be the same value that was provided during event ingestion
74
+ via the `/events/ingest` endpoint. Event IDs are case-sensitive and must match
75
+ exactly.
76
+
77
+ ## Response Details:
78
+
79
+ The response includes all event data including:
80
+
81
+ - Complete metadata key-value pairs
82
+ - Original timestamp (preserved from ingestion)
83
+ - Customer and business association
84
+ - Event name and processing information
85
+
86
+ ## Example Usage:
87
+
88
+ ```text
89
+ GET /events/api_call_12345
90
+ ```
91
+
92
+ Args:
93
+ extra_headers: Send extra headers
94
+
95
+ extra_query: Add additional query parameters to the request
96
+
97
+ extra_body: Add additional JSON properties to the request
98
+
99
+ timeout: Override the client-level default timeout for this request, in seconds
100
+ """
101
+ if not event_id:
102
+ raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}")
103
+ return self._get(
104
+ f"/events/{event_id}",
105
+ options=make_request_options(
106
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
107
+ ),
108
+ cast_to=Event,
109
+ )
110
+
111
+ def list(
112
+ self,
113
+ *,
114
+ customer_id: str | Omit = omit,
115
+ end: Union[str, datetime] | Omit = omit,
116
+ event_name: str | Omit = omit,
117
+ meter_id: str | Omit = omit,
118
+ page_number: int | Omit = omit,
119
+ page_size: int | Omit = omit,
120
+ start: Union[str, datetime] | Omit = omit,
121
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
122
+ # The extra values given here take precedence over values defined on the client or passed to this method.
123
+ extra_headers: Headers | None = None,
124
+ extra_query: Query | None = None,
125
+ extra_body: Body | None = None,
126
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
127
+ ) -> SyncDefaultPageNumberPagination[Event]:
128
+ """Fetch events from your account with powerful filtering capabilities.
129
+
130
+ This
131
+ endpoint is ideal for:
132
+
133
+ - Debugging event ingestion issues
134
+ - Analyzing customer usage patterns
135
+ - Building custom analytics dashboards
136
+ - Auditing billing-related events
137
+
138
+ ## Filtering Options:
139
+
140
+ - **Customer filtering**: Filter by specific customer ID
141
+ - **Event name filtering**: Filter by event type/name
142
+ - **Meter-based filtering**: Use a meter ID to apply the meter's event name and
143
+ filter criteria automatically
144
+ - **Time range filtering**: Filter events within a specific date range
145
+ - **Pagination**: Navigate through large result sets
146
+
147
+ ## Meter Integration:
148
+
149
+ When using `meter_id`, the endpoint automatically applies:
150
+
151
+ - The meter's configured `event_name` filter
152
+ - The meter's custom filter criteria (if any)
153
+ - If you also provide `event_name`, it must match the meter's event name
154
+
155
+ ## Example Queries:
156
+
157
+ - Get all events for a customer: `?customer_id=cus_abc123`
158
+ - Get API request events: `?event_name=api_request`
159
+ - Get events from last 24 hours:
160
+ `?start=2024-01-14T10:30:00Z&end=2024-01-15T10:30:00Z`
161
+ - Get events with meter filtering: `?meter_id=mtr_xyz789`
162
+ - Paginate results: `?page_size=50&page_number=2`
163
+
164
+ Args:
165
+ customer_id: Filter events by customer ID
166
+
167
+ end: Filter events created before this timestamp
168
+
169
+ event_name: Filter events by event name. If both event_name and meter_id are provided, they
170
+ must match the meter's configured event_name
171
+
172
+ meter_id: Filter events by meter ID. When provided, only events that match the meter's
173
+ event_name and filter criteria will be returned
174
+
175
+ page_number: Page number (0-based, default: 0)
176
+
177
+ page_size: Number of events to return per page (default: 10)
178
+
179
+ start: Filter events created after this timestamp
180
+
181
+ extra_headers: Send extra headers
182
+
183
+ extra_query: Add additional query parameters to the request
184
+
185
+ extra_body: Add additional JSON properties to the request
186
+
187
+ timeout: Override the client-level default timeout for this request, in seconds
188
+ """
189
+ return self._get_api_list(
190
+ "/events",
191
+ page=SyncDefaultPageNumberPagination[Event],
192
+ options=make_request_options(
193
+ extra_headers=extra_headers,
194
+ extra_query=extra_query,
195
+ extra_body=extra_body,
196
+ timeout=timeout,
197
+ query=maybe_transform(
198
+ {
199
+ "customer_id": customer_id,
200
+ "end": end,
201
+ "event_name": event_name,
202
+ "meter_id": meter_id,
203
+ "page_number": page_number,
204
+ "page_size": page_size,
205
+ "start": start,
206
+ },
207
+ usage_event_list_params.UsageEventListParams,
208
+ ),
209
+ ),
210
+ model=Event,
211
+ )
212
+
213
+ def ingest(
214
+ self,
215
+ *,
216
+ events: Iterable[EventInputParam],
217
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
218
+ # The extra values given here take precedence over values defined on the client or passed to this method.
219
+ extra_headers: Headers | None = None,
220
+ extra_query: Query | None = None,
221
+ extra_body: Body | None = None,
222
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
223
+ ) -> UsageEventIngestResponse:
224
+ """
225
+ This endpoint allows you to ingest custom events that can be used for:
226
+
227
+ - Usage-based billing and metering
228
+ - Analytics and reporting
229
+ - Customer behavior tracking
230
+
231
+ ## Important Notes:
232
+
233
+ - **Duplicate Prevention**:
234
+ - Duplicate `event_id` values within the same request are rejected (entire
235
+ request fails)
236
+ - Subsequent requests with existing `event_id` values are ignored (idempotent
237
+ behavior)
238
+ - **Rate Limiting**: Maximum 1000 events per request
239
+ - **Time Validation**: Events with timestamps older than 1 hour or more than 5
240
+ minutes in the future will be rejected
241
+ - **Metadata Limits**: Maximum 50 key-value pairs per event, keys max 100 chars,
242
+ values max 500 chars
243
+
244
+ ## Example Usage:
245
+
246
+ ```json
247
+ {
248
+ "events": [
249
+ {
250
+ "event_id": "api_call_12345",
251
+ "customer_id": "cus_abc123",
252
+ "event_name": "api_request",
253
+ "timestamp": "2024-01-15T10:30:00Z",
254
+ "metadata": {
255
+ "endpoint": "/api/v1/users",
256
+ "method": "GET",
257
+ "tokens_used": "150"
258
+ }
259
+ }
260
+ ]
261
+ }
262
+ ```
263
+
264
+ Args:
265
+ events: List of events to be pushed
266
+
267
+ extra_headers: Send extra headers
268
+
269
+ extra_query: Add additional query parameters to the request
270
+
271
+ extra_body: Add additional JSON properties to the request
272
+
273
+ timeout: Override the client-level default timeout for this request, in seconds
274
+ """
275
+ return self._post(
276
+ "/events/ingest",
277
+ body=maybe_transform({"events": events}, usage_event_ingest_params.UsageEventIngestParams),
278
+ options=make_request_options(
279
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
280
+ ),
281
+ cast_to=UsageEventIngestResponse,
282
+ )
283
+
284
+
285
+ class AsyncUsageEventsResource(AsyncAPIResource):
286
+ @cached_property
287
+ def with_raw_response(self) -> AsyncUsageEventsResourceWithRawResponse:
288
+ """
289
+ This property can be used as a prefix for any HTTP method call to return
290
+ the raw response object instead of the parsed content.
291
+
292
+ For more information, see https://www.github.com/dodopayments/dodopayments-python#accessing-raw-response-data-eg-headers
293
+ """
294
+ return AsyncUsageEventsResourceWithRawResponse(self)
295
+
296
+ @cached_property
297
+ def with_streaming_response(self) -> AsyncUsageEventsResourceWithStreamingResponse:
298
+ """
299
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
300
+
301
+ For more information, see https://www.github.com/dodopayments/dodopayments-python#with_streaming_response
302
+ """
303
+ return AsyncUsageEventsResourceWithStreamingResponse(self)
304
+
305
+ async def retrieve(
306
+ self,
307
+ event_id: str,
308
+ *,
309
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
310
+ # The extra values given here take precedence over values defined on the client or passed to this method.
311
+ extra_headers: Headers | None = None,
312
+ extra_query: Query | None = None,
313
+ extra_body: Body | None = None,
314
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
315
+ ) -> Event:
316
+ """Fetch detailed information about a single event using its unique event ID.
317
+
318
+ This
319
+ endpoint is useful for:
320
+
321
+ - Debugging specific event ingestion issues
322
+ - Retrieving event details for customer support
323
+ - Validating that events were processed correctly
324
+ - Getting the complete metadata for an event
325
+
326
+ ## Event ID Format:
327
+
328
+ The event ID should be the same value that was provided during event ingestion
329
+ via the `/events/ingest` endpoint. Event IDs are case-sensitive and must match
330
+ exactly.
331
+
332
+ ## Response Details:
333
+
334
+ The response includes all event data including:
335
+
336
+ - Complete metadata key-value pairs
337
+ - Original timestamp (preserved from ingestion)
338
+ - Customer and business association
339
+ - Event name and processing information
340
+
341
+ ## Example Usage:
342
+
343
+ ```text
344
+ GET /events/api_call_12345
345
+ ```
346
+
347
+ Args:
348
+ extra_headers: Send extra headers
349
+
350
+ extra_query: Add additional query parameters to the request
351
+
352
+ extra_body: Add additional JSON properties to the request
353
+
354
+ timeout: Override the client-level default timeout for this request, in seconds
355
+ """
356
+ if not event_id:
357
+ raise ValueError(f"Expected a non-empty value for `event_id` but received {event_id!r}")
358
+ return await self._get(
359
+ f"/events/{event_id}",
360
+ options=make_request_options(
361
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
362
+ ),
363
+ cast_to=Event,
364
+ )
365
+
366
+ def list(
367
+ self,
368
+ *,
369
+ customer_id: str | Omit = omit,
370
+ end: Union[str, datetime] | Omit = omit,
371
+ event_name: str | Omit = omit,
372
+ meter_id: str | Omit = omit,
373
+ page_number: int | Omit = omit,
374
+ page_size: int | Omit = omit,
375
+ start: Union[str, datetime] | Omit = omit,
376
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
377
+ # The extra values given here take precedence over values defined on the client or passed to this method.
378
+ extra_headers: Headers | None = None,
379
+ extra_query: Query | None = None,
380
+ extra_body: Body | None = None,
381
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
382
+ ) -> AsyncPaginator[Event, AsyncDefaultPageNumberPagination[Event]]:
383
+ """Fetch events from your account with powerful filtering capabilities.
384
+
385
+ This
386
+ endpoint is ideal for:
387
+
388
+ - Debugging event ingestion issues
389
+ - Analyzing customer usage patterns
390
+ - Building custom analytics dashboards
391
+ - Auditing billing-related events
392
+
393
+ ## Filtering Options:
394
+
395
+ - **Customer filtering**: Filter by specific customer ID
396
+ - **Event name filtering**: Filter by event type/name
397
+ - **Meter-based filtering**: Use a meter ID to apply the meter's event name and
398
+ filter criteria automatically
399
+ - **Time range filtering**: Filter events within a specific date range
400
+ - **Pagination**: Navigate through large result sets
401
+
402
+ ## Meter Integration:
403
+
404
+ When using `meter_id`, the endpoint automatically applies:
405
+
406
+ - The meter's configured `event_name` filter
407
+ - The meter's custom filter criteria (if any)
408
+ - If you also provide `event_name`, it must match the meter's event name
409
+
410
+ ## Example Queries:
411
+
412
+ - Get all events for a customer: `?customer_id=cus_abc123`
413
+ - Get API request events: `?event_name=api_request`
414
+ - Get events from last 24 hours:
415
+ `?start=2024-01-14T10:30:00Z&end=2024-01-15T10:30:00Z`
416
+ - Get events with meter filtering: `?meter_id=mtr_xyz789`
417
+ - Paginate results: `?page_size=50&page_number=2`
418
+
419
+ Args:
420
+ customer_id: Filter events by customer ID
421
+
422
+ end: Filter events created before this timestamp
423
+
424
+ event_name: Filter events by event name. If both event_name and meter_id are provided, they
425
+ must match the meter's configured event_name
426
+
427
+ meter_id: Filter events by meter ID. When provided, only events that match the meter's
428
+ event_name and filter criteria will be returned
429
+
430
+ page_number: Page number (0-based, default: 0)
431
+
432
+ page_size: Number of events to return per page (default: 10)
433
+
434
+ start: Filter events created after this timestamp
435
+
436
+ extra_headers: Send extra headers
437
+
438
+ extra_query: Add additional query parameters to the request
439
+
440
+ extra_body: Add additional JSON properties to the request
441
+
442
+ timeout: Override the client-level default timeout for this request, in seconds
443
+ """
444
+ return self._get_api_list(
445
+ "/events",
446
+ page=AsyncDefaultPageNumberPagination[Event],
447
+ options=make_request_options(
448
+ extra_headers=extra_headers,
449
+ extra_query=extra_query,
450
+ extra_body=extra_body,
451
+ timeout=timeout,
452
+ query=maybe_transform(
453
+ {
454
+ "customer_id": customer_id,
455
+ "end": end,
456
+ "event_name": event_name,
457
+ "meter_id": meter_id,
458
+ "page_number": page_number,
459
+ "page_size": page_size,
460
+ "start": start,
461
+ },
462
+ usage_event_list_params.UsageEventListParams,
463
+ ),
464
+ ),
465
+ model=Event,
466
+ )
467
+
468
+ async def ingest(
469
+ self,
470
+ *,
471
+ events: Iterable[EventInputParam],
472
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
473
+ # The extra values given here take precedence over values defined on the client or passed to this method.
474
+ extra_headers: Headers | None = None,
475
+ extra_query: Query | None = None,
476
+ extra_body: Body | None = None,
477
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
478
+ ) -> UsageEventIngestResponse:
479
+ """
480
+ This endpoint allows you to ingest custom events that can be used for:
481
+
482
+ - Usage-based billing and metering
483
+ - Analytics and reporting
484
+ - Customer behavior tracking
485
+
486
+ ## Important Notes:
487
+
488
+ - **Duplicate Prevention**:
489
+ - Duplicate `event_id` values within the same request are rejected (entire
490
+ request fails)
491
+ - Subsequent requests with existing `event_id` values are ignored (idempotent
492
+ behavior)
493
+ - **Rate Limiting**: Maximum 1000 events per request
494
+ - **Time Validation**: Events with timestamps older than 1 hour or more than 5
495
+ minutes in the future will be rejected
496
+ - **Metadata Limits**: Maximum 50 key-value pairs per event, keys max 100 chars,
497
+ values max 500 chars
498
+
499
+ ## Example Usage:
500
+
501
+ ```json
502
+ {
503
+ "events": [
504
+ {
505
+ "event_id": "api_call_12345",
506
+ "customer_id": "cus_abc123",
507
+ "event_name": "api_request",
508
+ "timestamp": "2024-01-15T10:30:00Z",
509
+ "metadata": {
510
+ "endpoint": "/api/v1/users",
511
+ "method": "GET",
512
+ "tokens_used": "150"
513
+ }
514
+ }
515
+ ]
516
+ }
517
+ ```
518
+
519
+ Args:
520
+ events: List of events to be pushed
521
+
522
+ extra_headers: Send extra headers
523
+
524
+ extra_query: Add additional query parameters to the request
525
+
526
+ extra_body: Add additional JSON properties to the request
527
+
528
+ timeout: Override the client-level default timeout for this request, in seconds
529
+ """
530
+ return await self._post(
531
+ "/events/ingest",
532
+ body=await async_maybe_transform({"events": events}, usage_event_ingest_params.UsageEventIngestParams),
533
+ options=make_request_options(
534
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
535
+ ),
536
+ cast_to=UsageEventIngestResponse,
537
+ )
538
+
539
+
540
+ class UsageEventsResourceWithRawResponse:
541
+ def __init__(self, usage_events: UsageEventsResource) -> None:
542
+ self._usage_events = usage_events
543
+
544
+ self.retrieve = to_raw_response_wrapper(
545
+ usage_events.retrieve,
546
+ )
547
+ self.list = to_raw_response_wrapper(
548
+ usage_events.list,
549
+ )
550
+ self.ingest = to_raw_response_wrapper(
551
+ usage_events.ingest,
552
+ )
553
+
554
+
555
+ class AsyncUsageEventsResourceWithRawResponse:
556
+ def __init__(self, usage_events: AsyncUsageEventsResource) -> None:
557
+ self._usage_events = usage_events
558
+
559
+ self.retrieve = async_to_raw_response_wrapper(
560
+ usage_events.retrieve,
561
+ )
562
+ self.list = async_to_raw_response_wrapper(
563
+ usage_events.list,
564
+ )
565
+ self.ingest = async_to_raw_response_wrapper(
566
+ usage_events.ingest,
567
+ )
568
+
569
+
570
+ class UsageEventsResourceWithStreamingResponse:
571
+ def __init__(self, usage_events: UsageEventsResource) -> None:
572
+ self._usage_events = usage_events
573
+
574
+ self.retrieve = to_streamed_response_wrapper(
575
+ usage_events.retrieve,
576
+ )
577
+ self.list = to_streamed_response_wrapper(
578
+ usage_events.list,
579
+ )
580
+ self.ingest = to_streamed_response_wrapper(
581
+ usage_events.ingest,
582
+ )
583
+
584
+
585
+ class AsyncUsageEventsResourceWithStreamingResponse:
586
+ def __init__(self, usage_events: AsyncUsageEventsResource) -> None:
587
+ self._usage_events = usage_events
588
+
589
+ self.retrieve = async_to_streamed_response_wrapper(
590
+ usage_events.retrieve,
591
+ )
592
+ self.list = async_to_streamed_response_wrapper(
593
+ usage_events.list,
594
+ )
595
+ self.ingest = async_to_streamed_response_wrapper(
596
+ usage_events.ingest,
597
+ )
@@ -6,7 +6,7 @@ from typing import Dict
6
6
 
7
7
  import httpx
8
8
 
9
- from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
9
+ from ..._types import Body, Query, Headers, NoneType, NotGiven, not_given
10
10
  from ..._utils import maybe_transform, async_maybe_transform
11
11
  from ..._compat import cached_property
12
12
  from ..._resource import SyncAPIResource, AsyncAPIResource
@@ -52,7 +52,7 @@ class HeadersResource(SyncAPIResource):
52
52
  extra_headers: Headers | None = None,
53
53
  extra_query: Query | None = None,
54
54
  extra_body: Body | None = None,
55
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
55
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
56
56
  ) -> HeaderRetrieveResponse:
57
57
  """
58
58
  Get a webhook by id
@@ -86,7 +86,7 @@ class HeadersResource(SyncAPIResource):
86
86
  extra_headers: Headers | None = None,
87
87
  extra_query: Query | None = None,
88
88
  extra_body: Body | None = None,
89
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
89
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
90
90
  ) -> None:
91
91
  """
92
92
  Patch a webhook by id
@@ -144,7 +144,7 @@ class AsyncHeadersResource(AsyncAPIResource):
144
144
  extra_headers: Headers | None = None,
145
145
  extra_query: Query | None = None,
146
146
  extra_body: Body | None = None,
147
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
147
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
148
148
  ) -> HeaderRetrieveResponse:
149
149
  """
150
150
  Get a webhook by id
@@ -178,7 +178,7 @@ class AsyncHeadersResource(AsyncAPIResource):
178
178
  extra_headers: Headers | None = None,
179
179
  extra_query: Query | None = None,
180
180
  extra_body: Body | None = None,
181
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
181
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
182
182
  ) -> None:
183
183
  """
184
184
  Patch a webhook by id