API de Consulta da operadora original em Python: solicitações únicas e múltiplas com requests
Chame uma API de consulta de operadora em Python com a biblioteca requests: solicitações únicas e múltiplas, resultados ordenados e verificação de saldo.

Um guia prático em Python para consultas de operadora únicas e múltiplas com a biblioteca requests, incluindo tratamento de erros e mapeamento de resultados ordenados de volta para as linhas de dados.
Para chamar uma API de consulta de operadora em Python, use a biblioteca requests para enviar um POST com um número no formato E.164 para /api/v1/check para obter um resultado, ou uma lista de até 100 números para /api/v1/batch-check para um conjunto ordenado de resultados. Envie a chave da API no cabeçalho X-API-Key a partir de um servidor confiável, defina um tempo limite (timeout), verifique o código de resposta antes de ler os dados e mapeie os resultados múltiplos de volta para suas linhas por posição e identificador. A operadora retornada é a da alocação original, não a rede atual.
Configure uma sessão de requests para consultas de operadora
A biblioteca requests mantém as chamadas HTTP concisas, e um objeto de sessão permite que cada chamada compartilhe cabeçalhos e uma conexão. Instale-a com pip install requests e mantenha a chave fora do código-fonte lendo-a de uma variável de ambiente.
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",
})
Três hábitos valem a pena ser adotados desde o início:
- Execute este código apenas em um servidor confiável, um worker ou um notebook que você controle. Nunca envie a chave em um navegador ou aplicativo móvel.
- Sempre passe um
timeoutpara cada chamada. Sem ele, o requests pode aguardar indefinidamente. - Normalize os números para o formato E.164 antes de enviar qualquer coisa: um sinal de mais inicial, o código do país e o número do assinante, sem espaços ou separadores.
Um pequeno auxiliar que remove separadores e adiciona o sinal de mais economiza muita limpeza repetida e mantém problemas de formatação fora dos seus resultados. Um formato rejeitado é um problema de formatação, não uma resposta da operadora, portanto, trate-o antes da solicitação.
Envie uma consulta única para /api/v1/check
A consulta única em tempo real é POST /api/v1/check. Ela aceita um número E.164 e responde na mesma solicitação. Envie o número no corpo JSON conforme descrito na documentação da API.
def check_one(number: str) -> dict | None:
resp = session.post(
f"{BASE_URL}/api/v1/check",
json=build_single_payload(number), # formato do corpo: veja a documentação da API
timeout=65,
)
resp.raise_for_status()
body = resp.json()
if body.get("code") != 0:
print("não concluído:", body.get("msg"))
return None
return body["data"]
O corpo possui um code, uma msg e um objeto data simples. Um code zero significa que a consulta foi concluída. Os dados contêm a operadora original, a operadora subjacente, o tipo de número, o código do país, a região e a cidade. Qualquer um dos valores opcionais pode estar vazio, e um resultado concluído com todos os valores de operadora vazios ainda é um resultado normal. Armazene valores vazios como indisponíveis, não como prova de que um número não possui operadora.
Um code diferente de zero significa que a consulta não foi concluída, por exemplo, quando uma resposta não pôde ser determinada. Não transforme esse caso em um sucesso vazio. Consultas falhas ou Indeterminado não geram cobrança, portanto, uma nova tentativa com um pequeno atraso é razoável. A documentação pública lista os limites de tempo limite para chamadas em tempo real, portanto, mantenha o tempo limite do seu cliente igual ou superior ao limite documentado para solicitações únicas.
Envie uma solicitação múltipla e mapeie os resultados para as linhas
Quando você tem um pequeno lote, o POST /api/v1/batch-check aceita entre 1 e 100 números E.164 e retorna um resultado síncrono ordenado. Os números podem vir de diferentes países. A resposta resume quantos itens havia, quantos tiveram sucesso e quantos falharam, e então lista um resultado por entrada em ordem.
def check_many(numbers: list[str]) -> list[dict]:
resp = session.post(
f"{BASE_URL}/api/v1/batch-check",
json=build_multi_payload(numbers), # formato do corpo: veja a documentação da 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 anexar resultados às suas linhas, combine a lista de entrada com a lista de resultados e verifique se o identificador de cada item corresponde ao número que você enviou. Essa segunda verificação protege você contra desalinhamentos silenciosos caso uma lista tenha sido alterada entre a criação e o envio da solicitação.
Cada item também carrega um sinalizador exists. Quando ele é falso, o item não possui um resultado normal. Isso não é o mesmo que um número inválido ou desconectado, portanto, armazene-o como sem resultado e decida mais tarde se deve tentar novamente ou deixá-lo de lado. Uma solicitação múltipla que atinge o tempo limite falha como um todo, sem resultados parciais, e o valor total é retornado, portanto, a resposta segura é tentar novamente o mesmo bloco.
Apenas uma solicitação múltipla por conta é executada por vez, portanto, um loop que processa blocos deve aguardar a conclusão de cada chamada antes de enviar a próxima.
Divida em blocos, tente novamente e verifique o saldo
Listas reais são maiores que 100 números, portanto, divida-as em blocos e processe cada um por 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))
Várias regras práticas mantêm este loop confiável:
- Remova duplicatas da lista limpa primeiro, para que cada número seja consultado apenas uma vez.
- Capture
requests.exceptions.TimeouteConnectionErrorseparadamente dos erros da API e tente novamente um número limitado de vezes com uma pausa. - Mantenha a concorrência baixa. A documentação pública descreve um pequeno número de slots de tempo real compartilhados em uso e não publica um limite fixo por minuto, portanto, evite disparar muitas threads paralelas.
- Grave cada bloco concluído em disco ou em um banco de dados assim que ele retornar, para que uma falha não perca o trabalho finalizado.
Antes de uma execução grande, chame GET /api/v1/balance. Isso lê o saldo da conta sem cobrar nada e permite que o script pare mais cedo com uma mensagem clara em vez de falhar no meio do caminho. Tanto os serviços de tempo real quanto os de arquivo compartilham um saldo e cobram por número concluído.
Para listas muito maiores do que alguns blocos, uma tarefa de arquivo assíncrona é mais adequada do que um longo loop de chamadas síncronas. Uma tarefa de arquivo é um fluxo de trabalho separado com seu próprio endpoint, não uma versão maior de uma solicitação múltipla.
Interprete os resultados de forma responsável
Uma vez que os dados estejam em um dataframe pandas ou em um banco de dados, o principal risco é a interpretação excessiva. A operadora é aquela à qual a faixa numérica foi originalmente alocada. Após a portabilidade, a pessoa pode usar outra operadora. Região e cidade descrevem a geografia da alocação, não onde uma pessoa ou telefone está agora. O tipo de número informa o tipo de faixa, não se a linha está ativa.
Bons usos incluem agrupar registros para testes de roteamento de provedores, sinalizar tipos de números incomuns para revisão e adicionar colunas de contexto a um CRM. Usos ruins incluem decidir se um número pode ou não ser alcançado, presumir quem o possui ou inferir consentimento.
Um esquema simples mantém o significado claro: operadora original, operadora subjacente, tipo de número, código do país, região, cidade, status da consulta e hora da consulta. A coluna de status separa resultados concluídos, vazios e falhos, para que relatórios posteriores não os misturem.
FAQ
Qual biblioteca Python funciona melhor para chamadas da API de consulta de operadora?
A biblioteca requests é suficiente tanto para o endpoint único quanto para o múltiplo. Use uma sessão para compartilhar o cabeçalho da chave da API, sempre defina um tempo limite e chame raise_for_status além de uma verificação no código de resposta. Para muitos trabalhos simultâneos, mantenha o pool pequeno, pois os slots de tempo real são compartilhados em toda a conta.
Como as equipes podem mapear resultados múltiplos de volta para as linhas de entrada?
Os resultados retornam na ordem de entrada, e cada item repete o identificador que foi enviado. Combine a lista de entrada com os resultados e verifique se cada identificador corresponde à sua linha antes de gravar os dados. Itens onde o sinalizador exists é falso devem ser armazenados como sem resultado normal, não como números inválidos.
Onde a chave da API deve ficar em um projeto Python?
Mantenha-a em uma variável de ambiente ou em um gerenciador de segredos em um servidor confiável e leia-a na inicialização. Não a envie para o controle de versão nem a envie a partir de código de navegador ou móvel. Se ela vazar em um log ou repositório, altere-a e revise o uso recente.
Saiba mais
Escolha as informações do produto que se encaixam no próximo passo do seu fluxo de trabalho.