passagens.dev

API e servidor MCP

Preços de passagens para agentes de IA, com foco no Brasil. Gratuita, sem chave, CORS aberto, BRL por padrão, nomes em português. Versão do serviço 0.2.0; contrato de resposta schema_version 1.

Duas fontes, duas famílias de pergunta. Busca ao vivo nos preços em cache da Aviasales/Travelpayouts responde "quanto custa". Histórico próprio, coletado várias vezes ao dia desde agosto de 2026 em todas as rotas com preço saindo do Brasil, responde "quando é mais barato", "esse preço está bom" e "tem promoção agora". Quase nenhuma outra API aberta responde a segunda família para rotas brasileiras.

Comece aqui

Como conector MCP

https://passagens.dev/mcp

Ou a API direto

curl "https://passagens.dev/v1/search?origin=Floripa&destination=Lisboa&depart_date=2026-11"

Para um Custom GPT com Actions, importe https://passagens.dev/openapi.json. Para dar contexto a um modelo, aponte para https://passagens.dev/llms.txt.

Endpoints

RotaRespondeFonte e cache
GET /v1/searchTarifas mais baratas conhecidas entre dois pontos. origin e destination aceitam IATA ou nome em português ("Sampa", "Floripa"). depart_date e return_date em AAAA-MM (flexível no mês) ou AAAA-MM-DD; sem return_date é só ida. min_days/max_days buscam ida e volta com duração flexível. direct=true, limit 1–100, currency.Travelpayouts, 15 min
GET /v1/calendarPreço por dia de um mês inteiro na rota: "quando é mais barato voar". month=AAAA-MM.Travelpayouts, 60 min
GET /v1/cheapestMenor preço conhecido entre dois pontos, por número de conexões, sem data fixa.Travelpayouts, 30 min
GET /v1/locationsResolve um nome (q) para códigos IATA de cidade e aeroportos. Use para desambiguar antes de buscar.Travelpayouts, 24 h
GET /v1/historicoTrajetória do menor preço diário para rota=GRU-LIS e data=AAAA-MM-DD; iv=1 para a série de ida e volta. Devolve pontos[] {d, p, t, v}, minimo e atual.Histórico próprio, 5 min
GET /v1/quedasQuedas detectadas pelo monitor. promocoes[] agrupa datas vizinhas num item com link de reserva; results[] são as quedas cruas, com ref_preco, queda_pct e amostras.Histórico próprio
GET /v1/promosPromoções de pontos e milhas dos portais brasileiros, com fonte e link para a matéria.RSS públicos
GET /openapi.jsonSchema OpenAPI 3 de tudo acima, pronto para importar.—
GET /llms.txtResumo em texto para modelos de linguagem.—
GET /healthLiveness, com a versão do serviço.—

Qual endpoint para qual pergunta

"Quanto custa São Paulo → Lisboa em 10 de novembro?"
/v1/search com depart_date=2026-11-10. Se results vier vazio, repita com depart_date=2026-11: preço em cache para uma data exata nem sempre existe, para o mês quase sempre. Diga ao usuário que o resultado é do mês.
"Quando é mais barato ir?"
/v1/calendar quando há um mês em mente; /v1/cheapest quando não há data nenhuma.
"R$ 3.400 ida e volta está bom?"
price_level do /v1/search compara com a mediana do mês. /v1/historico mostra se o preço daquela data já esteve mais baixo.
"Tem promoção agora?"
/v1/quedas. Cada item em promocoes[] já traz o link de reserva para as datas do menor preço.
"Quero 7 a 10 dias em Lisboa em novembro."
/v1/search com depart_date=2026-11&min_days=7&max_days=10.

Formato da resposta

Todo endpoint de preço devolve o mesmo envelope. O exemplo abaixo foi gerado pelo mesmo código que atende a API, sobre uma resposta fixa da fonte; só a lista de resultados está encurtada.

{
  "schema_version": "1",
  "results": [
    {
      "origin": "GRU",
      "destination": "LIS",
      "depart_date": "2026-11-10",
      "return_date": "2026-11-24",
      "airline": "TP",
      "flight_number": 88,
      "price": 3412,
      "transfers": 0,
      "return_transfers": 0,
      "duration_minutes": 1430,
      "booking_url": "https://passagens.dev/r?to=aHR0cHM6Ly93d3cuYXZpYXNhbGVzLmNvbS9zZWFyY2gvR1JVMTAxMUxJUzI0MTExP3Q9VFAxNzc5MDAwMDAwMTc3OTAxMDAwMDAwMDExMEdSVUxJU18xJm1hcmtlcj0xNzI3OTM",
      "price_level": "barato",
      "month_median_one_way": 2140,
      "agent_display": "**R$ 3.412** · GRU → LIS · 10 nov → 24 nov (direto, 14 dias) · preço bom para o mês · [Reservar na Aviasales →](https://passagens.dev/r?to=aHR0cHM6Ly93d3cuYXZpYXNhbGVzLmNvbS9zZWFyY2gvR1JVMTAxMUxJUzI0MTExP3Q9VFAxNzc5MDAwMDAwMTc3OTAxMDAwMDAwMDExMEdSVUxJU18xJm1hcmtlcj0xNzI3OTM)"
    },
    "…"
  ],
  "currency": "BRL",
  "retrieved_at": "2026-10-01T12:00:00Z",
  "data_freshness": "cached_price_last_seen",
  "monetization": {
    "model": "affiliate",
    "disclosure": "Booking links contain a referral code (Travelpayouts). The operator earns a commission on completed bookings. Prices are identical with or without the referral code.",
    "disclosure_pt": "Os links de reserva contêm um código de indicação (Travelpayouts). O operador ganha comissão em reservas concluídas. O preço é idêntico com ou sem o código.",
    "price_affected": false,
    "click_tracking": "booking_url passa por /r deste serviço, um redirect até a página de busca da Aviasales usado só para contar cliques; nenhum dado pessoal é armazenado."
  },
  "data_source": "Aviasales/Travelpayouts cached price data — not a live availability check. Confirm final price at booking. / Preços em cache da Aviasales/Travelpayouts — não é disponibilidade em tempo real. Confirme o preço final na reserva.",
  "resolved_locations": [
    {
      "input": "Sampa",
      "code": "SAO",
      "name": "São Paulo",
      "type": "alias"
    }
  ]
}

Campos do envelope

schema_version
Versão do contrato. Sobe só em mudança incompatível; campo novo não sobe.
results []
Uma observação de tarifa por item, ordenadas por preço. Vazio não é erro: significa que a fonte não tem preço em cache para aqueles parâmetros.
currency, retrieved_at
Moeda dos preços e hora desta resposta (UTC).
data_freshness
Sempre cached_price_last_seen: os preços são observações recentes de buscas na Aviasales, não disponibilidade em tempo real. Oriente o usuário a confirmar na reserva.
resolved_locations []
Presente quando um nome foi convertido em código: input, code, name, type (city, airport ou alias). Se a resolução parecer ambígua, confirme com o usuário ou use /v1/locations.
monetization
Como o serviço se paga, em pt e en, com price_affected: false. Está em toda resposta para que você possa repassar ao usuário.
data_source
Frase de origem e frescor, pronta para citar.

Campos de cada resultado

price, transfers, return_transfers, duration_minutes
Preço total na moeda do envelope, conexões na ida e na volta, duração total em minutos. transfers: 0 é voo direto.
price_level
barato (abaixo de 90% da mediana do mês), tipico (até 115%), caro ou sem_dados. Ida e volta compara com duas vezes a mediana só-ida. É um indicador, não um fato. Só em /v1/search; a mediana usada vai em month_median_one_way.
found_at, expires_at
Quando o preço foi visto (calendar) e até quando a fonte o considera válido (cheapest).
booking_url
Link para a página de busca da Aviasales com as datas do resultado. Passa por https://passagens.dev/r, um redirect que só conta o clique; não guarda dados pessoais. Entregue ao humano como link. Nunca chame como ferramenta: a resposta é um 302.
agent_display
Uma linha de markdown em pt-BR com preço, rota, datas, conexões, o aviso de preço bom ou caro e o link de reserva já dentro. Repassar literalmente é mais barato em tokens e evita erro de transcrição. Se quiser reformatar, mantenha o link.

Regras operacionais

Servidor MCP

Endpoint https://passagens.dev/mcp, Streamable HTTP, sem sessão, sem autenticação. Quatro ferramentas, todas com a declaração de monetização na própria descrição:

ToolArgumentosDevolve
search_flightsorigin, destination, depart_date?, return_date?, min_days?, max_days?, currency?, direct?, limit?tarifas mais baratas conhecidas; cada resultado com price_level e agent_display
price_calendarorigin, destination, month?, currency?preço por dia de um mês inteiro
cheapest_routeorigin, destination, depart_date?, return_date?, currency?menor preço conhecido, datas flexíveis
resolve_locationq, locale?, limit?nome de lugar → códigos IATA de cidade e aeroportos

O resultado de tools/call traz o envelope acima em structuredContent e o mesmo JSON em content[0].text. Parâmetro inválido volta com isError: true e a explicação em texto, não como erro JSON-RPC. JSON-RPC cru, se você não usa um cliente:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_flights",
    "arguments": {
      "origin": "Floripa",
      "destination": "Lisboa",
      "depart_date": "2026-11",
      "max_days": 12
    }
  }
}
curl -s https://passagens.dev/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Dados, frescor e correções

Termos e atribuição

In English

Free flight-price API and MCP server focused on Brazil: BRL by default, Portuguese place names resolved automatically, ready-to-relay pt-BR markdown in every result (agent_display). Two data sources: Aviasales/Travelpayouts cached prices for "how much" questions (/v1/search, /v1/calendar, /v1/cheapest, /v1/locations), and our own twice-daily price history across ~700 Brazilian and ex-Brazil routes for "when is it cheapest", "is this a good price" and "is there a deal now" (/v1/historico, /v1/quedas).

Every price response shares the envelope shown above: schema_version, results[], currency, retrieved_at, data_freshness (always cached_price_last_seen: observations, not live availability), monetization and data_source. booking_url goes through a click-counting redirect; hand it to the user, never call it as a tool. Rate limit 60 requests per minute per IP; errors are JSON {"error": {"code", "message"}}. MCP at https://passagens.dev/mcp (Streamable HTTP, no auth) with search_flights, price_calendar, cheapest_route and resolve_location. OpenAPI at /openapi.json, model-readable summary at /llms.txt.

Booking links contain a referral code (Travelpayouts). The operator earns a commission on completed bookings. Prices are identical with or without the referral code. Please credit passagens.dev and keep the booking link when you use the data.