The official TRM is published as open data on datos.gov.co and is queried with one unauthenticated HTTP request; the valor field arrives as text and one value can apply to several days, so filter by date and cache the result.
1. What the TRM is and where it is published#
The Representative Market Rate (TRM, Tasa Representativa del Mercado) is the official value of the dollar in Colombian pesos. The dataset «Tasa de Cambio Representativa del Mercado - TRM» is published by the Financial Superintendence of Colombia on the datos.gov.co open data portal, which exposes it as a query API (JSON format) with four fields.
| Field | What it holds | Example |
|---|---|---|
| valor | Pesos per dollar, as text | 3181.74 |
| unidad | Currency of the quote | COP |
| vigenciadesde | First day it applies | 2026-10-14T00:00:00.000 |
| vigenciahasta | Last day it applies | 2026-10-14T00:00:00.000 |
The API asks for no account or key for simple queries. The valor field arrives as text with a decimal point, and vigenciadesde and vigenciahasta mark the first and last day the value applies. On weekends and holidays one value covers several days: on October 17, 2026 the API returned 3,174.67 valid from October 17 to 19.
Documentation: Open Data Colombia: TRM (Financial Superintendence of Colombia) ↗
2. Querying the TRM for a date in Python#
The function filters the records whose validity includes the requested day. It uses only the standard library and Decimal so as not to accumulate floating-point errors in money. The example queries October 14, 2026 and converts a plan of 25 dollars a month.
import json
from decimal import Decimal
from urllib.parse import urlencode
from urllib.request import urlopen
URL = "https://www.datos.gov.co/resource/32sa-8pi3.json"
def trm_on(day: str) -> Decimal:
"""TRM in force on a date (YYYY-MM-DD), in pesos per dollar."""
condition = f"vigenciadesde <= '{day}T00:00:00.000' AND vigenciahasta >= '{day}T00:00:00.000'"
with urlopen(f"{URL}?" + urlencode({"$where": condition}), timeout=15) as r:
rows = json.load(r)
if not rows:
raise LookupError(f"no TRM for {day}")
return Decimal(rows[0]["valor"])
trm = trm_on("2026-10-14")
print(trm) # 3181.74
print(f"{Decimal(25) * trm:,.2f} COP") # a 25 USD a month planDocumentation: Socrata: consultas con $where ↗ · Python: urllib.request ↗
3. The same query in JavaScript#
With fetch, available in Node.js and in the browser. The script runs as a module so it can use top-level await. It formats the result with Intl in es-CO.
const URL_TRM = "https://www.datos.gov.co/resource/32sa-8pi3.json";
async function trmOn(day) {
const condition = `vigenciadesde <= '${day}T00:00:00.000' AND vigenciahasta >= '${day}T00:00:00.000'`;
const res = await fetch(`${URL_TRM}?` + new URLSearchParams({ $where: condition }));
if (!res.ok) throw new Error(`datos.gov.co answered ${res.status}`);
const rows = await res.json();
if (rows.length === 0) throw new Error(`no TRM for ${day}`);
return Number(rows[0].valor);
}
const trm = await trmOn("2026-10-14");
console.log(trm, (25 * trm).toLocaleString("es-CO", { style: "currency", currency: "COP" }));If you call the API from the browser, each visitor makes their own request; for a public page it is better to query it from your server and store the value.
Documentation: MDN: Fetch API ↗
4. Good practices#
- Cache the day's value and do not call the API on every user request.
- Keep the value's date next to the value, and show it: a price in pesos without a TRM date is not verifiable.
- Have a fallback value with its date for when the API does not answer, and do not invent a rate.
- Use Decimal (Python) or integer cents for money, and leave rounding for the end.
- Treat an empty response as a normal case: there may be no record for a future date.
For international prices, the TRM is an official Colombian reference, not the exchange rate your bank or card will charge, which adds its own margin and fees.
5. How Codifly uses it#
The catalog pages show the peso equivalent of each price with the TRM from this same source, with its date, and fall back to a dated reserve value when the query fails. You can see the result in the database and cloud comparators.
Go deeperWhat an AI API really costs in Latin American currencies (September 2026)
6. Keep your numbers current#
The values in this guide are those the API returned on October 18, 2026. The dataset and its fields may change, so check the official record before depending on them in production.
- Check the dataset record if the API changes shape.
- Test your code with a weekend date and with a date that has no record.
- Log a warning when you use the fallback value.
Sources and scope
Documentation checked on October 18, 2026. Examples and decision criteria are editorial proposals; adapt them to your application's contract and validate them in an authorized test environment.