API de Consulta del operador original en Python: solicitudes individuales y múltiples con requests
Llame a una API de consulta del operador desde Python con la biblioteca requests: solicitudes individuales y múltiples, resultados ordenados y saldo.

Una guía de Python para realizar consultas del operador individuales y múltiples con requests, incluyendo el manejo de errores y la asignación de resultados ordenados a sus filas correspondientes.
Para llamar a una API de consulta del operador en Python, utilice la biblioteca requests para realizar un POST de un número en formato E.164 a /api/v1/check para obtener un resultado, o una lista de hasta 100 números a /api/v1/batch-check para obtener un conjunto ordenado de resultados. Envíe la clave de API en el encabezado X-API-Key desde un servidor seguro, establezca un tiempo de espera (timeout), verifique el código de respuesta antes de leer los datos y asigne los resultados múltiples a sus filas por posición e identificador. El operador devuelto es el de la asignación original, no la red actual.
Configure una sesión de requests para consultas del operador
La biblioteca requests permite realizar llamadas HTTP de forma concisa, y un objeto de sesión permite que cada llamada comparta encabezados y una conexión. Instálela con pip install requests y mantenga la clave fuera del código fuente leyéndola desde una variable de entorno.
import os
import requests
BASE_URL = "https://carrierlookup.online"
session = requests.Session()
session.headers.update({
"X-API-Key": os.environ["CARRIERLOOKUP_API_KEY"],
"Accept": "application/json",
})
Vale la pena adoptar tres hábitos desde el principio:
- Ejecute este código únicamente en un servidor seguro, un trabajador o un entorno de desarrollo que usted controle. Nunca incluya la clave en una aplicación de navegador o móvil.
- Pase siempre un
timeouta cada llamada. Sin él, requests puede esperar indefinidamente. - Normalice los números a E.164 antes de enviar cualquier dato: un signo más inicial, el código de país y el número de suscriptor, sin espacios ni separadores.
Un pequeño asistente que elimine los separadores y añada el signo más ahorra muchas limpiezas repetitivas y evita problemas de formato en los resultados. Un formato rechazado es un problema de formato, no una respuesta del operador, así que manéjelo antes de realizar la solicitud.
Envíe una consulta individual a /api/v1/check
La consulta individual en tiempo real es POST /api/v1/check. Acepta un número E.164 y responde en la misma solicitud. Envíe el número en el cuerpo JSON como se describe en la documentación de la API.
def check_one(number: str) -> dict | None:
resp = session.post(
f"{BASE_URL}/api/v1/check",
json=build_single_payload(number), # estructura del cuerpo: consulte la documentación de la API
timeout=65,
)
resp.raise_for_status()
body = resp.json()
if body.get("code") != 0:
print("no completado:", body.get("msg"))
return None
return body["data"]
El cuerpo contiene un code, un msg y un objeto data plano. Un code de cero significa que la consulta se completó. Los datos contienen el operador original, el operador subyacente, el tipo de número, el código de país, la región y la ciudad. Cualquiera de los valores opcionales puede estar vacío, y un resultado completado con todos los valores del operador vacíos sigue siendo un resultado normal. Almacene los valores vacíos como no disponibles, no como prueba de que un número no tiene operador.
Un code distinto de cero significa que la consulta no se completó, por ejemplo, cuando no se pudo determinar una respuesta. No convierta ese caso en un éxito vacío. Las consultas fallidas o indeterminadas no generan cargos, por lo que es razonable realizar un reintento con una breve pausa. La documentación pública enumera los límites de tiempo de espera para las llamadas en tiempo real, así que mantenga el tiempo de espera de su cliente igual o superior al límite documentado para las solicitudes individuales.
Envíe una solicitud múltiple y asigne los resultados a las filas
Cuando tenga un lote pequeño, POST /api/v1/batch-check acepta entre 1 y 100 números E.164 y devuelve un resultado síncrono ordenado. Los números pueden provenir de diferentes países. La respuesta resume cuántos elementos había, cuántos tuvieron éxito y cuántos fallaron, y luego enumera un resultado por entrada en orden.
def check_many(numbers: list[str]) -> list[dict]:
resp = session.post(
f"{BASE_URL}/api/v1/batch-check",
json=build_multi_payload(numbers), # estructura del cuerpo: consulte la documentación de la API
timeout=310,
)
resp.raise_for_status()
body = resp.json()
if body.get("code") != 0:
raise RuntimeError(body.get("msg"))
return body["data"]["results"]
Para adjuntar los resultados a sus filas, combine la lista de entrada con la lista de resultados y verifique que el identificador de cada elemento coincida con el número que envió. Esa segunda verificación le protege de una desalineación silenciosa si una lista se modificó entre la creación y el envío de la solicitud.
Cada elemento también incluye un indicador exists. Cuando es falso, el elemento no tiene un resultado normal. Esto no es lo mismo que un número no válido o desconectado, así que almacénelo como sin resultado y decida más tarde si desea volver a intentarlo o dejarlo así. Una solicitud múltiple que agota el tiempo de espera falla por completo sin resultados parciales, y se devuelve el importe total, por lo que la respuesta segura es volver a intentar el mismo bloque.
Solo se ejecuta una solicitud múltiple por cuenta a la vez, por lo que un bucle que procesa bloques debe esperar a que cada llamada finalice antes de enviar la siguiente.
Divida en bloques, reintente y verifique el saldo
Las listas reales son más largas que 100 números, así que divídalas en bloques y maneje cada uno a su vez.
def chunks(items, size=100):
for i in range(0, len(items), size):
yield items[i:i + size]
rows = []
for part in chunks(clean_numbers):
rows.extend(check_many(part))
Varias reglas prácticas mantienen este bucle fiable:
- Elimine primero los duplicados de la lista limpia, para que cada número se consulte una sola vez.
- Capture
requests.exceptions.TimeoutyConnectionErrorpor separado de los errores de la API, y vuelva a intentarlo un número limitado de veces con una pausa. - Mantenga la concurrencia baja. La documentación pública describe un número pequeño de espacios en tiempo real compartidos y no publica un límite fijo por minuto, así que evite lanzar muchos hilos en paralelo.
- Escriba cada bloque completado en el disco o en una base de datos tan pronto como regrese, para que un fallo no pierda el trabajo terminado.
Antes de una ejecución grande, llame a GET /api/v1/balance. Lee el saldo de la cuenta sin realizar cargos y permite que el script se detenga antes con un mensaje claro en lugar de fallar a mitad del proceso. Tanto los servicios en tiempo real como los de archivo comparten un mismo saldo y facturan por número completado.
Para listas mucho más grandes que unos pocos bloques, una tarea de archivo asíncrona es más adecuada que un bucle largo de llamadas síncronas. Una tarea de archivo es un flujo de trabajo independiente con su propio endpoint, no una versión más grande de una solicitud múltiple.
Interprete los resultados de forma responsable
Una vez que los datos están en un marco de pandas o en una base de datos, el riesgo principal es una interpretación excesiva. El operador es aquel al que se asignó originalmente el rango de números. Después de la portabilidad, la persona puede utilizar otro operador. La región y la ciudad describen la geografía de asignación, no dónde se encuentra una persona o un teléfono ahora. El tipo de número le indica el tipo de rango, no si la línea está activa.
Los usos adecuados incluyen agrupar registros para pruebas de enrutamiento de proveedores, marcar tipos de números inusuales para su revisión y añadir columnas de contexto a un CRM. Los usos inadecuados incluyen decidir si se puede contactar con un número, asumir quién es el propietario o inferir consentimiento.
Un esquema simple mantiene el significado claro: operador original, operador subyacente, tipo de número, código de país, región, ciudad, estado de la consulta y hora de la consulta. La columna de estado separa los resultados completados, vacíos y fallidos, para que los informes posteriores no los mezclen.
Preguntas frecuentes
¿Qué biblioteca de Python funciona mejor para las llamadas a la API de consulta del operador?
La biblioteca requests es suficiente tanto para el endpoint individual como para el múltiple. Utilice una sesión para compartir el encabezado de la clave de API, establezca siempre un tiempo de espera y llame a raise_for_status además de verificar el código de respuesta. Para muchos trabajos simultáneos, mantenga el grupo pequeño porque los espacios en tiempo real se comparten en toda la cuenta.
¿Cómo pueden los equipos asignar resultados múltiples a las filas de entrada?
Los resultados regresan en el orden de entrada, y cada elemento repite el identificador que se envió. Combine la lista de entrada con los resultados y, a continuación, verifique que cada identificador coincida con su fila antes de escribir los datos. Los elementos donde el indicador exists es falso deben almacenarse como si no tuvieran un resultado normal, no como números no válidos.
¿Dónde debe residir la clave de API en un proyecto de Python?
Manténgala en una variable de entorno o en un gestor de secretos en un servidor seguro y léala al inicio. No la confirme en el control de código fuente ni la envíe desde el código del navegador o móvil. Si se filtra en un registro o repositorio, rótela y revise el uso reciente.
Más información
Elija la información del producto que se ajuste al siguiente paso de su flujo de trabajo.