API de Voos com Milhas: Guia Completo para Desenvolvedores
Buscar passagens com milhas sempre foi complexo e fragmentado. Cada programa tem sua própria plataforma, regras diferentes, e integrar tudo isso tecnicamente é um pesadelo.
Neste guia, vou mostrar como você pode oferecer busca de voos com milhas no seu app ou site de forma simples e unificada.
O Desafio da Busca de Milhas
Cenário Tradicional (Sem API)
Para oferecer busca de milhas, você precisaria:
1. Integrar com Smiles (API proprietária)
2. Integrar com LATAM Pass (sistema diferente)
3. Integrar com Tudo Azul (outro protocolo)
4. Integrar com Livelo, Esfera, etc.
5. Normalizar dados de cada fonte
6. Manter tudo atualizado
Resultado:
- 💰 Custo: R$ 100.000+ em desenvolvimento
- ⏰ Tempo: 6-12 meses de trabalho
- 🔧 Manutenção: Time dedicado permanente
- 😰 Complexidade: Altíssima
Com API de Voos
// Uma única chamada para buscar em TODOS os programas
const flights = await api.search({
origin: 'GRU',
destination: 'MIA',
departure: '2026-04-20',
include_miles: true // 👈 É só isso!
});
Resultado:
- ✅ 5 minutos para integrar
- ✅ R$ 0,25 por requisição
- ✅ Todos os programas em uma resposta
- ✅ Zero manutenção
Como Funciona
Arquitetura da API
Seu App/Site
↓
API de Voos (camada de agregação)
↓
┌─────────┬──────────┬──────────┬─────────┐
│ Smiles │ LATAM │ Tudo Azul│ Outros │
│ (Gol) │ Pass │ (Azul) │ │
└─────────┴──────────┴──────────┴─────────┘
A API faz o trabalho pesado:
- 🔄 Consulta todos os programas simultaneamente
- 📊 Normaliza os dados
- ⚡ Cacheia resultados inteligentemente
- 🎯 Retorna tudo em um formato único
Tutorial Prático
Passo 1: Busca Básica com Milhas
Se você ainda não está familiarizado com a estrutura básica da API, recomendo começar pelo nosso tutorial de como integrar uma API de voos em 5 minutos.
const axios = require('axios');
async function searchWithMiles() {
const response = await axios.post(
'https://api.api-de-voos.com/v1/search',
{
origin: 'GRU',
destination: 'JFK',
departure: '2026-05-15',
adults: 1,
include_miles: true // Incluir opções com milhas
},
{
headers: {
'Authorization': 'Bearer voos_test_abc123',
'Content-Type': 'application/json'
}
}
);
return response.data;
}
Resposta da API
{
"success": true,
"flights": [
{
"id": "flight_001",
"type": "conventional",
"airline": "LATAM",
"price": {
"amount": 3450.00,
"currency": "BRL"
},
"departure": { "airport": "GRU", "time": "2026-05-15T22:30:00Z" },
"arrival": { "airport": "JFK", "time": "2026-05-16T06:15:00Z" }
},
{
"id": "flight_002",
"type": "miles",
"airline": "LATAM",
"miles_required": 35000,
"program": "latam_pass",
"program_name": "LATAM Pass",
"taxes": {
"amount": 280.50,
"currency": "BRL",
"description": "Taxas aeroportuárias + impostos"
},
"departure": { "airport": "GRU", "time": "2026-05-15T22:30:00Z" },
"arrival": { "airport": "JFK", "time": "2026-05-16T06:15:00Z" },
"cabin_class": "economy",
"availability": "good"
},
{
"id": "flight_003",
"type": "miles",
"airline": "Gol",
"miles_required": 30000,
"program": "smiles",
"program_name": "Smiles",
"taxes": {
"amount": 195.80,
"currency": "BRL"
},
"departure": { "airport": "GRU", "time": "2026-05-15T18:45:00Z" },
"arrival": { "airport": "JFK", "time": "2026-05-16T02:30:00Z" },
"cabin_class": "economy",
"availability": "limited"
}
]
}
Passo 2: Filtrar Apenas Milhas
async function searchOnlyMiles() {
const response = await axios.post(
'https://api.api-de-voos.com/v1/search',
{
origin: 'GRU',
destination: 'JFK',
departure: '2026-05-15',
adults: 1,
only_miles: true // Apenas opções com milhas
},
{ headers }
);
return response.data;
}
Passo 3: Filtrar por Programa Específico
async function searchSpecificProgram() {
const response = await axios.post(
'https://api.api-de-voos.com/v1/search',
{
origin: 'GRU',
destination: 'JFK',
departure: '2026-05-15',
adults: 1,
only_miles: true,
miles_programs: ['smiles', 'latam_pass'] // Apenas Smiles e LATAM Pass
},
{ headers }
);
return response.data;
}
Programas Suportados
A API suporta os principais programas de milhas do Brasil e do mundo:
Programas Brasileiros
| Programa | Código | Companhia(s) Principal |
|---|---|---|
| Smiles | smiles | Gol |
| LATAM Pass | latam_pass | LATAM |
| Tudo Azul | tudo_azul | Azul |
| Esfera (Bradesco) | esfera | Múltiplas |
| Livelo | livelo | Múltiplas |
Programas Internacionais
| Programa | Código | Companhia(s) |
|---|---|---|
| AAdvantage | aadvantage | American Airlines |
| Flying Blue | flying_blue | Air France / KLM |
| Miles & More | miles_and_more | Lufthansa Group |
| SkyMiles | skymiles | Delta |
| Executive Club | executive_club | British Airways |
Entendendo os Dados de Milhas
Campo miles_required
Quantidade de milhas necessária para emitir a passagem:
{
"miles_required": 35000, // 35.000 milhas
"program": "latam_pass"
}
Campo taxes
Mesmo passagens com milhas têm custos (taxas aeroportuárias, combustível, impostos):
{
"taxes": {
"amount": 280.50, // R$ 280,50 a pagar
"currency": "BRL",
"breakdown": {
"airport_fees": 120.00,
"fuel_surcharge": 100.50,
"government_taxes": 60.00
}
}
}
Campo availability
Indica a disponibilidade de assentos para milhas:
{
"availability": "excellent", // Valores: excellent, good, limited, last_seats
"seats_available": 9
}
Comparando Preço vs Milhas
Calculadora de Valor
Ajude seu usuário a decidir se vale a pena usar milhas:
function calculateMilesValue(flight) {
// Valor médio da milha no mercado
const MILE_MARKET_VALUE = 0.015; // R$ 0,015 por milha
const milesValueInBRL = flight.miles_required * MILE_MARKET_VALUE;
const totalMilesCost = milesValueInBRL + flight.taxes.amount;
return {
miles_value: milesValueInBRL,
total_cost: totalMilesCost,
cash_price: flight.cash_alternative?.price.amount,
savings: flight.cash_alternative?.price.amount - totalMilesCost,
is_worth_it: totalMilesCost < flight.cash_alternative?.price.amount
};
}
// Uso
const flight = {
miles_required: 30000,
taxes: { amount: 200 },
cash_alternative: { price: { amount: 2500 } }
};
const analysis = calculateMilesValue(flight);
console.log(`Vale a pena? ${analysis.is_worth_it ? 'Sim' : 'Não'}`);
console.log(`Economia: R$ ${analysis.savings}`);
Exibindo no Frontend
function FlightCard({ flight }) {
if (flight.type === 'miles') {
return (
<div className="flight-card miles">
<div className="airline">{flight.airline}</div>
<div className="miles-info">
<span className="miles-amount">
{flight.miles_required.toLocaleString()} milhas
</span>
<span className="program">{flight.program_name}</span>
</div>
<div className="taxes">
+ R$ {flight.taxes.amount} em taxas
</div>
{flight.availability === 'limited' && (
<div className="warning">⚠️ Últimos assentos disponíveis</div>
)}
<button>Emitir com {flight.program_name}</button>
</div>
);
}
// Voo convencional
return (
<div className="flight-card cash">
<div className="airline">{flight.airline}</div>
<div className="price">R$ {flight.price.amount}</div>
<button>Comprar</button>
</div>
);
}
Casos de Uso Avançados
1. Busca Multi-Programas com Prioridade
Esse tipo de personalização é perfeito para produtos de nicho focados em milhas, como apps de cashback ou comparadores especializados.
async function searchWithPriority(userPrograms) {
const response = await axios.post(
'https://api.api-de-voos.com/v1/search',
{
origin: 'GRU',
destination: 'EZE',
departure: '2026-06-10',
adults: 2,
only_miles: true,
miles_programs: userPrograms // ['smiles', 'tudo_azul', 'latam_pass']
},
{ headers }
);
// Ordenar pelos programas do usuário
const flights = response.data.flights.sort((a, b) => {
const aPriority = userPrograms.indexOf(a.program);
const bPriority = userPrograms.indexOf(b.program);
return aPriority - bPriority;
});
return flights;
}
2. Alertas de Disponibilidade de Milhas
async function createMilesAlert() {
const response = await axios.post(
'https://api.api-de-voos.com/v1/alerts',
{
route: {
origin: 'GRU',
destination: 'LIS'
},
travel_window: {
start: '2026-07-01',
end: '2026-07-31'
},
alert_type: 'miles_availability',
programs: ['smiles', 'latam_pass'],
max_miles: 40000, // Alerta se encontrar por até 40k milhas
webhook_url: 'https://seu-app.com/webhook/miles-alert'
},
{ headers }
);
console.log('Alerta criado:', response.data.alert_id);
}
3. Calendário de Disponibilidade
async function getMilesCalendar() {
const response = await axios.post(
'https://api.api-de-voos.com/v1/miles/calendar',
{
origin: 'GRU',
destination: 'MIA',
month: '2026-08',
program: 'smiles'
},
{ headers }
);
// Retorna disponibilidade dia a dia
return response.data.calendar;
/* Exemplo de resposta:
{
"2026-08-01": { "available": true, "miles": 25000 },
"2026-08-02": { "available": false },
"2026-08-03": { "available": true, "miles": 25000, "availability": "limited" }
}
*/
}
Melhores Práticas
1. Cache Inteligente
Resultados de busca de milhas podem ser cacheados por mais tempo:
const CACHE_TTL = {
conventional: 5 * 60 * 1000, // 5 minutos
miles: 15 * 60 * 1000 // 15 minutos (milhas mudam menos)
};
async function searchWithCache(params) {
const cacheKey = `search:${JSON.stringify(params)}`;
const ttl = params.include_miles ? CACHE_TTL.miles : CACHE_TTL.conventional;
// Buscar do cache
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < ttl) {
return cached.data;
}
// Buscar da API
const data = await searchFlights(params);
cache.set(cacheKey, { data, timestamp: Date.now() });
return data;
}
2. Pré-filtro no Frontend
Evite requisições desnecessárias:
function canSearchMiles(userProfile) {
// Só habilitar busca de milhas se usuário tem programa
return userProfile.loyalty_programs?.length > 0;
}
// No componente
<Checkbox
label="Incluir busca com milhas"
disabled={!canSearchMiles(user)}
onChange={(checked) => setIncludeMiles(checked)}
/>
3. Educação do Usuário
Explique os conceitos:
function MilesExplainer() {
return (
<Tooltip content="O que são taxas em passagens de milhas?">
<InfoIcon />
<div className="tooltip-content">
<p>Mesmo usando milhas, você precisa pagar:</p>
<ul>
<li>Taxas aeroportuárias</li>
<li>Taxa de combustível</li>
<li>Impostos governamentais</li>
</ul>
<p>Essas taxas variam de R$ 150 a R$ 800 dependendo do destino.</p>
</div>
</Tooltip>
);
}
Integração com Carteiras de Milhas
Conectar Saldo do Usuário
async function searchWithUserBalance(user) {
const response = await axios.post(
'https://api.api-de-voos.com/v1/search',
{
origin: 'GRU',
destination: 'JFK',
departure: '2026-05-15',
adults: 1,
only_miles: true,
user_balances: [
{ program: 'smiles', balance: 50000 },
{ program: 'latam_pass', balance: 35000 },
{ program: 'tudo_azul', balance: 20000 }
]
},
{ headers }
);
// API retorna apenas voos que o usuário pode emitir
return response.data.flights;
}
Sugestão de Programas
function suggestBestProgram(flights, userBalances) {
return flights.map(flight => {
const userBalance = userBalances.find(b => b.program === flight.program);
return {
...flight,
can_afford: userBalance?.balance >= flight.miles_required,
missing_miles: Math.max(0, flight.miles_required - (userBalance?.balance || 0)),
best_option: calculateIfBestOption(flight, flights)
};
});
}
Tratamento de Erros Específicos
Erros Comuns em Busca de Milhas
async function searchMilesWithErrorHandling() {
try {
const response = await axios.post(url, params, { headers });
return response.data;
} catch (error) {
const errorCode = error.response?.data?.error?.code;
switch (errorCode) {
case 'NO_MILES_AVAILABILITY':
return {
message: 'Não há assentos disponíveis para milhas nesta data',
suggestion: 'Tente datas flexíveis ou outro programa'
};
case 'PROGRAM_UNAVAILABLE':
return {
message: 'Programa de milhas temporariamente indisponível',
suggestion: 'Tente novamente em alguns minutos'
};
case 'INVALID_PROGRAM':
return {
message: 'Programa de milhas não encontrado',
suggestion: 'Verifique os programas suportados'
};
default:
return {
message: 'Erro ao buscar voos com milhas',
suggestion: 'Entre em contato com o suporte'
};
}
}
}
Performance e Otimização
Busca Paralela
async function compareAllOptions() {
// Buscar dinheiro e milhas em paralelo
const [cashFlights, milesFlights] = await Promise.all([
searchFlights({ ...params, only_miles: false }),
searchFlights({ ...params, only_miles: true })
]);
return {
cash: cashFlights,
miles: milesFlights,
best_deal: findBestDeal(cashFlights, milesFlights)
};
}
Paginação de Resultados
async function searchMilesPaginated(page = 1) {
const response = await axios.post(
'https://api.api-de-voos.com/v1/search',
{
origin: 'GRU',
destination: 'JFK',
departure: '2026-05-15',
only_miles: true,
page: page,
per_page: 20
},
{ headers }
);
return {
flights: response.data.flights,
pagination: {
current_page: response.data.page,
total_pages: response.data.total_pages,
total_results: response.data.total_results
}
};
}
Próximos Passos
Funcionalidades Avançadas
-
Emissão com Milhas
- Endpoint
POST /v1/miles/bookings - Integração direta com programas
- Confirmação automática
- Endpoint
-
Transferência de Milhas
- Calcular se vale a pena transferir entre programas
- Taxas de transferência
- Tempo de processamento
-
Histórico de Preços em Milhas
- Ver variação de milhas necessárias
- Melhor época para emitir
- Previsão de tendências
Recursos Úteis
- 📚 Documentação de Milhas
- 🎮 Playground de Milhas
- 📊 Comparador de Programas
- 💬 Comunidade
- 📹 Tutorial em Vídeo
Conclusão
Integrar busca de passagens com milhas era complexo e caro. Agora você pode:
✅ Buscar em múltiplos programas com uma chamada ✅ Comparar preço em dinheiro vs milhas ✅ Oferecer alertas de disponibilidade ✅ Personalizar por saldo do usuário
Tudo isso por R$ 0,25 por requisição, com os mesmos 50 buscas grátis mensais. Entenda todos os custos no nosso guia completo de preços.
Se você está construindo uma startup, veja nosso guia para MVPs de travel tech para acelerar seu desenvolvimento.
Comece hoje: app.apidevoos.dev/login
Perguntas Frequentes
A busca de milhas custa o mesmo que a busca normal? Sim. R$ 0,25 por requisição, independente de incluir milhas ou não.
Todos os programas são consultados em cada busca?
Sim, a menos que você especifique programas específicos com miles_programs.
A API emite passagens com milhas diretamente?
Sim, através do endpoint /v1/miles/bookings (requer aprovação).
Como a API obtém dados de disponibilidade de milhas? Integrações diretas com cada programa de fidelidade.
Posso buscar apenas milhas de um programa específico?
Sim, use o parâmetro miles_programs: ['smiles'].
Gostou do tutorial? Compartilhe com a comunidade dev!
🐦 Twitter · 💼 LinkedIn · 📧 [Email](mailto:?subject=API de Voos com Milhas)