twelve_data_client/apis/
advanced_api.rs

1/*
2 * Twelve Data API
3 *
4 * ## Overview  Welcome to Twelve Data developer docs — your gateway to comprehensive financial market data through a powerful and easy-to-use API. Twelve Data provides access to financial markets across over 50 global countries, covering more than 1 million public instruments, including stocks, forex, ETFs, mutual funds, commodities, and cryptocurrencies.  ## Quickstart  To get started, you'll need to sign up for an API key. Once you have your API key, you can start making requests to the API.  ### Step 1: Create Twelve Data account  Sign up on the Twelve Data website to create your account [here](https://twelvedata.com/register). This gives you access to the API dashboard and your API key.  ### Step 2: Get your API key  After signing in, navigate to your [dashboard](https://twelvedata.com/account/api-keys) to find your unique API key. This key is required to authenticate all API and WebSocket requests.  ### Step 3: Make your first request  Try a simple API call with cURL to fetch the latest price for Apple (AAPL):  ``` curl \"https://api.twelvedata.com/price?symbol=AAPL&apikey=your_api_key\" ```  ### Step 4: Make a request from Python or Javascript  Use our client libraries or standard HTTP clients to make API calls programmatically. Here’s an example in [Python](https://github.com/twelvedata/twelvedata-python) and JavaScript:  #### Python (using official Twelve Data SDK):  ```python from twelvedata import TDClient  # Initialize client with your API key td = TDClient(apikey=\"your_api_key\")  # Get latest price for Apple price = td.price(symbol=\"AAPL\").as_json()  print(price) ```  #### JavaScript (Node.js):  ```javascript const fetch = require('node-fetch');  fetch('https://api.twelvedata.com/price?symbol=AAPL&apikey=your_api_key') &nbsp;&nbsp;.then(response => response.json()) &nbsp;&nbsp;.then(data => console.log(data)); ```  ### Step 5: Perform correlation analysis between Tesla and Microsoft prices  Fetch historical price data for Tesla (TSLA) and Microsoft (MSFT) and calculate the correlation of their closing prices:  ```python from twelvedata import TDClient import pandas as pd  # Initialize client with your API key td = TDClient(apikey=\"your_api_key\")  # Fetch historical price data for Tesla tsla_ts = td.time_series( &nbsp;&nbsp;&nbsp;&nbsp;symbol=\"TSLA\", &nbsp;&nbsp;&nbsp;&nbsp;interval=\"1day\", &nbsp;&nbsp;&nbsp;&nbsp;outputsize=100 ).as_pandas()  # Fetch historical price data for Microsoft msft_ts = td.time_series( &nbsp;&nbsp;&nbsp;&nbsp;symbol=\"MSFT\", &nbsp;&nbsp;&nbsp;&nbsp;interval=\"1day\", &nbsp;&nbsp;&nbsp;&nbsp;outputsize=100 ).as_pandas()  # Align data on datetime index combined = pd.concat( &nbsp;&nbsp;&nbsp;&nbsp;[tsla_ts['close'].astype(float), msft_ts['close'].astype(float)], &nbsp;&nbsp;&nbsp;&nbsp;axis=1, &nbsp;&nbsp;&nbsp;&nbsp;keys=[\"TSLA\", \"MSFT\"] ).dropna()  # Calculate correlation correlation = combined[\"TSLA\"].corr(combined[\"MSFT\"]) print(f\"Correlation of closing prices between TSLA and MSFT: {correlation:.2f}\") ```  ### Authentication  Authenticate your requests using one of these methods:  #### Query parameter method ``` GET https://api.twelvedata.com/endpoint?symbol=AAPL&apikey=your_api_key ```  #### HTTP header method (recommended) ``` Authorization: apikey your_api_key ```  ##### API key useful information <ul> <li> Demo API key (<code>apikey=demo</code>) available for demo requests</li> <li> Personal API key required for full access</li> <li> Premium endpoints and data require higher-tier plans (testable with <a href=\"https://twelvedata.com/exchanges\">trial symbols</a>)</li> </ul>  ### API endpoints   Service | Base URL | ---------|----------|  REST API | `https://api.twelvedata.com` |  WebSocket | `wss://ws.twelvedata.com` |  ### Parameter guidelines <ul> <li><b>Separator:</b> Use <code>&</code> to separate multiple parameters</li> <li><b>Case sensitivity:</b> Parameter names are case-insensitive</li>  <ul><li><code>symbol=AAPL</code> = <code>symbol=aapl</code></li></ul>  <li><b>Multiple values:</b> Separate with commas where supported</li> </ul>  ### Response handling  #### Default format All responses return JSON format by default unless otherwise specified.  #### Null values <b>Important:</b> Some response fields may contain `null` values when data is unavailable for specific metrics. This is expected behavior, not an error.  ##### Best Practices: <ul> <li>Always implement <code>null</code> value handling in your application</li> <li>Use defensive programming techniques for data processing</li> <li>Consider fallback values or error handling for critical metrics</li> </ul>  #### Error handling Structure your code to gracefully handle: <ul> <li>Network timeouts</li> <li>Rate limiting responses</li> <li>Invalid parameter errors</li> <li>Data unavailability periods</li> </ul>  ##### Best practices <ul> <li><b>Rate limits:</b> Adhere to your plan’s rate limits to avoid throttling. Check your dashboard for details.</li> <li><b>Error handling:</b> Implement retry logic for transient errors (e.g., <code>429 Too Many Requests</code>).</li> <li><b>Caching:</b> Cache responses for frequently accessed data to reduce API calls and improve performance.</li> <li><b>Secure storage:</b> Store your API key securely and never expose it in client-side code or public repositories.</li> </ul>  ## Errors  Twelve Data API employs a standardized error response format, delivering a JSON object with `code`, `message`, and `status` keys for clear and consistent error communication.  ### Codes  Below is a table of possible error codes, their HTTP status, meanings, and resolution steps:   Code | status | Meaning | Resolution |  --- | --- | --- | --- |  **400** | Bad Request | Invalid or incorrect parameter(s) provided. | Check the `message` in the response for details. Refer to the API Documenta­tion to correct the input. |  **401** | Unauthor­ized | Invalid or incorrect API key. | Verify your API key is correct. Sign up for a key <a href=\"https://twelvedata.com/account/api-keys\">here</a>. |  **403** | Forbidden | API key lacks permissions for the requested resource (upgrade required). | Upgrade your plan <a href=\"https://twelvedata.com/pricing\">here</a>. |  **404** | Not Found | Requested data could not be found. | Adjust parameters to be less strict as they may be too restrictive. |  **414** | Parameter Too Long | Input parameter array exceeds the allowed length. | Follow the `message` guidance to adjust the parameter length. |  **429** | Too Many Requests | API request limit reached for your key. | Wait briefly or upgrade your plan <a href=\"https://twelvedata.com/pricing\">here</a>. |  **500** | Internal Server Error | Server-side issue occurred; retry later. | Contact support <a href=\"https://twelvedata.com/contact\">here</a> for assistance. |  ### Example error response  Consider the following invalid request:  ``` https://api.twelvedata.com/time_series?symbol=AAPL&interval=0.99min&apikey=your_api_key ```  Due to the incorrect `interval` value, the API returns:  ```json { &nbsp;&nbsp;\"code\": 400, &nbsp;&nbsp;\"message\": \"Invalid **interval** provided: 0.99min. Supported intervals: 1min, 5min, 15min, 30min, 45min, 1h, 2h, 4h, 8h, 1day, 1week, 1month\", &nbsp;&nbsp;\"status\": \"error\" } ```  Refer to the API Documentation for valid parameter values to resolve such errors.  ## Libraries  Twelve Data provides a growing ecosystem of libraries and integrations to help you build faster and smarter in your preferred environment. Official libraries are actively maintained by the Twelve Data team, while selected community-built libraries offer additional flexibility.  A full list is available on our [GitHub profile](https://github.com/search?q=twelvedata).  ### Official SDKs <ul> <li><b>Python:</b> <a href=\"https://github.com/twelvedata/twelvedata-python\">twelvedata-python</a></li> <li><b>R:</b> <a href=\"https://github.com/twelvedata/twelvedata-r-sdk\">twelvedata-r-sdk</a></li> </ul>  ### AI integrations <ul> <li><b>Twelve Data MCP Server:</b> <a href=\"https://github.com/twelvedata/mcp\">Repository</a> — Model Context Protocol (MCP) server that provides seamless integration with AI assistants and language models, enabling direct access to Twelve Data's financial market data within conversational interfaces and AI workflows.</li> </ul>  ### Spreadsheet add-ons <ul> <li><b>Excel:</b> <a href=\"https://twelvedata.com/excel\">Excel Add-in</a></li> <li><b>Google Sheets:</b> <a href=\"https://twelvedata.com/google-sheets\">Google Sheets Add-on</a></li> </ul>  ### Community libraries  The community has developed libraries in several popular languages. You can explore more community libraries on [GitHub](https://github.com/search?q=twelvedata). <ul> <li><b>C#:</b> <a href=\"https://github.com/pseudomarkets/TwelveDataSharp\">TwelveDataSharp</a></li> <li><b>JavaScript:</b> <a href=\"https://github.com/evzaboun/twelvedata\">twelvedata</a></li> <li><b>PHP:</b> <a href=\"https://github.com/ingelby/twelvedata\">twelvedata</a></li> <li><b>Go:</b> <a href=\"https://github.com/soulgarden/twelvedata\">twelvedata</a></li> <li><b>TypeScript:</b> <a href=\"https://github.com/Clyde-Goodall/twelve-data-wrapper\">twelve-data-wrapper</a></li> </ul>  ### Other Twelve Data repositories <ul> <li><b>searchindex</b> <i>(Go)</i>: <a href=\"https://github.com/twelvedata/searchindex\">Repository</a> — In-memory search index by strings</li> <li><b>ws-tools</b> <i>(Python)</i>: <a href=\"https://github.com/twelvedata/ws-tools\">Repository</a> — Utility tools for WebSocket stream handling</li> </ul>  ### API specification <ul> <li><b>OpenAPI / Swagger:</b> Access the <a href=\"https://api.twelvedata.com/doc/swagger/openapi.json\">complete API specification</a> in OpenAPI format. You can use this file to automatically generate client libraries in your preferred programming language, explore the API interactively via Swagger tools, or integrate Twelve Data seamlessly into your AI and LLM workflows.</li> </ul>
5 *
6 * The version of the OpenAPI document: 0.0.1
7 *
8 * Generated by: https://openapi-generator.tech
9 */
10
11use super::{configuration, ContentType, Error};
12use crate::{apis::ResponseContent, models};
13use reqwest;
14use serde::{de::Error as _, Deserialize, Serialize};
15
16/// struct for passing parameters to the method [`advanced`]
17#[derive(Clone, Debug, Default, Serialize, Deserialize)]
18pub struct AdvancedParams {
19    /// Map of requests
20    pub key: Option<std::collections::HashMap<String, models::AdvancedRequestValue>>,
21}
22
23impl AdvancedParams {
24    /// Create a new builder for this parameter struct
25    pub fn builder() -> AdvancedParamsBuilder {
26        AdvancedParamsBuilder::default()
27    }
28}
29
30/// Builder for [`AdvancedParams`]
31#[derive(Clone, Debug, Default)]
32pub struct AdvancedParamsBuilder {
33    /// Map of requests
34    key: Option<std::collections::HashMap<String, models::AdvancedRequestValue>>,
35}
36
37impl AdvancedParamsBuilder {
38    /// Map of requests
39    pub fn key(
40        mut self,
41        key: std::collections::HashMap<String, models::AdvancedRequestValue>,
42    ) -> Self {
43        self.key = Some(key);
44        self
45    }
46
47    /// Build the parameter struct
48    pub fn build(self) -> AdvancedParams {
49        AdvancedParams { key: self.key }
50    }
51}
52
53/// struct for passing parameters to the method [`get_api_usage`]
54#[derive(Clone, Debug, Default, Serialize, Deserialize)]
55pub struct GetApiUsageParams {
56    /// Output format
57    pub format: Option<String>,
58    /// Specify the delimiter used when downloading the CSV file
59    pub delimiter: Option<String>,
60    /// Timezone at which output datetime will be displayed. Supports: <ul> <li>1. <code>UTC</code> for datetime at universal UTC standard</li> <li>2. Timezone name according to the IANA Time Zone Database. E.g. <code>America/New_York</code>, <code>Asia/Singapore</code>. Full list of timezones can be found <a href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" target=\"blank\">here</a>.</li> </ul> <i>Take note that the IANA Timezone name is case-sensitive</i>
61    pub timezone: Option<String>,
62}
63
64impl GetApiUsageParams {
65    /// Create a new builder for this parameter struct
66    pub fn builder() -> GetApiUsageParamsBuilder {
67        GetApiUsageParamsBuilder::default()
68    }
69}
70
71/// Builder for [`GetApiUsageParams`]
72#[derive(Clone, Debug, Default)]
73pub struct GetApiUsageParamsBuilder {
74    /// Output format
75    format: Option<String>,
76    /// Specify the delimiter used when downloading the CSV file
77    delimiter: Option<String>,
78    /// Timezone at which output datetime will be displayed. Supports: <ul> <li>1. <code>UTC</code> for datetime at universal UTC standard</li> <li>2. Timezone name according to the IANA Time Zone Database. E.g. <code>America/New_York</code>, <code>Asia/Singapore</code>. Full list of timezones can be found <a href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" target=\"blank\">here</a>.</li> </ul> <i>Take note that the IANA Timezone name is case-sensitive</i>
79    timezone: Option<String>,
80}
81
82impl GetApiUsageParamsBuilder {
83    /// Output format
84    pub fn format(mut self, format: impl Into<String>) -> Self {
85        self.format = Some(format.into());
86        self
87    }
88    /// Specify the delimiter used when downloading the CSV file
89    pub fn delimiter(mut self, delimiter: impl Into<String>) -> Self {
90        self.delimiter = Some(delimiter.into());
91        self
92    }
93    /// Timezone at which output datetime will be displayed. Supports: <ul> <li>1. <code>UTC</code> for datetime at universal UTC standard</li> <li>2. Timezone name according to the IANA Time Zone Database. E.g. <code>America/New_York</code>, <code>Asia/Singapore</code>. Full list of timezones can be found <a href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" target=\"blank\">here</a>.</li> </ul> <i>Take note that the IANA Timezone name is case-sensitive</i>
94    pub fn timezone(mut self, timezone: impl Into<String>) -> Self {
95        self.timezone = Some(timezone.into());
96        self
97    }
98
99    /// Build the parameter struct
100    pub fn build(self) -> GetApiUsageParams {
101        GetApiUsageParams {
102            format: self.format,
103            delimiter: self.delimiter,
104            timezone: self.timezone,
105        }
106    }
107}
108
109/// struct for typed errors of method [`advanced`]
110#[derive(Debug, Clone, Serialize, Deserialize)]
111#[serde(untagged)]
112pub enum AdvancedError {
113    UnknownValue(serde_json::Value),
114}
115
116/// struct for typed errors of method [`get_api_usage`]
117#[derive(Debug, Clone, Serialize, Deserialize)]
118#[serde(untagged)]
119pub enum GetApiUsageError {
120    UnknownValue(serde_json::Value),
121}
122
123/// The batch request endpoint allows users to request data for multiple financial instruments, time intervals, and data types simultaneously. This endpoint is useful for efficiently gathering diverse financial data in a single operation, reducing the need for multiple individual requests. Errors in specific requests do not affect the processing of others, and each error is reported separately, enabling easy troubleshooting.  ### Request body Only JSON `POST` requests are supported. The request content structure consists of key-value items. The key is a unique request ID. The value is requested url.  ### Response The response contains key-value data. The key is a unique request ID. The value is returned data.  ### API credits <ul> <li>The number of concurrent requests is limited by your subscription plan.</li> <li>Credits are consumed per requested endpoint, with the total usage equal to the sum of individual requests in the batch.</li> <li>If the requested data exceeds your available credits, only partial data will be returned asynchronously until your quota is exhausted.</li> <li>If one or more requests in the batch contain errors (e.g., invalid symbols or unsupported intervals), it will not affect the successful processing of other requests. Errors are reported individually within the response, allowing you to identify and correct specific issues without impacting the entire batch.</li> </ul>
124pub async fn advanced(
125    configuration: &configuration::Configuration,
126    params: AdvancedParams,
127) -> Result<models::AdvancedResponse, Error<AdvancedError>> {
128    // Extract parameters from params struct
129    let p_body_key = params.key;
130
131    let uri_str = format!("{}/batch", configuration.base_path);
132    let mut req_builder = configuration
133        .client
134        .request(reqwest::Method::POST, &uri_str);
135
136    if let Some(ref user_agent) = configuration.user_agent {
137        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
138    }
139    if let Some(ref apikey) = configuration.api_key {
140        let key = apikey.key.clone();
141        let value = match apikey.prefix {
142            Some(ref prefix) => format!("{} {}", prefix, key),
143            None => key,
144        };
145        req_builder = req_builder.header("Authorization", value);
146    };
147    req_builder = req_builder.json(&p_body_key);
148
149    let req = req_builder.build()?;
150    let resp = configuration.client.execute(req).await?;
151
152    let status = resp.status();
153    let content_type = resp
154        .headers()
155        .get("content-type")
156        .and_then(|v| v.to_str().ok())
157        .unwrap_or("application/octet-stream");
158    let content_type = super::ContentType::from(content_type);
159
160    if !status.is_client_error() && !status.is_server_error() {
161        let content = resp.text().await?;
162        match content_type {
163            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
164            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/*` content type response that cannot be converted to `models::AdvancedResponse`"))),
165            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::AdvancedResponse`")))),
166        }
167    } else {
168        let content = resp.text().await?;
169        let entity: Option<AdvancedError> = serde_json::from_str(&content).ok();
170        Err(Error::ResponseError(ResponseContent {
171            status,
172            content,
173            entity,
174        }))
175    }
176}
177
178/// The API Usage endpoint provides detailed information on your current API usage statistics. It returns data such as the number of requests made, remaining requests, and the reset time for your usage limits. This endpoint is essential for monitoring and managing your API consumption to ensure you stay within your allocated limits.
179pub async fn get_api_usage(
180    configuration: &configuration::Configuration,
181    params: GetApiUsageParams,
182) -> Result<models::GetApiUsageResponse, Error<GetApiUsageError>> {
183    // Extract parameters from params struct
184    let p_query_format = params.format;
185    let p_query_delimiter = params.delimiter;
186    let p_query_timezone = params.timezone;
187
188    let uri_str = format!("{}/api_usage", configuration.base_path);
189    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
190
191    if let Some(ref param_value) = p_query_format {
192        req_builder = req_builder.query(&[("format", &param_value.to_string())]);
193    }
194    if let Some(ref param_value) = p_query_delimiter {
195        req_builder = req_builder.query(&[("delimiter", &param_value.to_string())]);
196    }
197    if let Some(ref param_value) = p_query_timezone {
198        req_builder = req_builder.query(&[("timezone", &param_value.to_string())]);
199    }
200    if let Some(ref user_agent) = configuration.user_agent {
201        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
202    }
203    if let Some(ref apikey) = configuration.api_key {
204        let key = apikey.key.clone();
205        let value = match apikey.prefix {
206            Some(ref prefix) => format!("{} {}", prefix, key),
207            None => key,
208        };
209        req_builder = req_builder.header("Authorization", value);
210    };
211
212    let req = req_builder.build()?;
213    let resp = configuration.client.execute(req).await?;
214
215    let status = resp.status();
216    let content_type = resp
217        .headers()
218        .get("content-type")
219        .and_then(|v| v.to_str().ok())
220        .unwrap_or("application/octet-stream");
221    let content_type = super::ContentType::from(content_type);
222
223    if !status.is_client_error() && !status.is_server_error() {
224        let content = resp.text().await?;
225        match content_type {
226            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
227            ContentType::Text => return Ok(models::GetApiUsageResponse::Text(content)),
228            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GetApiUsageResponse`")))),
229        }
230    } else {
231        let content = resp.text().await?;
232        let entity: Option<GetApiUsageError> = serde_json::from_str(&content).ok();
233        Err(Error::ResponseError(ResponseContent {
234            status,
235            content,
236            entity,
237        }))
238    }
239}