runpod_sdk/model/
billing.rs

1use serde::{Deserialize, Serialize};
2#[cfg(feature = "strum")]
3use strum::{Display, EnumString};
4
5use super::common::GpuTypeId;
6
7/// Time bucket size for aggregating billing records.
8///
9/// Determines the granularity of billing data aggregation. Each billing record
10/// represents usage and costs for one time bucket period.
11///
12/// # Granularity Trade-offs
13///
14/// - **Hour**: Most detailed, suitable for real-time monitoring and debugging
15/// - **Day**: Good balance of detail and overview (default for most use cases)
16/// - **Week**: Weekly trends and medium-term analysis
17/// - **Month**: Monthly accounting and budget tracking
18/// - **Year**: Long-term cost analysis and yearly planning
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
20#[cfg_attr(feature = "strum", derive(Display, EnumString))]
21#[serde(rename_all = "lowercase")]
22#[cfg_attr(feature = "strum", strum(serialize_all = "lowercase"))]
23pub enum BucketSize {
24    /// Hourly billing aggregation for detailed analysis.
25    Hour,
26    /// Daily billing aggregation (default for most queries).
27    #[default]
28    Day,
29    /// Weekly billing aggregation for trend analysis.
30    Week,
31    /// Monthly billing aggregation for accounting purposes.
32    Month,
33    /// Yearly billing aggregation for long-term planning.
34    Year,
35}
36
37/// Grouping strategy for organizing billing records.
38///
39/// Controls how individual billing records are grouped and aggregated.
40/// Different grouping strategies provide different views of your usage patterns and costs.
41///
42/// # Grouping Strategies
43///
44/// - **PodId**: Individual Pod-level billing (detailed per-resource view)
45/// - **EndpointId**: Individual endpoint-level billing (default for Serverless)
46/// - **GpuTypeId**: Aggregate by GPU type (useful for capacity planning)
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
48#[cfg_attr(feature = "strum", derive(Display, EnumString))]
49#[serde(rename_all = "camelCase")]
50#[cfg_attr(feature = "strum", strum(serialize_all = "camelCase"))]
51pub enum BillingGrouping {
52    /// Group billing records by individual Pod ID.
53    /// Provides detailed per-Pod cost breakdown.
54    #[default]
55    PodId,
56    /// Group billing records by individual endpoint ID.
57    /// Default grouping for Serverless endpoint billing.
58    EndpointId,
59    /// Group billing records by GPU type ID.
60    /// Useful for analyzing costs across different GPU types and capacity planning.
61    GpuTypeId,
62}
63
64/// Individual billing record containing usage and cost information.
65///
66/// Represents billing data for a specific time period and resource grouping.
67/// Contains both cost information and detailed usage metrics.
68///
69/// # Field Availability
70///
71/// Not all fields are populated for every record type:
72/// - `disk_space_billed_gb` and `time_billed_ms` may not apply to all resource types
73/// - Resource ID fields (`pod_id`, `endpoint_id`, `gpu_type_id`) depend on grouping strategy
74/// - Fields are omitted (serialized as null) when not applicable
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(rename_all = "camelCase")]
77pub struct BillingRecord {
78    /// The amount charged for this group during the billing period, in USD.
79    /// This is the total cost after applying any applicable discounts or credits.
80    pub amount: f64,
81
82    /// The amount of disk space billed for the billing period, in gigabytes (GB).
83    /// Only applicable to certain resource types. Omitted when not applicable.
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub disk_space_billed_gb: Option<i32>,
86
87    /// The endpoint ID when grouping by endpoint ID.
88    /// Only populated when using `BillingGrouping::EndpointId`.
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub endpoint_id: Option<String>,
91
92    /// The GPU type ID when grouping by GPU type ID.
93    /// Only populated when using `BillingGrouping::GpuTypeId`.
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub gpu_type_id: Option<String>,
96
97    /// The Pod ID when grouping by Pod ID.
98    /// Only populated when using `BillingGrouping::PodId`.
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub pod_id: Option<String>,
101
102    /// The start timestamp of the period for which this billing record applies.
103    /// Formatted as an ISO 8601 datetime string (e.g., "2023-01-01T00:00:00Z").
104    pub time: String,
105
106    /// The total time billed for the billing period, in milliseconds.
107    /// Only applicable to time-based billing (e.g., compute resources).
108    /// Omitted for storage-only resources.
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub time_billed_ms: Option<i64>,
111}
112
113/// Collection of billing records returned by billing API endpoints.
114///
115/// This type alias represents the standard response format for all billing
116/// queries, containing an array of [`BillingRecord`] instances.
117pub type BillingRecords = Vec<BillingRecord>;
118
119/// Query parameters for retrieving Pod billing history.
120///
121/// Use this struct to customize Pod billing queries with filtering and grouping options.
122/// All fields are optional, allowing for flexible query construction.
123///
124/// # Default Behavior
125///
126/// When fields are omitted:
127/// - `bucket_size`: Defaults to `BucketSize::Day`
128/// - `grouping`: Defaults to `BillingGrouping::GpuTypeId`
129/// - Time range: Returns recent billing data (API-defined default period)
130///
131/// # Examples
132///
133/// ```rust
134/// use runpod_sdk::model::{PodBillingQuery, BucketSize};
135///
136/// // Query for a specific Pod's hourly billing
137/// let query = PodBillingQuery {
138///     bucket_size: Some(BucketSize::Hour),
139///     pod_id: Some("xedezhzb9la3ye".to_string()),
140///     start_time: Some("2023-01-01T00:00:00Z".to_string()),
141///     end_time: Some("2023-01-02T00:00:00Z".to_string()),
142///     ..Default::default()
143/// };
144/// ```
145#[derive(Debug, Clone, Default, Serialize)]
146#[serde(rename_all = "camelCase")]
147pub struct PodBillingQuery {
148    /// The length of each billing time bucket.
149    /// Determines how billing data is aggregated over time.
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub bucket_size: Option<BucketSize>,
152
153    /// The end date of the billing period to retrieve.
154    /// Must be in ISO 8601 format (e.g., "2023-01-31T23:59:59Z").
155    /// If omitted, uses API default (typically current time).
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub end_time: Option<String>,
158
159    /// Filter to Pods with the specified GPU type attached.
160    /// Only billing records for Pods using this GPU type will be returned.
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub gpu_type_id: Option<GpuTypeId>,
163
164    /// Group the billing records by the specified field.
165    /// Controls how individual billing records are organized and aggregated.
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub grouping: Option<BillingGrouping>,
168
169    /// Filter to a specific Pod by its unique identifier.
170    /// When specified, only billing data for this Pod is returned.
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub pod_id: Option<String>,
173
174    /// The start date of the billing period to retrieve.
175    /// Must be in ISO 8601 format (e.g., "2023-01-01T00:00:00Z").
176    /// If omitted, uses API default (typically 30 days ago).
177    #[serde(skip_serializing_if = "Option::is_none")]
178    pub start_time: Option<String>,
179}
180
181/// Query parameters for retrieving Serverless endpoint billing history.
182///
183/// Provides comprehensive filtering options for Serverless endpoint billing data,
184/// including data center filtering, image-based filtering, and template-based filtering.
185///
186/// # Default Behavior
187///
188/// When fields are omitted:
189/// - `bucket_size`: Defaults to `BucketSize::Day`
190/// - `grouping`: Defaults to `BillingGrouping::EndpointId`
191/// - `data_center_id`: Includes all available data centers
192/// - Time range: Returns recent billing data (API-defined default period)
193///
194/// # Examples
195///
196/// ```rust
197/// use runpod_sdk::model::{EndpointBillingQuery, BucketSize, BillingGrouping};
198///
199/// // Query billing for endpoints in specific data centers
200/// let query = EndpointBillingQuery {
201///     bucket_size: Some(BucketSize::Week),
202///     grouping: Some(BillingGrouping::GpuTypeId),
203///     data_center_id: Some(vec!["US-TX-1".to_string(), "US-CA-2".to_string()]),
204///     ..Default::default()
205/// };
206/// ```
207#[derive(Debug, Clone, Default, Serialize)]
208#[serde(rename_all = "camelCase")]
209pub struct EndpointBillingQuery {
210    /// The length of each billing time bucket.
211    /// Determines how billing data is aggregated over time.
212    #[serde(skip_serializing_if = "Option::is_none")]
213    pub bucket_size: Option<BucketSize>,
214
215    /// Filter to endpoints located in any of the specified RunPod data centers.
216    /// Data center IDs can be found in the Pod listing response.
217    /// If omitted, includes all available data centers.
218    #[serde(skip_serializing_if = "Option::is_none")]
219    pub data_center_id: Option<Vec<String>>,
220
221    /// Filter to a specific endpoint by its unique identifier.
222    /// When specified, only billing data for this endpoint is returned.
223    #[serde(skip_serializing_if = "Option::is_none")]
224    pub endpoint_id: Option<String>,
225
226    /// The end date of the billing period to retrieve.
227    /// Must be in ISO 8601 format (e.g., "2023-01-31T23:59:59Z").
228    /// If omitted, uses API default (typically current time).
229    #[serde(skip_serializing_if = "Option::is_none")]
230    pub end_time: Option<String>,
231
232    /// Filter to endpoints with any of the specified GPU types attached.
233    /// Useful for analyzing costs across different GPU configurations.
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub gpu_type_id: Option<Vec<GpuTypeId>>,
236
237    /// Group the billing records by the specified field.
238    /// Controls how individual billing records are organized and aggregated.
239    #[serde(skip_serializing_if = "Option::is_none")]
240    pub grouping: Option<BillingGrouping>,
241
242    /// Filter to endpoints created with the specified Docker image.
243    /// Useful for tracking costs of specific application deployments.
244    /// Example: "runpod/pytorch:2.1.0-py3.10-cuda11.8.0-devel-ubuntu22.04"
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub image_name: Option<String>,
247
248    /// The start date of the billing period to retrieve.
249    /// Must be in ISO 8601 format (e.g., "2023-01-01T00:00:00Z").
250    /// If omitted, uses API default (typically 30 days ago).
251    #[serde(skip_serializing_if = "Option::is_none")]
252    pub start_time: Option<String>,
253
254    /// Filter to endpoints created from the specified template.
255    /// Useful for tracking costs of endpoints deployed from specific templates.
256    #[serde(skip_serializing_if = "Option::is_none")]
257    pub template_id: Option<String>,
258}
259
260/// Query parameters for retrieving Network Volume billing history.
261///
262/// Network Volume billing is typically based on storage capacity and duration,
263/// with simpler filtering options compared to compute resources.
264///
265/// # Default Behavior
266///
267/// When fields are omitted:
268/// - `bucket_size`: Defaults to `BucketSize::Day`
269/// - Time range: Returns recent billing data (API-defined default period)
270///
271/// # Examples
272///
273/// ```rust
274/// use runpod_sdk::model::{NetworkVolumeBillingQuery, BucketSize};
275///
276/// // Query monthly billing for a specific Network Volume
277/// let query = NetworkVolumeBillingQuery {
278///     bucket_size: Some(BucketSize::Month),
279///     network_volume_id: Some("agv6w2qcg7".to_string()),
280///     start_time: Some("2023-01-01T00:00:00Z".to_string()),
281///     end_time: Some("2023-12-31T23:59:59Z".to_string()),
282/// };
283/// ```
284#[derive(Debug, Clone, Default, Serialize)]
285#[serde(rename_all = "camelCase")]
286pub struct NetworkVolumeBillingQuery {
287    /// The length of each billing time bucket.
288    /// Determines how billing data is aggregated over time.
289    #[serde(skip_serializing_if = "Option::is_none")]
290    pub bucket_size: Option<BucketSize>,
291
292    /// The end date of the billing period to retrieve.
293    /// Must be in ISO 8601 format (e.g., "2023-01-31T23:59:59Z").
294    /// If omitted, uses API default (typically current time).
295    #[serde(skip_serializing_if = "Option::is_none")]
296    pub end_time: Option<String>,
297
298    /// Filter to a specific Network Volume by its unique identifier.
299    /// When specified, only billing data for this Network Volume is returned.
300    #[serde(skip_serializing_if = "Option::is_none")]
301    pub network_volume_id: Option<String>,
302
303    /// The start date of the billing period to retrieve.
304    /// Must be in ISO 8601 format (e.g., "2023-01-01T00:00:00Z").
305    /// If omitted, uses API default (typically 30 days ago).
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub start_time: Option<String>,
308}