API Access

Series Finder

Documentation

Help and Support

Terms and Conditions

Documentation

You can use the API via the Python library bcchapi or directly as a REST or SOAP Web Service. Select an option to see the details.

The bcchapi library makes it easy to access the BDE API from Python using standardized classes and methods. Results are returned as pandas DataFrame objects, ready for analysis and visualization.

The bcchapi library is available on the Python Package Index (PyPI) and makes it easy to access the Statistical Database from Python.

In[1]:
# Install the bcchapi library from PyPI
!pip install bcchapi

Once installed, you can import the library in your script or notebook:

In[2]:
# Import the library in your code
import bcchapi

Now you can use the bcchapi library by following the steps below.

The main object of the library is Siete, which is instantiated by adding your API Key Token. You can then search and query series from the Statistical Database.

Note: If you do not have an API Key Token, visit the API Access section to see how to obtain it.

You can authenticate by entering your token directly:

In[3]:
# Instantiate the Siete class with your token
siete = bcchapi.Siete(token="your_token")

Once you have created an instance of the Siete class, you have access to specialized methods to interact with the Central Bank of Chile's Statistical Database. The two main methods are:


Method 1: siete.buscar()

Allows you to find series in the Central Bank of Chile's catalog using keywords in their titles. This is the first step to identify the series you want to query later with the cuadro() method to get the data.

Parameters:

  • contiene (str) Text to search for in the series title (Spanish by default).
  • ingles (bool) Search for text in English titles (False by default).
  • cache (bool) Use local cache to speed up the search process (True by default).

Output: A DataFrame with the series codes and their metadata: titles in Spanish and English, frequency, first observation date, last observation, creation, and update.

Example: Search for series containing "TPM" (first 3 matches):

In[3]:
# Search for series related to TPM
result = siete.buscar("TPM")

print(f"Found {len(result)} series")
result.head(3)
Out[3]:
Found 13 series

seriesIdfrequencyCodespanishTitleenglishTitlefirstObservationlastObservationupdatedAtcreatedAt
0F022.TPM.TIN.D001.NO.Z.DDAILYTasa de política monetaria (TPM) (porcentaje)Monetary policy rate (MPR) (percentage)1997-02-072025-10-132025-10-102025-10-10
1F089.EOF.FI_TPM_CFL.1A.DDAILYEvolución encuesta de operadores fin. (EOF)...Evolution survey of financial operators (EOF)...2021-10-072025-09-042025-09-042025-09-04
2F089.EOF.FI_TPM_DD.1A.DDAILYEvolución encuesta de operadores fin. (EOF)...Evolution survey of financial operators (EOF)...2021-10-072025-09-042025-09-042025-09-04

Method 2: siete.cuadro()

Obtains the observations of one or more series (using their codes) and builds a DataFrame indexed by date, ready to use. You can define the date range to query, convert the series frequency, and calculate variations.

Parameters:

  • series (list): List of series codes to query
  • desde (str, optional): Start date in 'YYYY-MM-DD' format. If not specified, returns from the first observation of the series.
  • hasta (str, optional): End date in 'YYYY-MM-DD' format. If not specified, returns up to the last observation of the series.
  • nombres (list, optional): Allows you to customize the name of the series to query.
  • frecuencia (str, optional): Allows you to convert the series frequency to monthly, quarterly, or annual, specifying the start (S) or end (E) of the period. ('ME'=month end, 'MS'=month start, 'QE'=quarter end, 'QS'=quarter start, 'YE'=year end, 'YS'=year start)
  • observado (str/dict, optional): Aggregation function when changing frequency. Options: "mean" (average), "sum" (sum), "last" (last value)
  • variacion (int, optional): Number of periods back to calculate the variation. Only uses data within the requested range (desde/hasta).

About the 'variacion' parameter:

Important: The variacion parameter always counts months back, regardless of the original frequency of the series:
  • variacion=1 → 1 month back (for monthly series = previous month)
  • variacion=3 → 3 months back (previous quarter)
  • variacion=12 → 12 months back (year-over-year variation)

Output: DataFrame indexed by date with each series as a column (using the code or alias defined in nombres). If you apply transformations such as frequency change or variation calculation, the result will reflect them.

Example: Query the observed dollar for a weekly range:

In[4]:
# Basic query for the observed dollar
data = siete.cuadro(
    series=["F073.TCO.PRE.Z.D"],  # Observed dollar
    desde="2024-10-01",
    hasta="2024-10-07",
    nombres=["Dollar"]
)

print(f"Data obtained: {len(data)} observations")
data
Out[4]:
Data obtained: 7 observations

Dollar
2024-10-01897.68
2024-10-02901.13
2024-10-03908.23
2024-10-04919.49
2024-10-05NaN
2024-10-06NaN
2024-10-07923.74

Example 1: Search and Query the Observed Dollar

In this example we will learn how to find observed dollar series and then retrieve their values.

Step 1: Search for the series

First we search for series related to "dólar observado" to identify the correct series code we need:

In[5]:
# Search for "dólar observado" in available series
search_result = siete.buscar("dólar observado")
print(f"Found {len(search_result)} series related to 'dólar observado'")
print("\nFirst 5 matches:")
search_result[['seriesId', 'frequencyCode', 'spanishTitle']].head()
Out[5]:
Found 3 series related to 'dólar observado' First 5 matches:
seriesIdfrequencyCodespanishTitle
0F073.TCO.PRE.Z.DDAILYTipo de cambio nominal (dólar observado $CLP/USD)...
1F073.TCO.PRE.HIST.MMONTHLYTipo de cambio del dólar observado diario, serie histórica
2F073.TCO.PRE.Z.MMONTHLYTipo de Cambio del Dólar Observado
Step 2: Query the data

From the previous results we will use the first code F073.TCO.PRE.Z.D which corresponds to the daily observed dollar. Now we query the data for the last year:

In[6]:
# Query data for the last year
dollar_data = siete.cuadro(
    series=["F073.TCO.PRE.Z.D"],
    desde="2024-09-01",
    hasta="2025-09-30"
)

print(f"Data retrieved: {len(dollar_data)} observations")
print(f"Period: {dollar_data.index.min()} to {dollar_data.index.max()}")
print("\nLast 10 observations:")
dollar_data.tail(10)
Out[6]:
Data retrieved: 394 observations
Period: 2024-09-02 00:00:00 to 2025-09-30 00:00:00

Last 10 observations:
F073.TCO.PRE.Z.D
2025-09-21NaN
2025-09-22951.03
2025-09-23954.72
2025-09-24952.87
2025-09-25953.24
2025-09-26956.42
2025-09-27NaN
2025-09-28NaN
2025-09-29958.90
2025-09-30961.24
Step 3: Calculate basic statistics

With the retrieved data we calculate some basic descriptive statistics to analyze the observed dollar behavior over the queried period:

In[7]:
# Basic statistics
print("Observed Dollar Statistics:")
print(f"Minimum value: ${datos_dolar.min().iloc[0]:.2f}")
print(f"Maximum value: ${datos_dolar.max().iloc[0]:.2f}")
print(f"Average value: ${datos_dolar.mean().iloc[0]:.2f}")
print(f"Last observation: ${datos_dolar.iloc[-1, 0]:.2f}")
Out[7]:
Observed Dollar statistics:
Minimum value: $896.25
Maximum value: $1012.76
Average value: $955.93
Last observation: $961.24

Example 2: Compare GDP and IMACEC

In this example we work with two important economic indicators with different frequencies: IMACEC (monthly) and GDP (quarterly). This shows how to handle series with mixed periodicities.

Step 1: Search for the series

First we search for each series separately to identify their correct codes:

In[8]:
# Search IMACEC
result_imacec = siete.buscar("Imacec empalmado")
print(f"Series found for IMACEC: {len(result_imacec)}")
print("\nFirst matches:")
result_imacec[['seriesId', 'frequencyCode', 'spanishTitle']].head(5)
Out[8]:
Series found for IMACEC: 4

First matches:
seriesIdfrequencyCodespanishTitle
0F032.IMC.IND.Z.Z.EP13.Z.Z.0.MMONTHLYImacec empalmado, serie original (índice 2013=...
1F032.IMC.IND.Z.Z.EP13.Z.Z.1.MMONTHLYImacec empalmado, desestacionalizado (índice 2...
2F032.IMC.IND.Z.Z.EP18.Z.Z.0.MMONTHLYImacec empalmado, serie original (índice 2018=...
In[9]:
# Search GDP
result_gdp = siete.buscar("PIB, volumen a precios del año anterior encadenado")
print(f"Series found for GDP: {len(result_gdp)}")
print("\nLast matches:")
result_gdp[['seriesId', 'frequencyCode', 'spanishTitle']].tail(10)
Out[9]:
Series found for GDP: 68

Last matches:
seriesIdfrequencyCodespanishTitle
58F032.PIB.FLU.R.CLP.2018.Z.Z.2025MAR.TQUARTERLYPIB, volumen a precios del año anterior encaden...
59F032.PIB.FLU.R.CLP.2018.Z.Z.2025MAY.TQUARTERLYPIB, volumen a precios del año anterior encaden...
60F032.PIB.FLU.R.CLP.2018.Z.Z.2025NOV.TQUARTERLYPIB, volumen a precios del año anterior encaden...
61F032.PIB.FLU.R.CLP.EP08.Z.Z.0.TQUARTERLYPIB, volumen a precios del año anterior encaden...
62F032.PIB.FLU.R.CLP.EP13.Z.Z.0.TQUARTERLYPIB, volumen a precios del año anterior encaden...
63F032.PIB.FLU.R.CLP.EP18.Z.Z.0.TQUARTERLYPIB, volumen a precios del año anterior encaden...
64F032.PIB.FLU.R.CLP.HIST.Z.Z.0.TQUARTERLYPIB, volumen a precios del año anterior encaden...
65F032.PIB.FLU.R.CLP.HIST.Z.Z.3.TQUARTERLYPIB, volumen a precios del año anterior encaden...
66F032.PIB.FLU.R.CLP.HIST13.Z.Z.0.TQUARTERLYPIB, volumen a precios del año anterior encaden...
67F032.PIB.FLU.R.CLP.HIST13.Z.Z.3.TQUARTERLYPIB, volumen a precios del año anterior encaden...
Step 2: Query each series separately

From the previous results, we will use:

  • IMACEC base year 2018: F032.IMC.IND.Z.Z.EP18.Z.Z.0.M (monthly frequency)
  • GDP: F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T (quarterly frequency)

We query each series individually to see their original frequencies:

In[10]:
# Query IMACEC (monthly)
imacec = siete.cuadro(
    series=["F032.IMC.IND.Z.Z.EP18.Z.Z.0.M"],
    desde="2024-01-01",
    hasta="2025-09-30",
    nombres=["IMACEC"]
)

print(f"IMACEC: {len(imacec)} monthly observations")
print(f"Period: {imacec.index.min().strftime('%Y-%m')} to {imacec.index.max().strftime('%Y-%m')}")
imacec.tail()
Out[10]:
IMACEC: 21 monthly observations
Period: 2024-01 to 2025-09
IMACEC
2025-05-01112.950836
2025-06-01108.388247
2025-07-01109.039654
2025-08-01110.446073
2025-09-01109.152886
In[11]:
# Query GDP (quarterly)
gdp = siete.cuadro(
    series=["F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T"],
    desde="2024-01-01",
    hasta="2025-09-30",
    nombres=["GDP"]
)

print(f"GDP: {len(gdp)} quarterly observations")
print(f"Period: {gdp.index.min().strftime('%Y-%m')} to {gdp.index.max().strftime('%Y-%m')}")
gdp
Out[11]:
GDP: 7 quarterly observations
Period: 2024-01 to 2025-07
GDP
2024-01-0151629.653131
2024-04-0151347.892689
2024-07-0151072.569785
2024-10-0155879.020025
2025-01-0152974.863449
2025-04-0153039.105024
2025-07-0151879.676786
Step 3: Calculate year-on-year changes separately

Now we calculate the year-on-year change (12 months back) for both series. Note that the change is computed only within the queried date range:

In[12]:
# Year-on-year change for IMACEC
imacec_var = siete.cuadro(
    series=["F032.IMC.IND.Z.Z.EP18.Z.Z.0.M"],
    desde="2024-01-01",
    hasta="2025-09-30",
    nombres=["IMACEC_var"],
    variacion=12  # 12 months back
)

print("IMACEC - Year-on-year change (%):")
(imacec_var * 100).round(2).tail()
Out[12]:
IMACEC - Year-on-year change (%):
IMACEC_var
2025-05-013.45
2025-06-013.30
2025-07-011.84
2025-08-010.26
2025-09-012.70

For IMACEC (monthly series), we use .tail() to show only the last 5 most recent year-on-year changes.

In[13]:
# Year-on-year change for GDP
gdp_var = siete.cuadro(
    series=["F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T"],
    desde="2024-01-01",
    hasta="2025-09-30",
    nombres=["GDP_var"],
    variacion=12  # 12 months back
)

print("GDP - Year-on-year change (%):")
(gdp_var * 100).round(2).tail()
Out[13]:
GDP - Year-on-year change (%):
GDP_var
2024-07-01NaN
2024-10-01NaN
2025-01-012.61
2025-04-013.29
2025-07-011.58

For GDP (quarterly), we also use .tail() but some values are NaN. Because GDP is quarterly, there are fewer observations in the same date range (only 6 quarters vs 20 months for IMACEC). Early quarters in 2024 show NaN because there are no observations 12 months back within the queried range. Valid values appear from 2025-Q1 onward when 2024-Q1 data exists for comparison.

Step 4: Query both series with original frequency

Finally, we can query both series simultaneously. The library allows mixing series with different frequencies in a single query:

In[14]:
# Query both series with their original frequency
combined_data = siete.cuadro(
    series=[
        "F032.IMC.IND.Z.Z.EP18.Z.Z.0.M",  # IMACEC (monthly)
        "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T"   # GDP (quarterly)
    ],
    desde="2024-01-01",
    hasta="2025-09-30",
    nombres=["IMACEC", "GDP"]
)

print("Combined data (original frequency):")
combined_data.tail(8)
Out[14]:
Combined data (original frequency):
IMACECGDP
2024-01-01107.86810851629.653131
2024-02-01104.151200NaN
2024-03-01115.035498NaN
2024-04-01111.15904751347.892689
2024-05-01109.182567NaN
2024-06-01104.928343NaN
2024-07-01107.07385251072.569785
2024-08-01110.163804NaN

As seen in the result, it is possible to combine series with different frequencies. IMACEC has monthly values while GDP has quarterly values (January, April, July, October). Therefore, for intermediate months (February, March, May, June, August) GDP shows NaN because those months are not part of its quarterly frequency.


Downloadable Complete Example

Download the interactive notebook with the detailed, executable examples:

Includes detailed examples for the observed dollar, GDP, IMACEC, handling different frequencies and step-by-step explanations.

The BDE API can be consumed as a web service (an interface that enables communication between applications over the internet) using two protocols: REST and SOAP. REST uses simple URLs and is popular in languages like Python and R, while SOAP uses a WSDL file and is common in environments such as C# or Java.

The Central Bank of Chile REST service lets you access the Statistical Database directly through parameterized URLs. Results are returned in JSON format, compatible with any programming language that supports HTTP.

The REST service is available through a single endpoint that accepts different functions via URL parameters. It is a direct option for developers who prefer to build their own HTTP requests without depending on specialized libraries.

Main Endpoint

https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx

Available functions

  • SearchSeries - Search series by frequency in the catalog
  • GetSeries - Retrieve data for a specific series
Advantages of the REST service: Maximum flexibility; it works with any program that supports HTTP, such as R, Stata, Matlab, Python, or any other you use.

All REST requests require a valid API Key Token that must be included as a parameter in each URL.

Note: If you do not have an API Key Token, visit the API Access section to learn how to obtain it.

You can include the API Key Token directly in the URL:

https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&...

The Central Bank of Chile's REST service offers two main methods to interact with the Statistical Database. Each method is specified via the function parameter in the URL:


Method 1: SearchSeries

Returns the full catalog of available series filtered by temporal frequency. Useful to explore which series are available before requesting specific data. Relevant data is in the SeriesInfos property of the JSON response.

Parameters:

  • token (str, required): Your personal API Key Token
  • function (str, required): Must be "SearchSeries"
  • frequency (str, required): Temporal frequency (DAILY, MONTHLY, QUARTERLY, ANNUAL)

Output: JSON with the full list of series for the requested frequency. Data is in SeriesInfos, including series code, titles in Spanish and English, frequency, first and last observation dates, and creation/update timestamps.

Example: Search for all available quarterly series:

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=SearchSeries&frequency=QUARTERLY
JSON Response:
{
  "Codigo": 0,
  "Descripcion": "Success",
  "Series": {
    "descripEsp": null,
    "descripIng": null,
    "seriesId": null,
    "Obs": null
  },
  "SeriesInfos": [ // ← Relevant data is here
    {
      "seriesId": "F061.1.FLU.S.USD.Z.T",
      "frequencyCode": "QUARTERLY",
      "spanishTitle": "Cuenta corriente, 1996-2011 (BP)",
      "englishTitle": "Current account, 1996-2011 (BP)",
      "firstObservation": "01-01-1996",
      "lastObservation": "01-07-2011",
      "updatedAt": "09-01-2015",
      "createdAt": "09-01-2015"
    },
    {
      "seriesId": "F061.1A.FLU.S.USD.Z.T",
      "frequencyCode": "QUARTERLY",
      "spanishTitle": "Comercio de bienes y servicios, 1996-2011 (BP)",
      "englishTitle": "Current account - Goods and services, 1996-2011 (BP)",
      "firstObservation": "01-01-1996",
      "lastObservation": "01-07-2011",
      "updatedAt": "09-01-2015",
      "createdAt": "09-01-2015"
    },
    // ... more series
    {
      "seriesId": "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T",
      "frequencyCode": "QUARTERLY",
      "spanishTitle": "PIB, volumen a precios del año anterior encadenado, referencia 2018 (miles de millones de pesos encadenados)",
      "englishTitle": "GDP, chained volume at previous year prices, reference 2018, linked series (billions of chained-pesos)",
      "firstObservation": "01-01-1996",
      "lastObservation": "01-04-2025",
      "updatedAt": "18-08-2025",
      "createdAt": "18-08-2025"
    }
    // ... more series
  ]
}

Method 2: GetSeries

Retrieves observations for a specific statistical series. You can define date ranges to limit the query and retrieve only the period of interest. Relevant data is in the Obs property inside Series of the response JSON.

Parameters:

  • token (str, required): Your personal API Key Token
  • function (str, optional): "GetSeries" (default value if omitted)
  • timeseries (str, required): Series code (e.g., F073.TCO.PRE.Z.D)
  • firstdate (str, optional): Start date in YYYY-MM-DD format
  • lastdate (str, optional): End date in YYYY-MM-DD format

Output: JSON with the observations of the requested series. The data is in Series.Obs, including dates, values, and status codes. It also includes series metadata such as titles in Spanish and English.

Example: Query the Monetary Policy Rate from October 10 to October 15, 2021:

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=GetSeries&timeseries=F022.TPM.TIN.D001.NO.Z.D&firstdate=2021-10-10&lastdate=2021-10-15
JSON Response:
{
  "Codigo": 0,
  "Descripcion": "Success",
  "Series": {
    "descripEsp": "Tasa de política monetaria (TPM) (porcentaje)",
    "descripIng": "Monetary policy rate (MPR) (percentage)",
    "seriesId": "F022.TPM.TIN.D001.NO.Z.D",
    "Obs": [ // ← Relevant data is here
      {
        "indexDateString": "12-10-2021",
        "value": "1.5",
        "statusCode": "OK"
      },
      {
        "indexDateString": "13-10-2021",
        "value": "1.5",
        "statusCode": "OK"
      },
      {
        "indexDateString": "14-10-2021",
        "value": "2.75",
        "statusCode": "OK"
      },
      {
        "indexDateString": "15-10-2021",
        "value": "2.75",
        "statusCode": "OK"
      }
    ]
  },
  "SeriesInfos": []
}

Example 1: Search and Retrieve Observed Dollar

In this example we'll learn how to search for observed dollar values: first identify the appropriate series, then retrieve its values.

Step 1: Search for the series

First we search all daily series to find the observed dollar. We use SearchSeries with frequency DAILY:

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=SearchSeries&frequency=DAILY
JSON Response:
{
  "Codigo": 0,
  "Descripcion": "Success",
  "Series": {
    "descripEsp": null,
    "descripIng": null,
    "seriesId": null,
    "Obs": null
  },
  "SeriesInfos": [ // ← Series metadata is here
    {
      "seriesId": "G073.TCMX.IND.199801.D",
      "frequencyCode": "DAILY",
      "spanishTitle": "Índice TCM-X (2 enero 1998=100)",
      "englishTitle": "MER-X index (2 January 1998=100)",
      "firstObservation": "02-01-2002",
      "lastObservation": "22-10-2025",
      "updatedAt": "21-10-2025",
      "createdAt": "21-10-2025"
    },
    {
      "seriesId": "F062.A5.STO.PF.USD.D",
      "frequencyCode": "DAILY",
      "spanishTitle": "PII Activos de reservas, 1996-2011, serie semanal",
      "englishTitle": "PII Activos de reservas, 1996-2011, serie semanal",
      "firstObservation": "31-12-1995",
      "lastObservation": "07-10-2025",
      "updatedAt": "15-10-2025",
      "createdAt": "15-10-2025"
    },
    // ... more series
    {
      "seriesId": "F073.TCO.PRE.Z.D",
      "frequencyCode": "DAILY",
      "spanishTitle": "Tipo de cambio nominal (dólar observado $CLP/USD); tipo de cambio; ; precio; diario; ; Banco Central de Chile; ; ",
      "englishTitle": "Nominal exchange rate (Observed dollar $CLP/USD); exchange rate; ; price; daily; ; central bank of chile; ; ",
      "firstObservation": "09-08-1982",
      "lastObservation": "22-10-2025",
      "updatedAt": "21-10-2025",
      "createdAt": "21-10-2025"
    }
    // ... more series
  ]
}

In the JSON response, search the SeriesInfos array for series containing "dólar observado" in their spanishTitle. The code of interest is F073.TCO.PRE.Z.D.

Step 2: Query the data

Now query the observed dollar data for a specific week using GetSeries:

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=GetSeries&timeseries=F073.TCO.PRE.Z.D&firstdate=2024-10-01&lastdate=2024-10-07
JSON Response:
{
  "Codigo": 0,
  "Descripcion": "Success",
  "Series": {
    "descripEsp": "Tipo de cambio nominal (dólar observado $CLP/USD); tipo de cambio; ; precio; diario; ; Banco Central de Chile; ; ",
    "descripIng": "Nominal exchange rate (Observed dollar $CLP/USD); exchange rate; ; price; daily; ; central bank of chile; ; ",
    "seriesId": "F073.TCO.PRE.Z.D",
    "Obs": [ // ← Relevant data is here
      {
        "indexDateString": "01-10-2024",
        "value": "897.68",
        "statusCode": "OK"
      },
      {
        "indexDateString": "02-10-2024",
        "value": "901.13",
        "statusCode": "OK"
      },
      {
        "indexDateString": "03-10-2024",
        "value": "908.23",
        "statusCode": "OK"
      },
      {
        "indexDateString": "04-10-2024",
        "value": "919.49",
        "statusCode": "OK"
      },
      {
        "indexDateString": "05-10-2024",
        "value": "NaN",
        "statusCode": "ND"
      },
      {
        "indexDateString": "06-10-2024",
        "value": "NaN",
        "statusCode": "ND"
      },
      {
        "indexDateString": "07-10-2024",
        "value": "923.74",
        "statusCode": "OK"
      }
    ]
  },
  "SeriesInfos": []
}

The JSON response contains observations in Series.Obs, where each observation includes a date (indexDateString), a value (value) and a status (statusCode). These values show the exchange rate evolution during that week.


Example 2: Compare GDP and IMACEC

In this example we will query two indicators with different frequencies: IMACEC (monthly) and GDP (quarterly).

Step 1: Search for the series separately

First search the monthly series to find IMACEC:

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=SearchSeries&frequency=MONTHLY
JSON Response:
{
  "SeriesInfos": [
    // ... more series
    {
      "seriesId": "F032.IMC.IND.Z.Z.EP18.Z.Z.0.M",
      "frequencyCode": "MONTHLY",
      "spanishTitle": "Imacec empalmado, serie original (índice 2018=100)",
      "englishTitle": "Monthly indicator of economic activity Imacec, linked series (2018 index=100)"
    }
    // ... more series
  ]
}

Look for series that contain "Imacec empalmado" in their spanishTitle to find the 2018-base IMACEC code: F032.IMC.IND.Z.Z.EP18.Z.Z.0.M.

Then search the quarterly series to find GDP:

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=SearchSeries&frequency=QUARTERLY
JSON Response:
{
  "SeriesInfos": [
    // ... more series
    {
      "seriesId": "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T",
      "frequencyCode": "QUARTERLY",
      "spanishTitle": "PIB, volumen a precios del año anterior encadenado, referencia 2018 (miles de millones de pesos encadenados)",
      "englishTitle": "GDP, chained volume at previous year prices, reference 2018, linked series (billions of chained-pesos)"
    }
    // ... more series
  ]
}

Look for series that contain "PIB, volumen a precios del año anterior encadenado" in their spanishTitle to find the 2018-base GDP code: F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T.

Step 2: Query each series separately

The REST service only allows independent queries, so we must query each series separately:

IMACEC (monthly): Query IMACEC from January to June 2024, obtaining six observations (one per month).

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=GetSeries&timeseries=F032.IMC.IND.Z.Z.EP18.Z.Z.0.M&firstdate=2024-01-01&lastdate=2024-06-30
JSON Response:
{
  "Series": {
    "descripEsp": "Imacec empalmado, serie original (índice 2018=100)",
    "seriesId": "F032.IMC.IND.Z.Z.EP18.Z.Z.0.M",
    "Obs": [
      { "indexDateString": "01-01-2024", "value": "107.86810800473", "statusCode": "OK" },
      { "indexDateString": "01-02-2024", "value": "104.15119989615", "statusCode": "OK" },
      { "indexDateString": "01-03-2024", "value": "115.03549781737", "statusCode": "OK" },
      { "indexDateString": "01-04-2024", "value": "111.1590474829", "statusCode": "OK" },
      { "indexDateString": "01-05-2024", "value": "109.18256697619", "statusCode": "OK" },
      { "indexDateString": "01-06-2024", "value": "104.92834280488", "statusCode": "OK" }
    ]
  }
}

GDP (quarterly): Query GDP from January to June 2024. In this case we only obtain two observations because the frequency is quarterly.

URL:
https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=your_token&function=GetSeries&timeseries=F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T&firstdate=2024-01-01&lastdate=2024-06-30
JSON Response:
{
  "Series": {
    "descripEsp": "PIB, volumen a precios del año anterior encadenado, referencia 2018 (miles de millones de pesos encadenados)",
    "seriesId": "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T",
    "Obs": [
      { "indexDateString": "01-01-2024", "value": "51629.653130861", "statusCode": "OK" },
      { "indexDateString": "01-04-2024", "value": "51347.892688956", "statusCode": "OK" }
    ]
  }
}

The quarterly GDP has observations only in January and April for this period, while IMACEC has complete monthly data from January to June.

This example shows how to consume the Central Bank of Chile's REST service from R using the rjson and httr libraries. The steps follow the same logic as the previous examples but are implemented in R for a complete workflow.

Environment setup

First install and load the required libraries:

In[1]:
# Install libraries (run only once)
install.packages("rjson")
install.packages("httr")

# Load libraries
library("rjson")
library(httr)
In[2]:
# API Key Token (replace with your own)
token <- "your_token"

Example 1: Search and Retrieve Observed Dollar

Step 1: Search for the series

First we search for series related to "dólar observado" using SearchSeries with daily frequency:

In[3]:
# Full URL to search daily series
url_search_dollar <- paste0(
  "https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=", token,
  "&function=SearchSeries&frequency=DAILY"
)

# Run the query
json_data_dolar <- rjson::fromJSON(file = url_search_dollar)

# Process SeriesInfos from JSON
daily_series <- as.data.frame(do.call(rbind, lapply(json_data_dolar$SeriesInfos, as.vector)))
daily_series$spanishTitle <- as.character(daily_series$spanishTitle)

# Filter series containing "dólar observado"
idx_dolar <- grep("dólar observado", daily_series$spanishTitle, ignore.case = TRUE)
dollar_series <- daily_series[idx_dolar, ]

cat("Found", nrow(series_dolar), "series related to 'dólar observado'\n")
print(head(series_dolar, 3))
Out[3]:
Found 1 series related to 'dólar observado'

           seriesId         freq                           spanishTitle
1055  F073.TCO.PRE.Z.D     DAILY    Tipo de cambio nominal (dólar observado...)  

                 englishTitle                             firstObs        lastObs         updated
1055  Nominal exchange rate (Observed dollar...)        09-08-1982      23-10-2025     22-10-2025
Step 2: Retrieve the data

Now we query the observed dollar data for the last year using the code F073.TCO.PRE.Z.D:

In[4]:
# Full URL to retrieve series data
url_dollar_data <- paste0(
  "https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=", token,
  "&function=GetSeries&timeseries=F073.TCO.PRE.Z.D",
  "&firstdate=2024-09-01&lastdate=2025-09-30"
)

# Run the query
json_data_serie <- rjson::fromJSON(file = url_dollar_data)

# Process observations (Series.Obs from JSON)
observations <- as.data.frame(do.call(rbind, lapply(json_data_serie$Series$Obs, as.vector)))
observations$value <- as.numeric(observations$value)
observations$indexDateString <- as.character(observations$indexDateString)

cat("Retrieved:", nrow(observations), "observations\n")
cat("Period:", min(observations$indexDateString), "to", max(observations$indexDateString), "\n")
print(tail(observations, 10))
Out[4]:
Retrieved: 394 observations
Period: 01-09-2024 to 30-09-2025

    indexDateString   value  statusCode
385      21-09-2025    NaN         ND
386      22-09-2025  951.03        OK
387      23-09-2025  954.72        OK
388      24-09-2025  952.87        OK
389      25-09-2025  953.24        OK
390      26-09-2025  956.42        OK
391      27-09-2025    NaN         ND
392      28-09-2025    NaN         ND
393      29-09-2025  958.90        OK
394      30-09-2025  961.24        OK
Step 3: Compute basic statistics

With the retrieved data, we calculate basic descriptive statistics:

In[5]:
# Basic statistics (excluding NA values)
valid_values <- observations$value[!is.na(observations$value)]

cat("Observed Dollar statistics:\n")
cat("Minimum value: $", round(min(valid_values), 2), "\n")
cat("Maximum value: $", round(max(valid_values), 2), "\n")
cat("Average value: $", round(mean(valid_values), 2), "\n")
cat("Last observation: $", round(tail(valid_values, 1), 2), "\n")
Out[5]:
Observed Dollar statistics:
Minimum value: $ 896.25
Maximum value: $ 1012.76
Average value: $ 955.92
Last observation: $ 961.24

Example 2: GDP and IMACEC with different frequencies

In this example we will work with two economic indicators that have different frequencies: IMACEC (monthly) and GDP (quarterly).

Step 1: Search for the series

First we search for both series separately according to their frequency:

In[6]:
# Search for IMACEC (MONTHLY frequency)
url_search_imacec <- paste0(
  "https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=", token,
  "&function=SearchSeries&frequency=MONTHLY"
)

json_data_imacec <- rjson::fromJSON(file = url_search_imacec)
monthly_series <- as.data.frame(do.call(rbind, lapply(json_data_imacec$SeriesInfos, as.vector)))
monthly_series$spanishTitle <- as.character(monthly_series$spanishTitle)

idx_imacec <- grep("imacec empalmado", monthly_series$spanishTitle, ignore.case = TRUE)
imacec_series <- monthly_series[idx_imacec, ]

cat("Series found for IMACEC:", nrow(imacec_series), "\n")
print(head(imacec_series, 5))
Out[6]:
Series found for IMACEC: 4

                       seriesId        freq                               spanishTitle                       …
4583  F032.IMC.IND.Z.Z.EP13.Z.Z.0.M   MONTHLY     Imacec empalmado, serie original (índice 2013=100)         …
4584  F032.IMC.IND.Z.Z.EP13.Z.Z.1.M   MONTHLY     Imacec empalmado, desestacionalizado (índice 2013=100)     …
4601  F032.IMC.IND.Z.Z.EP18.Z.Z.0.M   MONTHLY     Imacec empalmado, serie original (índice 2018=100)         …
4602  F032.IMC.IND.Z.Z.EP18.Z.Z.1.M   MONTHLY     Imacec empalmado, desestacionalizado (índice 2018=100)     …
In[7]:
# Search for GDP (QUARTERLY frequency)
url_search_gdp <- paste0(
  "https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=", token,
  "&function=SearchSeries&frequency=QUARTERLY"
)

json_data_gdp <- rjson::fromJSON(file = url_search_gdp)
quarterly_series <- as.data.frame(do.call(rbind, lapply(json_data_gdp$SeriesInfos, as.vector)))
quarterly_series$spanishTitle <- as.character(quarterly_series$spanishTitle)

idx_gdp <- grep("PIB, volumen a precios del año anterior encadenado", quarterly_series$spanishTitle, ignore.case = TRUE)
series_gdp <- quarterly_series[idx_gdp, ]

cat("Series found for GDP:", nrow(series_gdp), "\n")
print(tail(series_gdp, 5))
Out[7]:
Series found for GDP: 65

                       seriesId          freq                               spanishTitle                       …
2412  F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T    QUARTERLY      PIB, volumen a precios del año anterior encadenado…    …
2414  F032.PIB.FLU.R.CLP.HIST.Z.Z.0.T    QUARTERLY      PIB, volumen a precios del año anterior encadenado…    …
2415  F032.PIB.FLU.R.CLP.HIST.Z.Z.3.T    QUARTERLY      PIB, volumen a precios del año anterior encadenado…    …
2416  F032.PIB.FLU.R.CLP.HIST13.Z.Z.0.T  QUARTERLY      PIB, volumen a precios del año anterior encadenado…    …
2417  F032.PIB.FLU.R.CLP.HIST13.Z.Z.3.T  QUARTERLY      PIB, volumen a precios del año anterior encadenado…    …
Step 2: Query each series separately

From the previous results, we will use F032.IMC.IND.Z.Z.EP18.Z.Z.0.M (IMACEC) and F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T (GDP):

In[8]:
# Query IMACEC (monthly)
url_imacec_data <- paste0(
  "https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=", token,
  "&function=GetSeries&timeseries=F032.IMC.IND.Z.Z.EP18.Z.Z.0.M",
  "&firstdate=2024-01-01&lastdate=2025-09-30"
)

json_imacec_data <- rjson::fromJSON(file = url_imacec_data)
obs_imacec <- as.data.frame(do.call(rbind, lapply(json_imacec_data$Series$Obs, as.vector)))
obs_imacec$value <- as.numeric(obs_imacec$value)
obs_imacec$indexDateString <- as.character(obs_imacec$indexDateString)
colnames(obs_imacec)[colnames(obs_imacec) == "value"] <- "IMACEC"

cat("IMACEC:", nrow(obs_imacec), "monthly observations\n")
print(tail(obs_imacec, 5))
Out[8]:
IMACEC: 21 monthly observations

   indexDateString    IMACEC  statusCode
17      01-05-2025  112.9508        OK
18      01-06-2025  108.3882        OK
19      01-07-2025  109.0397        OK
20      01-08-2025  110.4461        OK
21      01-09-2025  109.1529        OK
In[9]:
# Query GDP (quarterly)
url_gdp_data <- paste0(
  "https://si3.bcentral.cl/SieteRestWS/SieteRestWS.ashx?token=", token,
  "&function=GetSeries&timeseries=F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T",
  "&firstdate=2024-01-01&lastdate=2025-09-30"
)

json_gdp_data <- rjson::fromJSON(file = url_gdp_data)
obs_gdp <- as.data.frame(do.call(rbind, lapply(json_gdp_data$Series$Obs, as.vector)))
obs_gdp$value <- as.numeric(obs_gdp$value)
obs_gdp$indexDateString <- as.character(obs_gdp$indexDateString)
colnames(obs_gdp)[colnames(obs_gdp) == "value"] <- "GDP"

cat("GDP:", nrow(obs_gdp), "quarterly observations\n")
print(obs_gdp)
Out[9]:
GDP: 7 quarterly observations

  indexDateString      GDP  statusCode
1      01-01-2024  51629.65        OK
2      01-04-2024  51347.89        OK
3      01-07-2024  51072.57        OK
4      01-10-2024  55879.02        OK
5      01-01-2025  52974.86        OK
6      01-04-2025  53039.11        OK
7      01-07-2025  51879.68        OK
Step 3: Combine both series with different frequencies

Although the REST service requires querying each series separately, we can combine them in a DataFrame using R to show both series together:

In[10]:
# Prepare dates for merge
obs_imacec$fecha_date <- as.Date(obs_imacec$indexDateString, format = "%d-%m-%Y")
obs_gdp$fecha_date <- as.Date(obs_gdp$indexDateString, format = "%d-%m-%Y")

# Create monthly date sequence
all_dates <- seq(from = as.Date("2024-01-01"),
                           to = as.Date("2025-08-01"),
                           by = "month")

# Base data frame wuth all dates
combined_data <- data.frame(
  fecha = format(all_dates, "%d-%m-%Y"),
  fecha_date = all_dates,
  stringsAsFactors = FALSE
)

# Add IMACEC and GDP
combined_data <- merge(combined_data, obs_imacec[, c("fecha_date", "IMACEC")],
                           by = "fecha_date", all.x = TRUE)
combined_data <- merge(combined_data, obs_gdp[, c("fecha_date", "GDP")],
                           by = "fecha_date", all.x = TRUE)

# Select final columns
combined_data <- combined_data[, c("fecha", "IMACEC", "GDP")]

cat("Combined data (original frequency):\n")
print(head(combined_data, 8))
Out[10]:
Combined data (original frequency):

       fecha    IMACEC      GDP
1  01-01-2024  107.8681  51629.65
2  01-02-2024  104.1512       NA
3  01-03-2024  115.0355       NA
4  01-04-2024  111.1590  51347.89
5  01-05-2024  109.1826       NA
6  01-06-2024  104.9283       NA
7  01-07-2024  107.0739  51072.57
8  01-08-2024  110.1638       NA

As we can see in the result, it is possible to combine series with different frequencies. IMACEC has monthly values, while GDP only has quarterly values (January, April, July, October). Therefore, in the intermediate dates, NA values appear for GDP, since those months do not correspond to its quarterly frequency.


Downloadable Complete Example

Download the complete script with all executable examples:

Includes detailed examples for the observed dollar, GDP, IMACEC, handling different frequencies and transparent construction of REST URLs with R.

The Central Bank of Chile's SOAP service provides access to statistical data via a WSDL file (Web Services Description Language). This interface is ideal for enterprise development environments such as C# and Java, where a client can be generated automatically from the WSDL.

The WSDL file fully describes the SOAP service, including available methods, their parameters and response formats. Development environments can import this file to automatically generate the required client classes.

Main WSDL

https://si3.bcentral.cl/SieteWS/SieteWS.asmx?wsdl

Available Methods

  • SearchSeries - Search series by frequency in the catalog
  • GetSeries - Get data for a specific series
Consistency with REST: SOAP service methods are exactly the same as REST methods. They share the same names, parameters and return the same information; only the invocation mechanism differs.
Advantages of the SOAP service: Automatic client code generation, strong typing, and better integration in enterprise environments and frameworks like .NET and Java EE.

The SOAP service uses traditional BDE username and password authentication, not a token. These are sent as parameters in each method call.

Note: If you do not have BDE credentials, first review the instructions in Do you have an account in the BDE? to create your account, and then in How to enable the API? to enable API usage. Once completed, your BDE username and password will be your credentials to consume the SOAP API.

Required authentication parameters

  • user: Your registered BDE email
  • pass: Your BDE access password

These parameters must be included in each SOAP call along with the specific parameters of the method you want to use.

Practical implementation: To see how credentials are used in practice, see the "C# Example" section.

The Central Bank of Chile's SOAP service offers two main methods to interact with the Statistical Database. These methods are invoked via SOAP clients (typically generated by development environments), allowing direct calls to the service functions:


Method 1: SearchSeries

Returns the full catalog of available series filtered by temporal frequency. This is useful to explore which series are available before requesting specific data. Relevant data is in the SeriesInfos property of the SearchSeriesResult response object.

Parameters:

  • user (string, required): Registered user email
  • pass (string, required): User password
  • frequency (string, required): Temporal frequency (DAILY, MONTHLY, QUARTERLY, ANNUAL)

Output: SOAP object with the full list of series for the requested frequency. The data is in SeriesInfos, including series code, Spanish and English titles, frequency, first and last observation dates, and creation/update timestamps.

Output structure:

SearchSeriesResponse
 └── SearchSeriesResult (Response)
      ├── Codigo (0 = OK, ≠0 = Error)
      ├── Descripcion (description)
      └── SeriesInfos (ArrayOfInternetSeriesInfo)
           ├── internetSeriesInfo (one per series)
           │    ├── seriesId
           │    ├── frequency (DAILY, MONTHLY, QUARTERLY, etc.)
           │    ├── frequencyCode
           │    ├── spanishTitle
           │    ├── englishTitle
           │    ├── firstObservation
           │    ├── lastObservation
           │    ├── updatedAt
           │    └── createdAt
           └── ...

Method 2: GetSeries

Retrieves historical data (observations) for a specific statistical series. You can define date ranges to limit the query and retrieve only the period of interest. Relevant data is in the obs property inside Series of the response object.

Parameters:

  • user (string, required): Registered user email
  • password (string, required): User password
  • firstDate (string, optional): Start date in YYYY-MM-DD format
  • lastDate (string, optional): End date in YYYY-MM-DD format
  • seriesIds (array, required): Array of series codes to query
Important: In the seriesIds array only one series can be included per request. If more than one series is sent in the array, the query will return an error. To query multiple series, you must make separate requests for each series.

Output: SOAP object with the historical data of the requested series in the specified date range. The data is in Series, where each fameSeries contains the observations (obs) with dates and numeric values.

Response structure:

GetSeriesResponse
 └── GetSeriesResult (Response)
      ├── Codigo (0 = OK, ≠0 = Error)
      ├── Descripcion (description)
      ├── Series
      │    └── fameSeries (one per requested series)
      │           ├── seriesKey
      │           ├── precision
      │           └── obs (observations)
      │                   ├── indexDateString (date)
      │                   ├── seriesKey
      │                   ├── statusCode
      │                   └── value (double, numeric value)
      └── SeriesInfos
           └── internetSeriesInfo (metadata per series)
                   ├── seriesId
                   ├── frequency (DAILY, MONTHLY, QUARTERLY, etc.)
                   ├── frequencyCode
                   ├── spanishTitle
                   ├── englishTitle
                   ├── firstObservation
                   ├── lastObservation
                   ├── updatedAt
                   └── createdAt
Important note: Always check Codigo and Descripcion in the response. Codigo = 0 means success; any other value indicates an error or no results. The Descripcion field will indicate whether the operation was successful or describe the error otherwise.

This example shows how to consume the SOAP service from a C# application using the client automatically generated from the WSDL. Here you can see in practice how credentials are used and how to access the data.

Generate the client

The SOAP client generation process has different approaches depending on the .NET version:

  • .NET Framework: Referencia Web tradicional (Add Service Reference)
  • .NET 5/6/7/8: WCF Connected Services

Specific details of the configuration process can be found in the technical manual available below.

https://si3.bcentral.cl/SieteWS/SieteWS.asmx?wsdl
Differences in code by .NET version

Once the client is generated, there are important differences in implementation depending on the .NET version you use:

Aspect .NET Framework .NET 5/6/7/8
Main Method static void Main(string[] args) static async Task Main()
Instantiate Client SieteWS client = new SieteWS(); SieteWSSoapClient client = new SieteWSSoapClient(SieteWSSoapClient.EndpointConfiguration.SieteWSSoap);
Method Calls client.SearchSeries(...)
client.GetSeries(...)
await client.SearchSeriesAsync(...)
await client.GetSeriesAsync(...)

Note: These differences are due to changes in .NET architecture. In .NET 5/6/7/8 all methods are asynchronous by default.


Initial Configuration

First we define the credentials that we will use in all examples:

C#:
// Credentials (replace with your own)
string user = "user@example.com";
string pass = "password";

Example: Search and Query the Observed Dollar

Step 1: Search for the series

First we search for series related to "observed dollar" using SearchSeries with daily frequency:

.NET Framework
In[1]:
using (SieteWS client = new SieteWS())
{
    Respuesta busquedaDolar = client.SearchSeries(user, pass, "DAILY");
    int seriesEncontradas = 0;

    if (busquedaDolar.Codigo == 0)
    {
        foreach (internetSeriesInfo serie in busquedaDolar.SeriesInfos)
        {
            if (serie.spanishTitle.ToLower().Contains("dólar observado"))
            {
                seriesEncontradas++;
                Console.WriteLine($"{serie.seriesId}: {serie.spanishTitle}");
            }
        }

        Console.WriteLine($"Found {seriesEncontradas} series related to 'dólar observado'");
    }
    else
    {
        Console.WriteLine($"Query error: {busquedaDolar.Descripcion}");
    }
}
.NET 5/6/7/8
In[1]:
using (var client = new SieteWSSoapClient(SieteWSSoapClient.EndpointConfiguration.SieteWSSoap))
{
    Respuesta busquedaDolar = await client.SearchSeriesAsync(user, pass, "DAILY");
    int seriesEncontradas = 0;

    if (busquedaDolar.Codigo == 0)
    {
        foreach (internetSeriesInfo serie in busquedaDolar.SeriesInfos)
        {
            if (serie.spanishTitle.ToLower().Contains("dólar observado"))
            {
                seriesEncontradas++;
                Console.WriteLine($"{serie.seriesId}: {serie.spanishTitle}");
            }
        }

        Console.WriteLine($"Found {seriesEncontradas} series related to 'dólar observado'");
    }
    else
    {
        Console.WriteLine($"Query error: {busquedaDolar.Descripcion}");
    }
}
Out[1]:
F073.TCO.PRE.Z.D: Tipo de cambio nominal (dólar observado $CLP/USD); tipo de cambio; ; precio; diario; ; Banco Central de Chile; ;
Found 1 series related to 'dólar observado'
Step 2: Retrieve the data

Now we query the observed dollar data for the last year using the F073.TCO.PRE.Z.D code:

.NET Framework
In[2]:
string[] seriesDolar = { "F073.TCO.PRE.Z.D" };
string firstDate = "2024-09-01";
string lastDate = "2025-09-30";
using (SieteWS client = new SieteWS())
{
    Respuesta datosDolar = client.GetSeries(user, pass, firstDate, lastDate, seriesDolar);

    if (datosDolar.Codigo == 0)
    {
        var observaciones = datosDolar.Series[0].obs;

        Console.WriteLine($"Retrieved: {observaciones.Length} observations");
        Console.WriteLine("Last 10 values:");
        for (int i = Math.Max(0, observaciones.Length - 10); i < observaciones.Length; i++)
        {
            Console.WriteLine($"{observaciones[i].indexDateString}: {observaciones[i].value}");
        }
    }
    else
    {
        Console.WriteLine($"Query error: {datosDolar.Descripcion}");
    }
}
.NET 5/6/7/8
In[2]:
string[] seriesDolar = { "F073.TCO.PRE.Z.D" };
string firstDate = "2024-09-01";
string lastDate = "2025-09-30";
using (var client = new SieteWSSoapClient(SieteWSSoapClient.EndpointConfiguration.SieteWSSoap))
{
    Respuesta datosDolar = await client.GetSeriesAsync(user, pass, firstDate, lastDate, seriesDolar);

    if (datosDolar.Codigo == 0)
    {
        var observaciones = datosDolar.Series[0].obs;

        Console.WriteLine($"Retrieved: {observaciones.Length} observations");
        Console.WriteLine("Last 10 values:");
        for (int i = Math.Max(0, observaciones.Length - 10); i < observaciones.Length; i++)
        {
            Console.WriteLine($"{observaciones[i].indexDateString}: {observaciones[i].value}");
        }
    }
    else
    {
        Console.WriteLine($"Query error: {datosDolar.Descripcion}");
    }
}
Out[2]:
Retrieved: 394 observations
Last 10 values:
21-09-2025: NaN
22-09-2025: 951,03
23-09-2025: 954,72
24-09-2025: 952,87
25-09-2025: 953,24
26-09-2025: 956,42
27-09-2025: NaN
28-09-2025: NaN
29-09-2025: 958,9
30-09-2025: 961,24
Step 3: Compute basic statistics

With the values obtained, we filter the valid values and compute basic statistics:

.NET Framework
In[3]:
var valores = observaciones.Where(o => !double.IsNaN(o.value)).Select(o => o.value).ToArray();
Console.WriteLine("\\nObserved Dollar Statistics:");
Console.WriteLine($"Minimum value: ${valores.Min():F2}");
Console.WriteLine($"Maximum value: ${valores.Max():F2}");
Console.WriteLine($"Average value: ${valores.Average():F2}");
Console.WriteLine($"Last observation: ${valores.Last():F2}");
.NET 5/6/7/8
In[3]:
var valores = observaciones.Where(o => !double.IsNaN(o.value)).Select(o => o.value).ToArray();
Console.WriteLine("\\nObserved Dollar Statistics:");
Console.WriteLine($"Minimum value: ${valores.Min():F2}");
Console.WriteLine($"Maximum value: ${valores.Max():F2}");
Console.WriteLine($"Average value: ${valores.Average():F2}");
Console.WriteLine($"Last observation: ${valores.Last():F2}");
Out[3]:
Observed Dollar Statistics:
Minimum value: $896.25
Maximum value: $1012.76
Average value: $955.93
Last observation: $961.24

Example 2: GDP and IMACEC with different frequencies

In this example we will work with two economic indicators that have different frequencies: IMACEC (monthly) and GDP (quarterly). This shows how to combine series with different periodicities.

Step 1: Search for the series

First we search for both series separately according to their frequency:

.NET Framework
In[4]:
using (SieteWS client = new SieteWS())
{
    // Search for IMACEC (MONTHLY frequency)
    Respuesta busquedaImacec = client.SearchSeries(user, pass, "MONTHLY");
    if (busquedaImacec.Codigo == 0)
    {
        int seriesImacec = 0;
        foreach (internetSeriesInfo serie in busquedaImacec.SeriesInfos)
        {
            if (serie.spanishTitle.ToLower().Contains("imacec empalmado"))
            {
                seriesImacec++;
                Console.WriteLine($"{serie.seriesId}: {serie.spanishTitle}");
            }
        }
        Console.WriteLine($"Series found for IMACEC: {seriesImacec}");
    }
    else
    {
        Console.WriteLine($"Query error: {busquedaImacec.Descripcion}");
    }

    // Search for GDP (QUARTERLY frequency)
    Respuesta busquedaGDP = client.SearchSeries(user, pass, "QUARTERLY");

    if (busquedaGDP.Codigo == 0)
    {
        int seriesGDP = 0;
        foreach (internetSeriesInfo serie in busquedaGDP.SeriesInfos)
        {
            if (serie.spanishTitle.ToLower().Contains("pib, volumen a precios del año anterior encadenado, referencia"))
            {
                seriesGDP++;
                Console.WriteLine($"{serie.seriesId}: {serie.spanishTitle}");
            }
        }
        Console.WriteLine($"Series found for GDP: {seriesGDP}");
    }
    else
    {
        Console.WriteLine($"Query error: {busquedaGDP.Descripcion}");
    }
}
.NET 5/6/7/8
In[4]:
using (var client = new SieteWSSoapClient(SieteWSSoapClient.EndpointConfiguration.SieteWSSoap))
{
    // Search for IMACEC (MONTHLY frequency)
    Respuesta busquedaImacec = await client.SearchSeriesAsync(user, pass, "MONTHLY");
    if (busquedaImacec.Codigo == 0)
    {
        int seriesImacec = 0;
        foreach (internetSeriesInfo serie in busquedaImacec.SeriesInfos)
        {
            if (serie.spanishTitle.ToLower().Contains("imacec empalmado"))
            {
                seriesImacec++;
                Console.WriteLine($"{serie.seriesId}: {serie.spanishTitle}");
            }
        }
        Console.WriteLine($"Series found for IMACEC: {seriesImacec}");
    }
    else
    {
        Console.WriteLine($"Query error: {busquedaImacec.Descripcion}");
    }

    // Search for GDP (QUARTERLY frequency)
    Respuesta busquedaPIB = await client.SearchSeriesAsync(user, pass, "QUARTERLY");

    if (busquedaPIB.Codigo == 0)
    {
        int seriesPIB = 0;
        foreach (internetSeriesInfo serie in busquedaPIB.SeriesInfos)
        {
            if (serie.spanishTitle.ToLower().Contains("pib, volumen a precios del año anterior encadenado, referencia"))
            {
                seriesPIB++;
                Console.WriteLine($"{serie.seriesId}: {serie.spanishTitle}");
            }
        }
        Console.WriteLine($"Series found for GDP: {seriesGDP}");
    }
    else
    {
        Console.WriteLine($"Query error: {busquedaPIB.Descripcion}");
    }
}
Out[4]:
F032.IMC.IND.Z.Z.EP13.Z.Z.0.M: Imacec empalmado, serie original (índice 2013=100)
F032.IMC.IND.Z.Z.EP13.Z.Z.1.M: Imacec empalmado, desestacionalizado (índice 2013=100)
F032.IMC.IND.Z.Z.EP18.Z.Z.0.M: Imacec empalmado, serie original (índice 2018=100)
F032.IMC.IND.Z.Z.EP18.Z.Z.1.M: Imacec empalmado, desestacionalizado (índice 2018=100)
Series found for IMACEC: 4
F032.PIB.FLU.R.CLP.2008.Z.Z.0.T: GDP, volume at previous year prices linked, reference 2008 (millions of linked pesos)
F032.PIB.FLU.R.CLP.2008.Z.Z.1.T: GDP, volume at previous year prices linked, reference 2008 (seasonally adjusted)
F032.PIB.FLU.R.CLP.EP08.Z.Z.0.T: GDP, volume at previous year prices linked, reference 2008 (millions of linked pesos)
F032.PIB.FLU.R.CLP.EP13.Z.Z.0.T: GDP, volume at previous year prices linked, reference 2013 (billions of linked pesos)
F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T: GDP, volume at previous year prices linked, reference 2018 (billions of linked pesos)
Series found for GDP: 5
Step 2: Query each series separately

From the results above, we will use F032.IMC.IND.Z.Z.EP18.Z.Z.0.M (IMACEC) and F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T (GDP):

.NET Framework
In[5]:
// Query IMACEC (monthly)
string[] seriesIMACEC = { "F032.IMC.IND.Z.Z.EP18.Z.Z.0.M" };
using (SieteWS client = new SieteWS())
{
    Respuesta datosIMACEC = client.GetSeries(user, pass, "2024-01-01", "2025-09-30", seriesIMACEC);
    if (datosIMACEC.Codigo == 0)
    {
        var obsIMACEC = datosIMACEC.Series[0].obs;

        Console.WriteLine($"IMACEC: {obsIMACEC.Length} monthly observations");
        Console.WriteLine("Last 5 observations:");

        for (int i = Math.Max(0, obsIMACEC.Length - 5); i < obsIMACEC.Length; i++)
        {
            Console.WriteLine($"{i + 1} {obsIMACEC[i].indexDateString} {obsIMACEC[i].value:F4}");
        }
    }
    else
    {
        Console.WriteLine($"Query error: {datosIMACEC.Descripcion}");
    }
}

// Query GDP (quarterly)
string[] seriesPIB = { "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T" };
using (SieteWS client = new SieteWS())
{
    Respuesta datosPIB = client.GetSeries(user, pass, "2024-01-01", "2025-09-30", seriesPIB);
    if (datosPIB.Codigo == 0)
    {
        var obsPIB = datosPIB.Series[0].obs;
        Console.WriteLine($"GDP: {obsPIB.Length} quarterly observations");

        foreach (var obs in obsPIB)
        {
            Console.WriteLine($"{obs.indexDateString} {obs.value:F2}");
        }
    }
    else
    {
        Console.WriteLine($"Query error: {datosPIB.Descripcion}");
    }
}
.NET 5/6/7/8
In[5]:
// Query IMACEC (monthly)
string[] seriesIMACEC = { "F032.IMC.IND.Z.Z.EP18.Z.Z.0.M" };
using (var client = new SieteWSSoapClient(SieteWSSoapClient.EndpointConfiguration.SieteWSSoap))
{
    Respuesta datosIMACEC = await client.GetSeriesAsync(user, pass, "2024-01-01", "2025-09-30", seriesIMACEC);
    if (datosIMACEC.Codigo == 0)
    {
        var obsIMACEC = datosIMACEC.Series[0].obs;

        Console.WriteLine($"IMACEC: {obsIMACEC.Length} monthly observations");
        Console.WriteLine("Last 5 observations:");

        for (int i = Math.Max(0, obsIMACEC.Length - 5); i < obsIMACEC.Length; i++)
        {
            Console.WriteLine($"{i + 1} {obsIMACEC[i].indexDateString} {obsIMACEC[i].value:F4}");
        }
    }
    else
    {
        Console.WriteLine($"Query error: {datosIMACEC.Descripcion}");
    }
}

// Query GDP (quarterly)
string[] seriesPIB = { "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T" };
using (var client = new SieteWSSoapClient(SieteWSSoapClient.EndpointConfiguration.SieteWSSoap))
{
    Respuesta datosPIB = await client.GetSeriesAsync(user, pass, "2024-01-01", "2025-09-30", seriesPIB);
    if (datosPIB.Codigo == 0)
    {
        var obsPIB = datosPIB.Series[0].obs;
        Console.WriteLine($"GDP: {obsPIB.Length} quarterly observations");

        foreach (var obs in obsPIB)
        {
            Console.WriteLine($"{obs.indexDateString} {obs.value:F2}");
        }
    }
    else
    {
        Console.WriteLine($"Query error: {datosPIB.Descripcion}");
    }
}
Out[5]:
IMACEC: 21 monthly observations
Last 5 observations:
17 01-05-2025 112,9508
18 01-06-2025 108,3882
19 01-07-2025 109,0397
20 01-08-2025 110,4461
21 01-09-2025 109,1529
GDP: 7 quarterly observations
1 01-01-2024 51629,65
2 01-04-2024 51347,89
3 01-07-2024 51072,57
4 01-10-2024 55879,02
5 01-01-2025 52974,86
6 01-04-2025 53039,11
7 01-07-2025 51879,68
Step 3: Combine both series with different frequencies

Finally, we combine IMACEC (monthly) and GDP (quarterly) for joint analysis:

.NET Framework
In[6]:
string[] seriesIMACEC = { "F032.IMC.IND.Z.Z.EP18.Z.Z.0.M" };
string[] seriesPIB = { "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T" };

using (SieteWS client = new SieteWS())
{
    Respuesta datosIMACEC = client.GetSeries(user, pass, "2024-01-01", "2025-09-30", seriesIMACEC);
    var obsIMACEC = datosIMACEC.Series[0].obs;

    Respuesta datosPIB = client.GetSeries(user, pass, "2024-01-01", "2025-09-30", seriesPIB);
    var obsPIB = datosPIB.Series[0].obs;

    // Prepare combined data
    var datosCombinados = new List<dynamic>();

    // Generate monthly base dates
    var fechasBase = new List<DateTime>();
    for (var fecha = new DateTime(2024, 1, 1); fecha <= new DateTime(2025, 8, 1); fecha = fecha.AddMonths(1))
    {
        fechasBase.Add(fecha);
    }

    // Combine IMACEC and GDP data
    foreach (var fecha in fechasBase)
    {
        string fechaStr = fecha.ToString("dd-MM-yyyy");
        var imacecObs = obsIMACEC.FirstOrDefault(o => o.indexDateString == fechaStr);
        var pibObs = obsPIB.FirstOrDefault(o => o.indexDateString == fechaStr);

        datosCombinados.Add(new
        {
            Fecha = fechaStr,
            IMACEC = imacecObs?.value.ToString("F4") ?? "NA",
            PIB = pibObs?.value.ToString("F2") ?? "NA"
        });
    }

    Console.WriteLine("Combined (original frequency):");
    Console.WriteLine();
    Console.WriteLine(" fecha IMACEC PIB");
    // Print only the first 8
    for (int i = 0; i < Math.Min(8, datosCombinados.Count); i++)
    {
        var dato = datosCombinados[i];
        Console.WriteLine($"{i + 1} {dato.Fecha} {dato.IMACEC,8} {dato.PIB,8}");
    }
}
.NET 5/6/7/8
In[6]:
string[] seriesIMACEC = { "F032.IMC.IND.Z.Z.EP18.Z.Z.0.M" };
string[] seriesPIB = { "F032.PIB.FLU.R.CLP.EP18.Z.Z.0.T" };

using (var client = new SieteWSSoapClient(SieteWSSoapClient.EndpointConfiguration.SieteWSSoap))
{
    Respuesta datosIMACEC = await client.GetSeriesAsync(user, pass, "2024-01-01", "2025-09-30", seriesIMACEC);
    var obsIMACEC = datosIMACEC.Series[0].obs;

    Respuesta datosPIB = await client.GetSeriesAsync(user, pass, "2024-01-01", "2025-09-30", seriesPIB);
    var obsPIB = datosPIB.Series[0].obs;

    // Prepare combined data
    var datosCombinados = new List<dynamic>();

    // Generate base monthly dates
    var fechasBase = new List<DateTime>();
    for (var fecha = new DateTime(2024, 1, 1); fecha <= new DateTime(2025, 8, 1); fecha = fecha.AddMonths(1))
    {
        fechasBase.Add(fecha);
    }

    // Combine IMACEC and PIB data
    foreach (var fecha in fechasBase)
    {
        string fechaStr = fecha.ToString("dd-MM-yyyy");
        var imacecObs = obsIMACEC.FirstOrDefault(o => o.indexDateString == fechaStr);
        var pibObs = obsPIB.FirstOrDefault(o => o.indexDateString == fechaStr);

        datosCombinados.Add(new
        {
            Fecha = fechaStr,
            IMACEC = imacecObs?.value.ToString("F4") ?? "NA",
            PIB = pibObs?.value.ToString("F2") ?? "NA"
        });
    }

    Console.WriteLine("Combined data (original frequency):");
    Console.WriteLine();
    Console.WriteLine(" fecha IMACEC PIB");
    // Print only the first 8
    for (int i = 0; i < Math.Min(8, datosCombinados.Count); i++)
    {
        var dato = datosCombinados[i];
        Console.WriteLine($"{i + 1} {dato.Fecha} {dato.IMACEC,8} {dato.PIB,8}");
    }
}
Out[6]:
Combined data (original frequency):

        fecha    IMACEC      GDP
1  01-01-2024  107.8681  51629.65
2  01-02-2024  104.1512       NA
3  01-03-2024  115.0355       NA
4  01-04-2024  111.1590  51347.89
5  01-05-2024  109.1826       NA
6  01-06-2024  104.9283       NA
7  01-07-2024  107.0739  51072.57
8  01-08-2024  110.1638       NA

Below is the WSDL file for download, a sample C# application, and a technical manual that shows how to use the SOAP service in C# with examples of how to use the WSDL and methods in Visual Studio for different .NET versions: