runpod_sdk/service/
billing.rs

1use std::future::Future;
2
3#[cfg(feature = "tracing")]
4use crate::TRACING_TARGET_SERVICE;
5use crate::model::{
6    BillingRecords, EndpointBillingQuery, NetworkVolumeBillingQuery, PodBillingQuery,
7};
8use crate::{Result, RunpodClient};
9
10/// Trait for retrieving billing information and usage data.
11///
12/// The `BillingService` provides methods to query billing records for various
13/// RunPod resources including Pods, Serverless endpoints, and Network volumes.
14/// It allows filtering by time ranges, grouping by different criteria, and
15/// retrieving detailed usage statistics for cost analysis and monitoring.
16///
17/// This trait is implemented on the [`RunpodClient`](crate::client::RunpodClient).
18///
19/// # Features
20///
21/// - Query Pod billing history with flexible time ranges
22/// - Retrieve Serverless endpoint billing data with detailed metrics
23/// - Access Network volume usage and billing information
24/// - Support for different time bucket sizes (hour, day, week, month, year)
25/// - Flexible grouping options for data aggregation
26///
27/// # Time Ranges
28///
29/// All billing queries support optional start and end time parameters.
30/// Times should be provided in ISO 8601 format (e.g., "2024-01-01T00:00:00Z").
31/// If not specified, the service will return recent billing data.
32pub trait BillingService {
33    /// Retrieves detailed Pod billing history and usage data.
34    ///
35    /// This method returns billing records for GPU and CPU Pod usage, including
36    /// runtime costs, resource utilization, and time-based billing information.
37    /// Results can be filtered by time range and grouped by various criteria
38    /// such as Pod ID, GPU type, or data center.
39    ///
40    /// # Arguments
41    ///
42    /// * `query` - Query parameters to filter and group the billing data
43    ///   - `bucket_size`: Time granularity (hour, day, week, month, year)
44    ///   - `grouping`: How to group the results (by Pod ID, GPU type, etc.)
45    ///   - `start_time`/`end_time`: Time range filter in ISO 8601 format
46    ///   - `pod_id`: Filter by specific Pod ID
47    ///   - `gpu_type_id`: Filter by specific GPU type
48    ///
49    /// # Returns
50    ///
51    /// A vector of `BillingRecord` containing:
52    /// - Runtime duration and costs
53    /// - Resource type and specifications
54    /// - Time-based billing breakdowns
55    /// - Pod identification and metadata
56    ///
57    /// # Example
58    ///
59    /// ```no_run
60    /// # use runpod_sdk::{RunpodClient, RunpodConfig, Result};
61    /// # use runpod_sdk::model::{PodBillingQuery, BucketSize};
62    /// # use runpod_sdk::service::BillingService;
63    /// # async fn example() -> Result<()> {
64    /// let config = RunpodConfig::from_env()?;
65    /// let client = RunpodClient::new(config)?;
66    ///
67    /// let query = PodBillingQuery {
68    ///     bucket_size: Some(BucketSize::Day),
69    ///     start_time: Some("2024-01-01T00:00:00Z".to_string()),
70    ///     end_time: Some("2024-01-31T23:59:59Z".to_string()),
71    ///     ..Default::default()
72    /// };
73    ///
74    /// let records = client.get_pod_billing(query).await?;
75    /// println!("Found {} pod billing records", records.len());
76    /// # Ok(())
77    /// # }
78    /// ```
79    fn get_pod_billing(
80        &self,
81        query: PodBillingQuery,
82    ) -> impl Future<Output = Result<BillingRecords>>;
83
84    /// Retrieves comprehensive Serverless endpoint billing history and metrics.
85    ///
86    /// This method provides detailed billing information for Serverless endpoint
87    /// usage, including request processing costs, idle time charges, and scaling
88    /// metrics. The data helps analyze endpoint performance and cost efficiency.
89    ///
90    /// # Arguments
91    ///
92    /// * `query` - Query parameters for filtering and grouping endpoint billing data
93    ///   - `bucket_size`: Time granularity for aggregating billing data
94    ///   - `grouping`: Grouping criteria (endpoint ID, template ID, etc.)
95    ///   - `start_time`/`end_time`: Time range for the billing period
96    ///   - `endpoint_id`: Filter by specific endpoint
97    ///   - `template_id`: Filter by template used by endpoints
98    ///   - `gpu_type_id`: Filter by GPU type used
99    ///
100    /// # Returns
101    ///
102    /// A vector of `BillingRecord` containing:
103    /// - Request processing costs and duration
104    /// - Idle time and scaling charges
105    /// - Worker utilization metrics
106    /// - Template and resource information
107    /// - Time-based cost breakdowns
108    ///
109    /// # Example
110    ///
111    /// ```no_run
112    /// # use runpod_sdk::{RunpodClient, RunpodConfig, Result};
113    /// # use runpod_sdk::model::{EndpointBillingQuery, BucketSize, BillingGrouping};
114    /// # use runpod_sdk::service::BillingService;
115    /// # async fn example() -> Result<()> {
116    /// let config = RunpodConfig::from_env()?;
117    /// let client = RunpodClient::new(config)?;
118    ///
119    /// let query = EndpointBillingQuery {
120    ///     bucket_size: Some(BucketSize::Day),
121    ///     grouping: Some(BillingGrouping::EndpointId),
122    ///     start_time: Some("2024-01-01T00:00:00Z".to_string()),
123    ///     end_time: Some("2024-01-31T23:59:59Z".to_string()),
124    ///     ..Default::default()
125    /// };
126    ///
127    /// let records = client.get_endpoint_billing(query).await?;
128    /// println!("Found {} endpoint billing records", records.len());
129    /// # Ok(())
130    /// # }
131    /// ```
132    fn get_endpoint_billing(
133        &self,
134        query: EndpointBillingQuery,
135    ) -> impl Future<Output = Result<BillingRecords>>;
136
137    /// Retrieves Network Volume billing history and storage usage metrics.
138    ///
139    /// This method returns billing information for Network Volume storage,
140    /// including storage capacity costs, data transfer charges, and usage
141    /// patterns. This data is essential for managing storage costs and
142    /// optimizing volume utilization across your infrastructure.
143    ///
144    /// # Arguments
145    ///
146    /// * `query` - Query parameters for filtering volume billing data
147    ///   - `bucket_size`: Time granularity for billing aggregation
148    ///   - `grouping`: How to group results (by volume ID, data center, etc.)
149    ///   - `start_time`/`end_time`: Time range for billing period
150    ///   - `volume_id`: Filter by specific Network Volume ID
151    ///   - `data_center_id`: Filter by data center location
152    ///
153    /// # Returns
154    ///
155    /// A vector of `BillingRecord` containing:
156    /// - Storage capacity costs and duration
157    /// - Data transfer and bandwidth charges
158    /// - Volume utilization metrics
159    /// - Data center and regional cost breakdown
160    /// - Time-based storage billing details
161    ///
162    /// # Example
163    ///
164    /// ```no_run
165    /// # use runpod_sdk::{RunpodClient, RunpodConfig, Result};
166    /// # use runpod_sdk::model::{NetworkVolumeBillingQuery, BucketSize, BillingGrouping};
167    /// # use runpod_sdk::service::BillingService;
168    /// # async fn example() -> Result<()> {
169    /// let config = RunpodConfig::from_env()?;
170    /// let client = RunpodClient::new(config)?;
171    ///
172    /// let query = NetworkVolumeBillingQuery {
173    ///     bucket_size: Some(BucketSize::Day),
174    ///     start_time: Some("2024-01-01T00:00:00Z".to_string()),
175    ///     end_time: Some("2024-01-31T23:59:59Z".to_string()),
176    ///     ..Default::default()
177    /// };
178    ///
179    /// let records = client.get_volume_billing(query).await?;
180    /// println!("Found {} volume billing records", records.len());
181    /// # Ok(())
182    /// # }
183    /// ```
184    fn get_volume_billing(
185        &self,
186        query: NetworkVolumeBillingQuery,
187    ) -> impl Future<Output = Result<BillingRecords>>;
188}
189
190impl BillingService for RunpodClient {
191    async fn get_pod_billing(&self, query: PodBillingQuery) -> Result<BillingRecords> {
192        #[cfg(feature = "tracing")]
193        tracing::debug!(target: TRACING_TARGET_SERVICE, "Getting pod billing records");
194
195        let response = self.get("/billing/pods").query(&query).send().await?;
196        let response = response.error_for_status()?;
197        let records: BillingRecords = response.json().await?;
198
199        #[cfg(feature = "tracing")]
200        tracing::debug!(
201            count = records.len(),
202            "Pod billing records retrieved successfully"
203        );
204
205        Ok(records)
206    }
207
208    async fn get_endpoint_billing(&self, query: EndpointBillingQuery) -> Result<BillingRecords> {
209        #[cfg(feature = "tracing")]
210        tracing::debug!(target: TRACING_TARGET_SERVICE, "Getting endpoint billing records");
211
212        let response = self.get("/billing/endpoints").query(&query).send().await?;
213        let response = response.error_for_status()?;
214        let records: BillingRecords = response.json().await?;
215
216        #[cfg(feature = "tracing")]
217        tracing::debug!(
218            count = records.len(),
219            "Endpoint billing records retrieved successfully"
220        );
221
222        Ok(records)
223    }
224
225    async fn get_volume_billing(&self, query: NetworkVolumeBillingQuery) -> Result<BillingRecords> {
226        #[cfg(feature = "tracing")]
227        tracing::debug!(target: TRACING_TARGET_SERVICE, "Getting network volume billing records");
228
229        let response = self
230            .get("/billing/networkvolumes")
231            .query(&query)
232            .send()
233            .await?;
234        let response = response.error_for_status()?;
235        let records: BillingRecords = response.json().await?;
236
237        #[cfg(feature = "tracing")]
238        tracing::debug!(
239            count = records.len(),
240            "Network volume billing records retrieved successfully"
241        );
242
243        Ok(records)
244    }
245}