Free Public APIs Every Backend Developer Should Know
Integrating external APIs is routine work in backend development. The challenge is finding out which ones exist, what they actually offer for free, and how to integrate them reliably. This article is a commented catalog — with real limitations and production tips.
🇧🇷 Addresses and Locations
ViaCEP
URL: https://viacep.com.br/ws/{cep}/json/
Auth: None
Limit: Undocumented
Countries: 🇧🇷 Brazil
Returns street, neighborhood, city and state from a Brazilian postal code. Also supports reverse lookup by street name + municipality + state.
Strengths: zero configuration, consistent response, widely adopted.
Limitations: no public SLA and no declared rate limit — aggressive caching is mandatory.
BrasilAPI
URL: https://brasilapi.com.br/api/
Auth: None
Limit: Undocumented
Countries: 🇧🇷 Brazil
A hub of Brazilian public data. One dependency, many useful endpoints:
GET /cep/v2/{cep}— postal code via multiple sources, more robust than ViaCEPGET /banks/v1— bank list with ISPB and COMPE codesGET /cnpj/v1/{cnpj}— full company registration dataGET /ddd/v1/{ddd}— state and cities by area codeGET /feriados/v1/{year}— national holidays by yearGET /taxas/v1— SELIC, CDI, savings rate and other financial indicesGET /ibge/municipios/v1/{uf}— municipalities by state
Strengths: unified API for official government data, open source, well maintained by the community.
Limitations: uptime depends on third-party sources — a circuit breaker is mandatory in production.
IBGE — Localities
URL: https://servicodados.ibge.gov.br/api/v1/localidades/
Auth: None
Limit: Undocumented
Countries: 🇧🇷 Brazil
Official geographic data: states, municipalities, mesoregions, microregions and districts. Ideal for validating addresses, populating dropdowns or generating regional reports.
Most used endpoints: /estados, /estados/{uf}/municipios, /municipios/{ibgeCode}.
💰 Financial Data
AwesomeAPI — Exchange Rates
URL: https://economia.awesomeapi.com.br/last/{pairs}
Auth: None
Limit: Undocumented
Countries: 🌍 Global
Real-time exchange rates for currencies (USD-BRL, EUR-BRL, GBP-BRL), cryptocurrencies (BTC-BRL, ETH-BRL) and Brazilian stocks (PETR4, VALE3). Offers history via /daily/{pair}/{days}.
Strengths: zero configuration, covers hundreds of pairs, updates every few minutes.
Limitations: no declared SLA — do not use as a sole source in critical payment systems. A 5–10 min cache is the minimum.
BrasilAPI — Rates and Indices
URL: https://brasilapi.com.br/api/taxas/v1
Auth: None
Limit: Undocumented
Countries: 🇧🇷 Brazil
Returns SELIC, CDI, CDB, savings rate and other financial indicators. Useful for investment simulators, monetary correction calculations and financial dashboards.
BACEN — PTAX
URL: https://olinda.bcb.gov.br/olinda/servico/PTAX/versao/v1/odata/
Auth: None
Limit: Undocumented
Countries: 🇧🇷 Brazil
Official exchange rates from the Brazilian Central Bank. PTAX is the reference rate used in financial contracts, settlements and monetary adjustments — more authoritative than commercial sources for legal or contractual purposes.
Most used endpoints:
GET /CotacaoDolarDia(dataCotacao=@d)?@d='MM-DD-YYYY'— USD rate for a given day (buy and sell)GET /CotacaoMoedaDia(moeda=@m,dataCotacao=@d)?@m='EUR'&@d='MM-DD-YYYY'— other currencies
Strengths: official government source, free, no authentication required.
Limitations: data is only available on Brazilian banking business days; the API uses OData, which can be verbose for simple use cases.
₿ Cryptocurrencies
CoinGecko
URL: https://api.coingecko.com/api/v3/
Auth: None (demo) / Free API key
Limit: 30 req/min
Countries: 🌍 Global
The largest free cryptocurrency market data API: real-time prices, OHLCV history, market cap, volume and metadata for 10,000+ tokens. Does not cover on-chain data (wallet balances, transactions or block exploration) — use Etherscan or Blockchain.com for that.
Most used endpoints:
GET /simple/price?ids=bitcoin,ethereum&vs_currencies=usd,brl— current price for multiple tokensGET /coins/{id}/market_chart?vs_currency=usd&days=30— price historyGET /coins/markets?vs_currency=usd&order=market_cap_desc— ranking by market cap
Strengths: comprehensive market coverage, no registration required for basic use, excellent documentation.
Limitations: 30 req/min without an API key — caching is mandatory. For higher production volumes, consider the paid plan.
Etherscan
URL: https://api.etherscan.io/v2/api?chainid=1
Auth: Free API key
Limit: 5 req/sec / 100,000 req/day
Countries: 🌍 Global (Multi-chain EVM)
The largest Ethereum network explorer. Query wallet balances, transaction history, ERC-20/ERC-721 token transfers, verified contracts and block data — all via REST API. The chainid parameter lets you use the same API key across multiple networks: Ethereum (1), Polygon (137), BNB Chain (56) and dozens of other compatible EVM networks.
Most used endpoints:
GET ?chainid=1&module=account&action=balance&address={address}— ETH balance of a walletGET ?chainid=1&module=account&action=tokentx&address={address}— ERC-20 token transfersGET ?chainid=1&module=block&action=getblocknobytime×tamp={ts}— block closest to a timestamp
Strengths: extensive documentation, real-time on-chain data, free for basic use, a single API key covers multiple EVM networks.
Limitations: requires registration to obtain an API key; free plan limits may be insufficient for batch queries.
Blockchain.com — Simple API
URL: https://blockchain.info/
Auth: None
Limit: Undocumented
Countries: 🌍 Global (Bitcoin)
Public API for Bitcoin on-chain data. No API key, no registration — direct access to wallet balances and transaction history.
Most used endpoints:
GET /balance?active={address}— BTC balance of one or more walletsGET /rawaddr/{address}— full transaction history for an addressGET /latestblock— most recent confirmed block
Strengths: zero configuration, Bitcoin data with no external provider dependency.
Limitations: Bitcoin only; no documented limit but susceptible to throttling at high volumes — caching is mandatory.
🏢 CNPJ and Companies
BrasilAPI — CNPJ
URL: https://brasilapi.com.br/api/cnpj/v1/{cnpj}
Auth: None
Limit: Undocumented
Countries: 🇧🇷 Brazil
Full company data from the Brazilian Revenue Service (Receita Federal): company name, trade name, CNAE codes, registration status, size, address and partner list.
Strengths: official data without requiring a digital certificate or special agreement.
Limitations: data reflects the last sync with Receita Federal — there may be a few hours lag.
🌤 Weather
Open-Meteo
URL: https://api.open-meteo.com/v1/forecast
Auth: None
Limit: 10,000 req/day
Countries: 🌍 Global
Open-source weather forecasts powered by multiple climate models (ECMWF, GFS, DWD). Covers hourly and daily forecasts as well as historical data back to 1940.
Strengths: no auth required, global coverage, excellent documentation, 80+ years of historical data.
Limitations: 10k req/day — a minimum 15-minute cache is mandatory.
🌐 IP Geolocation
ipapi.co
URL: https://ipapi.co/{ip}/json/
Auth: None
Limit: 1,000 req/day
Countries: 🌍 Global
Returns city, country, region, timezone, lat/lon, organization (ASN) and local currency. Omitting {ip} automatically uses the caller’s IP — useful for detecting a user’s country without login.
Strengths: rich data (ASN, currency, timezone), free HTTPS.
Limitations: 1k req/day is low for high-traffic production — per-session or per-IP caching is essential.
ip-api.com
URL: http://ip-api.com/json/{ip}
Auth: None
Limit: 45 req/min
Countries: 🌍 Global
Warning: the free plan is HTTP only — do not use in contexts where HTTPS is required. The paid plan enables HTTPS and raises the limit.
🌍 Geocoding and Geographic Data
Nominatim — OpenStreetMap
URL: https://nominatim.openstreetmap.org/
Auth: None
Limit: 1 req/sec (hard maximum by OpenStreetMap Foundation usage policy)
Countries: 🌍 Global
Geocoding and reverse geocoding powered by OpenStreetMap data. Converts addresses to coordinates and vice versa — free and with no registration.
Most used endpoints:
GET /search?q={address}&format=json— address → coordinatesGET /reverse?lat={lat}&lon={lon}&format=json— coordinates → full address
Strengths: free, no auth, global coverage, open-source data.
Limitations: the 1 req/s limit is hard and applies to the entire application (sum of all users). Not suitable for batch geocoding — for higher volumes, consider self-hosting Photon or using Geoapify.
CountriesNow
URL: https://countriesnow.space/api/v0.1/
Auth: None
Limit: Undocumented
Countries: 🌍 Global (222 countries)
Structured data for 222 countries and territories: name, capital, ISO code, dialing code, timezone, population, currency, language and flags (SVG). Free API, no registration, actively maintained.
Most used endpoints:
GET /countries— full list with ISO2, ISO3 and cities (227 countries)GET /countries/flag/images— list with flag URLs (SVG)GET /countries/currency— list with currency and ISO code per countryPOST /countries/capital— capital of a specific country (body:{"country":"Brazil"})
Strengths: no auth, global coverage, includes flags and demographic data, clean JSON.
Limitations: no native pagination — returns complete lists; keep a local cache (TTL 24h+) to avoid repeating the call on every request.
🔒 Security
Have I Been Pwned
URL: https://api.pwnedpasswords.com/range/{prefix}
Auth: None (passwords) / paid API key (emails)
Limit: Undocumented (returns 429 on abuse)
Countries: 🌍 Global
Checks whether a password has appeared in known data breaches using k-anonymity: you send only the first 5 characters of the SHA-1 hash. The server returns all hashes with that prefix and comparison happens locally — the full password never travels over the network.
Strengths: privacy by design, database with billions of leaked passwords, completely free for passwords.
Limitations: checking compromised email addresses requires a paid API key ($3.50/month).
VirusTotal
URL: https://www.virustotal.com/api/v3/
Auth: Free API key
Limit: 4 req/min / 500 req/day
Countries: 🌍 Global
Analyzes URLs, files, domains and IPs against 70+ antivirus engines. Useful for validating user-submitted links or scanning uploaded files before processing them.
Hudson Rock — Cavalier
URL: https://cavalier.hudsonrock.com/api/json/v2/osint-tools/
Auth: None
Limit: Undocumented
Countries: 🌍 Global
Cybercrime intelligence focused on infostealer malware. Unlike HIBP — which indexes data from breaches and public dumps — Cavalier covers credentials stolen directly from victims’ devices by malware such as RedLine, Raccoon and Vidar.
Public endpoints:
GET /search-by-email?email={email}— checks if an email appears in infostealer logsGET /search-by-domain?domain={domain}— identifies compromised employees and systems for a domain
Strengths: covers a distinct attack vector from HIBP; no authentication required.
Limitations: large generic domains (e.g., google.com) may return 400; rate limit undocumented.
📅 Public Holidays
Nager.Date
URL: https://date.nager.at/api/v3/PublicHolidays/{year}/{country}
Auth: None
Limit: Undocumented
Countries: 🌍 100+ countries
National and regional public holidays in 100+ countries. Essential for business day calculations, SLAs and scheduling. Supports BR, US, DE, PT, ES and dozens of other ISO 3166-1 codes.
🧪 Dev and Prototyping
JSONPlaceholder
URL: https://jsonplaceholder.typicode.com/
Auth: None
Limit: No declared limit
Countries: 🌍 Global
Fully functional fake API: posts, users, todos, photos, albums, comments. Supports all HTTP verbs — PUT/PATCH/DELETE simulate without persisting. Ideal for testing HttpClient pipelines or generating sample data in demos without spinning up infrastructure.
PokeAPI
URL: https://pokeapi.co/api/v2/
Auth: None
Limit: 100 req/min
Countries: 🌍 Global
Complete Pokémon universe catalog. Has one of the best REST API documentations available — great for practicing pagination with limit/offset, caching and relationships in RESTful APIs.
⚙️ Integrating Reliably
The production pattern is always the same: typed HttpClient or Refit for the HTTP client, Polly for resilience and TTL-based cache to reduce latency and respect rate limits. Only the endpoint changes.
Typed HttpClient
IHttpClientFactory fixes two classic pitfalls of new HttpClient(): socket exhaustion — HttpClient must be reused across requests, never instantiated per call — and stale DNS — without the factory, the resolved DNS stays locked in the socket indefinitely. The typed client wraps HttpClient in a domain-specific service class; you inject the class, not HttpClient directly.
When to use: projects with few external endpoints, or when you want full control over serialization and error handling without adding external dependencies.
// The HttpClient is injected already configured by IHttpClientFactory
public class ViaCepClient(HttpClient httpClient)
{
public Task<ViaCepResponse?> GetAddressAsync(string postalCode)
{
// Strip non-digit characters before building the URL
var digits = new string(postalCode.Where(char.IsDigit).ToArray());
return httpClient.GetFromJsonAsync<ViaCepResponse>($"/ws/{digits}/json/");
}
}
// Program.cs — registers the typed client with a centralized base URL
builder.Services.AddHttpClient<ViaCepClient>(client =>
client.BaseAddress = new Uri("https://viacep.com.br"));
Refit
Refit generates the HTTP client implementation from an annotated interface. You describe the API contract as an interface — Refit creates the concrete class at runtime via source generators. The interface also acts as living documentation of the contract.
When to use instead of typed HttpClient: when the API has many endpoints or you want to eliminate serialization and URL-building boilerplate. Downsides: it’s an external dependency and less flexible for very custom scenarios (large response streaming, complex multipart uploads).
// dotnet add package Refit.HttpClientFactory
// The interface declares endpoints — Refit generates the implementation at runtime
public interface IViaCepApi
{
[Get("/ws/{cep}/json/")]
Task<ViaCepResponse> GetAddressAsync(string cep);
}
// Program.cs — Refit and Polly chain into the same HttpClient pipeline
builder.Services.AddRefitClient<IViaCepApi>()
.ConfigureHttpClient(client =>
client.BaseAddress = new Uri("https://viacep.com.br"));
Refit and Polly integrate in the same chain: AddRefitClient<T>().ConfigureHttpClient(...).AddResilienceHandler(...).
Cache
Cache stores external call responses locally for a set period (TTL — Time to Live), avoiding repeated requests. Beyond reducing latency, it protects against rate limits and shields your application from momentary instability in the external dependency.
IMemoryCache — stores data in the process’s own memory. Simple, no additional latency. Critical limitation: not shared between instances. In horizontally scaled environments (multiple pods/containers), each instance holds its own isolated cache — inconsistencies are inevitable and the caching benefit is partially lost.
IDistributedCache with Redis — external cache shared across all instances. Mandatory when the application scales horizontally. Adds network latency (~1ms on LAN), but guarantees consistency and allows the cache to survive pod restarts.
// Program.cs
builder.Services.AddMemoryCache();
// In the service:
public async Task<ExchangeRate?> GetRateAsync(string pair)
{
var cacheKey = $"rate:{pair.ToUpper()}";
// Return immediately if the value is already cached
if (_cache.TryGetValue(cacheKey, out ExchangeRate? cached))
return cached;
var result = await _api.GetRateAsync(pair);
if (result is not null)
_cache.Set(cacheKey, result, new MemoryCacheEntryOptions
{
// Hard ceiling — expires regardless of access frequency
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
// Resets the TTL on each read — only expires if unused
SlidingExpiration = TimeSpan.FromMinutes(2),
});
return result;
}
Resilience with Polly
Polly is the resilience library for .NET. It implements stability patterns — retry, circuit breaker, timeout and bulkhead — that protect your application when external dependencies fail or slow down. In .NET 8+, Polly v8 is integrated directly via Microsoft.Extensions.Http.Resilience, with no need for manual pipeline setup.
Retry automatically retries transient failures (network timeouts, momentary 503s). Circuit Breaker stops trying when the dependency is clearly unavailable — it prevents a slow API from bringing down your whole application and gives the external service time to recover. Strategy order is critical: from inside out, each layer wraps the previous one.
builder.Services.AddHttpClient<ViaCepClient>(client =>
client.BaseAddress = new Uri("https://viacep.com.br"))
.AddResilienceHandler("viacep-pipeline", pipeline =>
{
// Timeout applied individually to each attempt
pipeline.AddTimeout(TimeSpan.FromSeconds(4));
pipeline.AddRetry(new HttpRetryStrategyOptions
{
// Maximum number of retries after the initial failure
MaxRetryAttempts = 3,
// Base delay before the first retry
Delay = TimeSpan.FromMilliseconds(500),
// Exponential: each retry doubles the previous delay (500ms → 1s → 2s)
BackoffType = DelayBackoffType.Exponential,
// Random variation on the delay to prevent simultaneous retry storms
UseJitter = true,
// Trigger retry on network exceptions or 5xx responses
ShouldHandle = args => ValueTask.FromResult(
args.Outcome.Exception is not null ||
args.Outcome.Result?.StatusCode >= HttpStatusCode.InternalServerError),
});
pipeline.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
// Time window used to calculate the failure rate
SamplingDuration = TimeSpan.FromSeconds(30),
// Minimum requests in the window before evaluating the circuit
MinimumThroughput = 5,
// Open the circuit if 50% or more of requests fail
FailureRatio = 0.5,
// How long the circuit stays open before attempting recovery
BreakDuration = TimeSpan.FromSeconds(15),
});
});
Strategy order matters: timeout → retry → circuit breaker, from inside out.
Official References
- Microsoft.Extensions.Http.Resilience — full Polly v8 integration docs
- Refit — documentation and advanced examples
- IMemoryCache — in-memory caching in ASP.NET Core
- IDistributedCache — distributed cache and Redis integration