10 APIs Gratuitas para Python — Uso Comercial, Código de Producción y Guía de Seguridad

Con APIs externas, los desarrolladores Python pueden implementar recuperación de datos, información financiera y procesamiento de imágenes sin construir todo desde cero. Sin embargo, «gratuito para usar» y «seguro para usar en producción» son dos cosas completamente diferentes.

Este artículo presenta 10 APIs gratuitas y prácticas para Python con código listo para producción, detalles de Rate Limit y patrones de diseño seguro. Más allá de una simple lista de APIs, cubrimos la filosofía de diseño que usan los profesionales al trabajar con APIs externas.

Nivel objetivo: Principiante a intermedio (capaz de usar requests). Requisito previo:

Bash
pip install requests

Para gestión segura de claves API, consulta también «10 Patrones de Implementación de Seguridad en Python

Plantilla Básica de Llamadas API

Antes de profundizar en APIs individuales, establezcamos la plantilla base que toda llamada API debe seguir. En producción, estos cuatro puntos son el estándar mínimo:

  • Establecer un timeout — evita que tu programa espere indefinidamente
  • Verificar códigos de estado — maneja correctamente las respuestas distintas de 200
  • Manejar excepciones — afronta fallos de red y timeouts
  • No asumir JSON — evita crashes cuando la respuesta es HTML o texto
basic_template.py
import requests

url = "https://api.example.com/data"

try:
    response = requests.get(url, timeout=5)
    response.raise_for_status()
    data = response.json()
    print(data)
except requests.exceptions.Timeout:
    print("Timeout: server not responding")
except requests.exceptions.HTTPError as e:
    print(f"HTTP error: {e.response.status_code}")
except requests.exceptions.RequestException as e:
    print(f"Request error: {e}")
except ValueError:
    print("JSON decode error: response is not JSON")
💡 Tip

Mantén esta plantilla como función de utilidad compartida en tu proyecto. Los ejemplos de código siguientes omiten el manejo de errores por brevedad, pero siempre aplica este patrón en código de producción.

Tabla Comparativa de APIs Gratuitas

APIPropósitoClave APIRate LimitComercialDificultad
① Open-MeteoDatos del climaNingunoFlexible★☆☆
② ExchangeRateTipos de cambioNinguno1.500/día★☆☆
③ CoinGeckoPrecios de criptoNinguno10–30/minVerificar ToS★☆☆
④ JSONPlaceholderPrueba/MockNingunoNinguno★☆☆
⑤ REST CountriesInfo de paísesNingunoFlexible★☆☆
⑥ The Cat APIImágenes de gatosOpcional10/min★☆☆
⑦ IP-APIGeolocalización por IPNinguno45/minSolo pago★☆☆
⑧ Advice SlipFrases aleatoriasNinguno1/2seg★☆☆
⑨ PokeAPIDatos de PokémonNingunoFlexible★★☆
⑩ Numbers APICuriosidades numéricasNingunoFlexible★☆☆

① Open-Meteo — API del Clima sin Clave

Open-Meteo es una API de datos meteorológicos completamente gratuita y sin clave API. Proporciona clima actual, temperatura, velocidad del viento, precipitación y pronósticos hasta 16 días. El uso comercial está permitido, lo que la convierte en la opción preferida para herramientas relacionadas con el clima.

open_meteo.py
import requests

url = "https://api.open-meteo.com/v1/forecast"
params = {
    "latitude": 35.6762,
    "longitude": 139.6503,
    "current_weather": True
}

response = requests.get(url, params=params, timeout=5)
data = response.json()

weather = data["current_weather"]
print(f"Temp: {weather['temperature']}°C")
print(f"Wind: {weather['windspeed']} km/h")

La mayor ventaja es acceso instantáneo a datos sin ninguna autenticación. No se necesita registro de clave API ni creación de cuenta. Cambia la latitud/longitud y obtendrás datos meteorológicos de cualquier parte del mundo.

💡 Tip

Open-Meteo es un proyecto de código abierto que usa datos de agencias meteorológicas europeas. La precisión es alta incluso para ubicaciones en Asia y América, lo que lo hace adecuado tanto para proyectos personales como para herramientas comerciales.

② ExchangeRate API — Tipos de Cambio

ExchangeRate API proporciona tipos de cambio de divisas gratuitos para las principales monedas. Útil para herramientas de conversión de divisas, sitios de comparación de precios y dashboards financieros. No requiere clave API, con 1.500 solicitudes por día.

exchange_rate.py
import requests

url = "https://open.er-api.com/v6/latest/USD"
response = requests.get(url, timeout=5)
data = response.json()

jpy_rate = data["rates"]["JPY"]
print(f"1 USD = {jpy_rate} JPY")

# Currency conversion example
usd_amount = 100
jpy_amount = usd_amount * jpy_rate
print(f"{usd_amount} USD = {jpy_amount:.0f} JPY")

Una consideración crítica con datos financieros es la frecuencia de actualización. Esta API se actualiza aproximadamente una vez al día, por lo que no es adecuada para trading en tiempo real. Proporciona suficiente precisión para conversión aproximada de divisas y referencias de precios diarios.

⚠️ Nota

Al mostrar tipos de cambio a los usuarios, siempre indica que «los tipos son aproximados». Pueden existir discrepancias con los tipos en tiempo real, y estos datos no deben usarse como base para transacciones financieras.

③ CoinGecko API — Precios de Criptomonedas

CoinGecko proporciona precios de criptomonedas, capitalización de mercado, volúmenes de trading y rankings. El plan gratuito es sorprendentemente potente y ampliamente usado para desarrollo de herramientas relacionadas con cripto.

coingecko.py
import requests

url = "https://api.coingecko.com/api/v3/simple/price"
params = {
    "ids": "bitcoin,ethereum",
    "vs_currencies": "usd,eur",
    "include_24hr_change": "true"
}

response = requests.get(url, params=params, timeout=5)
data = response.json()

btc = data["bitcoin"]
print(f"BTC: ${btc['usd']:,.0f} (24h: {btc['usd_24h_change']:.1f}%)")

El Rate Limit de CoinGecko en el plan gratuito es de aproximadamente 10–30 solicitudes por minuto. Dado que los precios de cripto son volátiles, el caché es esencial. Obtén datos cada minuto, almacena localmente y sirve desde caché.

💡 Tip

CoinGecko permite obtener múltiples monedas en una sola solicitud. Usa ids=bitcoin,ethereum,solana con separación por comas para reducir drásticamente el número de solicitudes.

④ JSONPlaceholder — El Estándar para Práctica de API

JSONPlaceholder es una API mock diseñada para aprendizaje y pruebas de APIs REST. Proporciona datos simulados para usuarios, posts, comentarios y álbumes, ampliamente usada para prototipado de desarrollo de APIs y pruebas de frontend.

jsonplaceholder.py
import requests

# Get posts
url = "https://jsonplaceholder.typicode.com/posts"
params = {"_limit": 3}
response = requests.get(url, params=params, timeout=5)
posts = response.json()

for post in posts:
    print(f"[{post['id']}] {post['title']}")

# Practice POST requests
new_post = {"title": "Test", "body": "Hello", "userId": 1}
res = requests.post(url, json=new_post, timeout=5)
print(f"Created: status={res.status_code}")

La mayor ventaja es soporte para todos los métodos HTTP: GET, POST, PUT, PATCH, DELETE. Las solicitudes POST y DELETE no modifican datos reales — las respuestas son simuladas, lo que permite experimentar con seguridad. Ideal para incorporar nuevos ingenieros y probar clientes API.

💡 Tip

Si necesitas una API mock para tu propio proyecto, usa el diseño de JSONPlaceholder como referencia y configura un servidor mock local con json-server (paquete npm).

⑤ REST Countries — Información de Países

REST Countries proporciona información básica sobre cada país del mundo — población, área, capital, bandera, moneda, idiomas y región — todo en formato JSON. Excelente para herramientas de educación geográfica, dashboards de estadísticas y aplicaciones internacionalizadas.

rest_countries.py
import requests

url = "https://restcountries.com/v3.1/name/japan"
response = requests.get(url, timeout=5)
data = response.json()[0]

print(f"Country: {data['name']['common']}")
print(f"Capital: {data['capital'][0]}")
print(f"Population: {data['population']:,}")
print(f"Region: {data['region']}")
print(f"Flag: {data['flag']}")

Esta API es ideal para caché ya que los datos de países rara vez cambian. Obtén todos los datos una vez y almacena localmente — no necesitas llamar a la API de nuevo. Cargar todos los datos en memoria al iniciar es el enfoque más eficiente.

💡 Tip

El endpoint /v3.1/all devuelve datos de los más de 250 países de una vez. Usa filtros de campos (?fields=name,population,capital) para reducir el tamaño de la respuesta y ahorrar ancho de banda.

⑥ The Cat API — Imágenes de Gatos Aleatorias

The Cat API devuelve imágenes aleatorias de gatos. Aunque parece lúdica, es genuinamente útil en producción para pruebas de visualización de imágenes en UI, generación de placeholders dinámicos y pruebas de clientes API.

cat_api.py
import requests

url = "https://api.thecatapi.com/v1/images/search"
params = {"limit": 3}
response = requests.get(url, params=params, timeout=5)
images = response.json()

for img in images:
    print(f"URL: {img['url']} (size: {img['width']}x{img['height']})")

Las funciones básicas funcionan sin clave API, pero registrarse para una clave gratuita aumenta los límites de tasa y desbloquea filtros por raza y favoritos.

💡 Tip

Al probar funciones de «visualización dinámica de imágenes» en desarrollo frontend, esta API proporciona un entorno de prueba más realista que imágenes dummy estáticas.

⑦ IP-API — Geolocalización por IP

IP-API devuelve datos de geolocalización a partir de direcciones IP — país, región, ciudad, ISP y zona horaria. Se usa para análisis de acceso, visualización de contenido por región y monitoreo de seguridad.

ip_api.py
import requests

url = "http://ip-api.com/json/"
response = requests.get(url, timeout=5)
data = response.json()

print(f"Country: {data['country']}")
print(f"Region: {data['regionName']}")
print(f"City: {data['city']}")
print(f"ISP: {data['isp']}")
print(f"Timezone: {data['timezone']}")
⚠️ Importante

El nivel gratuito es solo HTTP (HTTPS requiere plan de pago). Para entornos de producción que requieran HTTPS, considera actualizar o cambiar a alternativas como ipinfo.io. El uso comercial también requiere el plan de pago.

El límite de tasa es de 45 solicitudes por minuto. Para consultas masivas de IP, usa el endpoint http://ip-api.com/batch para mayor eficiencia.

⑧ Advice Slip API — Frases Aleatorias

Advice Slip API devuelve consejos y frases aleatorias en inglés. Útil para pantallas de prueba de UI, funciones de mensaje diario y embellecimiento de chatbots.

advice_slip.py
import requests

url = "https://api.adviceslip.com/advice"
response = requests.get(url, timeout=5)
data = response.json()

advice = data["slip"]["advice"]
print(f"Today's advice: {advice}")

Esta API presenta un diseño de endpoint minimalista — solo /advice (aleatorio) y /advice/{id} (por ID). Aplica un límite de intervalo de 2 segundos entre llamadas consecutivas.

💡 Tip

Las APIs con diseños «un endpoint, una respuesta» como esta sirven como referencias de libro de texto para diseño de APIs. Al construir tu propia API, empezar así de simple es una buena práctica de producción.

⑨ PokeAPI — Ideal para Aprender Datos Estructurados

PokeAPI proporciona nombres, tipos, estadísticas e imágenes de Pokémon. Más allá de los datos del juego, su estructura lo hace excelente para aprender procesamiento de JSON anidado, paginación y manejo de datos relacionales — patrones que encontrarás en toda API de producción.

pokeapi.py
import requests

url = "https://pokeapi.co/api/v2/pokemon/pikachu"
response = requests.get(url, timeout=5)
data = response.json()

print(f"Name: {data['name']}")
print(f"Type: {data['types'][0]['type']['name']}")
print(f"HP: {data['stats'][0]['base_stat']}")
print(f"Image: {data['sprites']['front_default']}")

Las respuestas de PokeAPI están profundamente anidadas, requiriendo patrones de acceso como data["types"][0]["type"]["name"]. Esto es común en APIs de producción (Stripe, Twilio, AWS SDK), así que practicar aquí facilita la integración real de APIs.

💡 Tip

PokeAPI tiene más de 1.000 entradas con soporte de paginación (?offset=20&limit=20). El patrón lista → detalle se aplica directamente al diseño de APIs de e-commerce y redes sociales.

⑩ Numbers API — Curiosidades Numéricas

Numbers API devuelve trivia y datos curiosos sobre cualquier número. Útil para sitios educativos, herramientas de quiz y embellecimiento de UI con contenido diario.

numbers_api.py
import requests

number = 42
url = f"http://numbersapi.com/{number}?json"
response = requests.get(url, timeout=5)
data = response.json()

print(f"{number}: {data['text']}")
# e.g.: 42: 42 is the answer to the Ultimate Question ...

Los tipos incluyen trivia (por defecto), math, date y year. Por ejemplo, http://numbersapi.com/3/14/date?json devuelve trivia sobre el 14 de marzo.

⚠️ Nota

Numbers API es solo HTTP — sin soporte HTTPS. Para uso en producción, evítala o retransmite solicitudes a través de tu servidor y devuelve respuestas HTTPS a los clientes.

Rate Limits y Estrategia de Caché

La trampa más peligrosa con APIs gratuitas es exceder los límites de tasa. Los servicios gratuitos tienen límites estrictos, y las violaciones resultan en bloqueos de IP que pueden durar horas o días.

Patrones típicos de límite de tasa:

PatrónEjemploCaso de Uso
Por segundo1/segDatos en tiempo real
Por minuto60/minAPIs estándar
Por día1.000/díaRecuperación de datos

La solución es el caché. Almacena las respuestas de la API localmente y sírvelas desde caché dentro de una ventana TTL.

cache_example.py
import requests
import time
import json
import os

CACHE_FILE = "cache.json"
CACHE_TTL = 300  # 5 minutos

def get_with_cache(url):
    if os.path.exists(CACHE_FILE):
        with open(CACHE_FILE) as f:
            cache = json.load(f)
        if url in cache and time.time() - cache[url]["time"] < CACHE_TTL:
            return cache[url]["data"]

    response = requests.get(url, timeout=5)
    data = response.json()

    cache = {}
    if os.path.exists(CACHE_FILE):
        with open(CACHE_FILE) as f:
            cache = json.load(f)
    cache[url] = {"data": data, "time": time.time()}
    with open(CACHE_FILE, "w") as f:
        json.dump(cache, f)

    return data
💡 Tip

En producción, usa Redis o memcached en lugar de caché en archivo. Django proporciona django.core.cache, y FastAPI tiene aiocache para soporte de caché integrado.

Patrones Esenciales de Diseño Seguro

El código de producción que usa APIs externas requiere estos cinco patrones de diseño:

PatrónPropósitoRiesgo si Falta
timeoutEvitar espera infinitaPrograma se congela
retryManejar fallos transitoriosProcesamiento se detiene
rate controlRespetar límites de APIBloqueo de IP
fallbackManejar caídas de APIServicio caído
cacheReducir solicitudesLímite excedido

Un patrón de producción combinado:

safe_api_call.py
import requests
import time

def safe_api_call(url, max_retries=3, delay=1):
    for attempt in range(max_retries):
        try:
            response = requests.get(url, timeout=5)
            if response.status_code == 429:  # Rate Limit
                wait = int(response.headers.get("Retry-After", delay * 2))
                time.sleep(wait)
                continue
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException:
            if attempt < max_retries - 1:
                time.sleep(delay * (attempt + 1))
                continue
            return None  # fallback
    return None

Recuerda este principio de producción: las APIs externas son poco fiables por defecto. Caídas, cambios de especificación, picos de latencia, cambios de límites — estos no son escenarios de «podría pasar», son «pasará». Los profesionales diseñan asumiendo que las APIs externas no pueden ser confiables.

Para más sobre diseño seguro, consulta «10 Patrones de Implementación de Seguridad en Python

Errores Comunes y Términos de Servicio

Conoce los patrones de fallo que los principiantes suelen encontrar:

ErrorResultadoSolución
Llamadas API en bucleBloqueo de IPsleep + caché
Sin cachéLímite excedidoCaché por archivo/Redis
Sin manejo de erroresCrash del programatry/except obligatorio
Sin timeoutPrograma se congelatimeout=5 como estándar
Ignorar ToSRiesgo legalSiempre leer Términos

Siempre verifica los Términos de Servicio. Incluso las APIs gratuitas pueden tener restricciones:

  • Sin uso comercial — solo uso personal
  • Atribución requerida — obligación de mostrar «Powered by ○○»
  • Sin redistribución — no se puede republicar datos crudos en otro servicio
  • Restricciones HTTPS — nivel gratuito solo HTTP (IP-API, Numbers API)
⚠️ Advertencia

«Gratuito» no significa «usar como quieras». Ignorar los Términos de Servicio es más peligroso que enviar código con errores — es un riesgo legal directo.

Diseño Profesional — Provider Abstraction

Los desarrolladores experimentados siempre piensan en las APIs externas de esta manera:

  • Las APIs gratuitas son para prototipado y validación
  • Planifica migración a plan de pago o reemplazo auto-hospedado en producción
  • Diseña para evitar dependencia excesiva de cualquier proveedor

Esto se logra mediante Provider Abstraction — encapsulando las llamadas API detrás de una interfaz para que los proveedores puedan intercambiarse sin cambiar el código de la aplicación.

provider_abstraction.py
class WeatherProvider:
    def get_temperature(self, lat, lon):
        raise NotImplementedError

class OpenMeteoProvider(WeatherProvider):
    def get_temperature(self, lat, lon):
        url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}&current_weather=true"
        data = requests.get(url, timeout=5).json()
        return data["current_weather"]["temperature"]

class PaidWeatherProvider(WeatherProvider):
    def get_temperature(self, lat, lon):
        # Swap to paid API by changing just this class
        pass

# Usage
weather = OpenMeteoProvider()
temp = weather.get_temperature(35.67, 139.65)
print(f"Temperature: {temp}°C")

Con este diseño, cambiar de proveedores de API requiere cambiar solo una clase. No necesitas reescribir toda tu aplicación. Durante las pruebas, también puedes intercambiar un proveedor mock.

💡 Tip

Esto también se conoce como «Strategy Pattern» y se aplica más allá de las APIs a bases de datos, servicios de email, almacenamiento de archivos — cualquier integración de servicio externo.

Preguntas Frecuentes

P: ¿Cuál es la diferencia entre APIs con y sin clave?

Las claves API identifican usuarios. Las APIs sin clave son convenientes pero tienden a tener límites de tasa más estrictos basados en IP. Las APIs con clave pueden gestionar límites por usuario y típicamente permiten más solicitudes.

P: ¿Puedo construir un servicio público usando APIs gratuitas?

Depende de los Términos de Servicio. Open-Meteo y REST Countries permiten uso comercial, pero el nivel gratuito de IP-API es solo no comercial. Siempre verifica los ToS de cada API antes de publicar.

P: ¿Qué pasa si una API se cae repentinamente?

Por eso es importante el diseño de fallback. Mantén datos recientes en caché para poder servirlos durante caídas. Para tiempos de inactividad prolongados, usa Provider Abstraction para cambiar a una API alternativa.

P: ¿Qué significa 429 Too Many Requests?

Has excedido el límite de tasa. Verifica el encabezado de respuesta Retry-After y espera los segundos especificados antes de reintentar. Si consistentemente recibes 429, implementa caché o aumenta los intervalos entre solicitudes.

Conclusión

Las APIs gratuitas permiten a los desarrolladores Python implementar clima, divisas, cripto, imágenes y muchas otras funciones en tiempo récord. Pero lo que realmente importa no es qué APIs eliges — es cómo las usas.

  1. Siempre implementa timeout y manejo de errores
  2. Verifica los Rate Limits y mantente dentro de ellos usando caché
  3. Lee los Términos de Servicio antes de usar cualquier API
  4. Gestiona dependencias con Provider Abstraction
  5. Diseña asumiendo que las APIs externas son poco fiables

Las APIs son potentes, pero la dependencia excesiva rompe las cosas. Usadas sabiamente, pueden acelerar drásticamente tu velocidad de desarrollo. Esa es la esencia de la integración de APIs externas.

Comments

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *