📻

API de Listagem de Rádios

API de Listagem de Rádios

Facets de géneros por eixo

GET /radios/facets?locale=pt mantém o array plano genres para clientes
existentes e acrescenta genreAxes, separando a taxonomia ortogonal entre
music e content:

{
  "genres": [
    { "value": "pop", "count": 120, "label": "Pop" },
    { "value": "news", "count": 80, "label": "Notícias" }
  ],
  "genreAxes": {
    "music": [{ "value": "pop", "count": 120, "label": "Pop" }],
    "content": [{ "value": "news", "count": 80, "label": "Notícias" }]
  },
  "languages": [],
  "countries": []
}

Valores legados ainda não reconhecidos pela taxonomia continuam presentes em
genres, mas não são atribuídos artificialmente a nenhum eixo. O filtro
continua a enviar o valor canónico existente em ?genre=...; não há alteração
na semântica da pesquisa nem migração de dados.

Endpoint

GET /radios

Descrição

Endpoint público para listar todas as rádios disponíveis na plataforma Audissey. O endpoint está protegido com rate limiting (100 requisições por minuto).

Parâmetros de Query (Opcionais)

Parâmetro Tipo Valores Aceites Descrição
genre string - Filtrar rádios por género específico
language string - Filtrar rádios por idioma (ex: 'pt', 'en')
sortBy string 'home', 'name', 'popularity' Ordenar resultados. home replica o ranking popular da Home (cliques/votos e diversidade), pelos idiomas do utilizador (ver abaixo).
country string - Filtrar por país (nome em inglês). Com sortBy=home substitui Portugal e desliga a ordenação por idiomas.
locale string - Locale da UI para os rótulos. Com sortBy=home e sem sessão, é também o idioma do dispositivo.
countryCode string ISO 3166-1 alpha-2 Só com sortBy=home e sem sessão: país do dispositivo (ex: GB). Nunca filtra.
page number 1+ Página (1-based)
pageSize number 1-200 Itens por página (padrão 50)

Resposta

Formato

[
  {
    "id": "string",
    "name": "string",
    "stream_url": "string",
    "genre": ["string"],
    "language": "string",
    "country": "string",
    "logo_url": "string"
  }
]

Campos

Exemplos de Uso

Listar todas as rádios

GET /radios

Filtrar por género

GET /radios?genre=Rock

Filtrar por idioma

GET /radios?language=pt

Filtrar por género e idioma

GET /radios?genre=Pop&language=en

Ordenar por nome

GET /radios?sortBy=name

Combinação de filtros

GET /radios?genre=Jazz&language=pt&sortBy=name

Continuação de Rádios populares da Home

GET /radios?sortBy=home&page=1&pageSize=50
GET /radios?sortBy=home&page=2&pageSize=50

As duas páginas usam a mesma ordenação determinística; os empates são
resolvidos por _id e os resultados não se repetem entre páginas.

"Ver mais" pelos idiomas do utilizador

sortBy=home é o "Ver mais" do carrossel "Rádios populares" da Home e segue
os mesmos idiomas de conteúdo:

Com idiomas, a lista é:

  1. as rádios ativas de cada país das variantes do utilizador (por
    origin_country, até 5 países, o da variante preferida primeiro), seguidas
    das mais populares do mundo que ainda não estejam na lista, para nada ficar
    escondido. Uma query por país e uma mundial, cada uma com no máximo 200
    rádios (HOME_RANKING_CANDIDATE_LIMIT), por isso a lista tem no máximo
    6 × 200 = 1 200 rádios;
  2. cada bloco no ranking da Home de sempre (cliques, votos, _id, diversidade
    de géneros);
  3. reordenada por idioma (rerankByLanguage) com a força dos destaques da
    Home (homeHighlightsLanguageStrength: 2 × SUGGESTION_LANGUAGE_STRENGTH,
    no máximo 2).

Um utilizador en-GB vê primeiro as rádios britânicas, depois as das outras
variantes da sua lista e as da mesma língua, depois as restantes. Um
utilizador pt-PT vê primeiro a lista de Portugal de sempre, seguida do resto
do mundo. A paginação (page/pageSize) corta a lista inteira, que não
depende da página.

Sem idiomas (convidado sem countryCode: dispositivo sem região e sem localização, ou uma app antiga), com
SUGGESTION_LANGUAGE_STRENGTH=0, ou com um filtro country, é a lista de
sempre: as 200 rádios mais populares de Portugal (ou desse país). Também o é
quando nenhum dos países do utilizador tem rádios (com os filtros pedidos):
antes da migração 013 nenhuma rádio tem origin_country, e o top mundial
sozinho não ordenaria nada (pt e pt-BR têm a mesma língua base). Nesse
caso a query mundial nem é feita.

Pré-requisitos (runbook): a migração 20261023_013 (preenche
origin_country/locale) e o índice
is_active_1_origin_country_1_clickcount_-1_votes_-1__id_1 do
indexes.json. Sem o índice, cada query por país vazia faz FETCH de todas as
rádios ativas e um SORT (cerca de 236 ms medidos em staging, até 5 por
página); sem a migração, a lista é a de sempre (acima). As verificações
ver-mais-by-country e ver-mais-worldwide do explain-smoke confirmam os
planos.

Notas aceites na revisão:

# Convidado num dispositivo inglês no Reino Unido
GET /radios?sortBy=home&page=1&pageSize=50&locale=en&countryCode=GB

Para ver as parcelas da pontuação de cada rádio (administradores), ver
Debug da ordenação por idioma
(debugRanking=true, também em GET /radios/nearby e GET /radios/nearby-geo).

Rate Limiting

O endpoint está protegido com rate limiting:

Se o limite for excedido, a API retornará o status HTTP 429 (Too Many Requests).

Os sinais autenticados têm também limites por utilizador (req.user._id),
independentes da rádio e do IP: POST /radios/:id/now-playing aceita 30
pedidos por minuto e POST /radios/:id/listen aceita 60. As duas contagens
são separadas; ultrapassar um limite devolve 429 e não consome a quota de
outro utilizador. Sem autenticação, estas rotas devolvem 401.
As contagens ficam em memória em cada réplica; com cinco réplicas, o limite
efetivo pode chegar a cinco vezes estes valores. O limite global por IP
continua a aplicar-se.

Códigos de Resposta

Código Descrição
200 Sucesso - Lista de rádios retornada
429 Too Many Requests - Rate limit excedido
500 Internal Server Error - Erro no servidor

Notas