Dois nomes de time idênticos e dois preços decimais não bastam para estabelecer uma comparação. Os registros precisam se referir ao mesmo evento, período de liquidação, regra de mercado, linha e seleção. Trate a normalização como a preservação desses significados, não apenas como renomear propriedades JSON.
O esquema abaixo é um projeto de aplicação proposto. Ele não descreve um formato universal de feed.
Separe identidade de observação
Mantenha uma tabela canônica de eventos e uma tabela separada de mapeamento de feeds. Um ID canônico de evento deve permanecer estável quando o feed muda seu ID ou um horário de início é corrigido. Guarde o ID original da fonte junto de cada observação para poder auditar uma junção depois.
Para um candidato a correspondência, compare esporte, competição, participantes, início agendado e orientação casa/fora. Use apelidos para gerar candidatos e depois verifique conflitos. Confrontos repetidos, jogos remarcados, duplas, times reservas e locais neutros podem derrotar a correspondência simples por nome. Uma pontuação de confiança pode encaminhar um candidato para revisão; ela não deve converter silenciosamente incerteza em identidade.
Feeds derivados da Pinnacle mostram por que o ID da fonte importa. Uma partida ao vivo pode chegar como um confronto pai mais confrontos filhos reemitidos que compartilham os mesmos nomes de time, e o mesmo mercado pode aparecer sob dois IDs ao mesmo tempo, um atual e um de fechamento, com preços diferentes. Indexe as observações pelo ID de evento do feed, nunca pelos nomes dos times.
Mantenha os mapeamentos não resolvidos visíveis. Excluí-los de uma comparação enquanto se informa a contagem de exclusões é preferível a exibir uma diferença de preço precisa para eventos incompatíveis.
Construa a chave de mercado antes da coluna de preço
| Elemento da chave | Significado de exemplo | Por que não pode ser descartado |
|---|---|---|
| Evento | ID canônico da partida | Os mesmos times podem se enfrentar mais de uma vez |
| Período | Jogo completo, primeiro tempo, primeiro set | Períodos são contratos diferentes |
| Família de mercado | Moneyline, total, handicap | Os preços se referem a conjuntos de resultados diferentes |
| Regra de liquidação | Somente tempo regulamentar, prorrogação incluída | Rótulos parecidos podem liquidar de forma diferente |
| Linha | Total 2.5, handicap da casa -0.5 | Linhas diferentes não são preços intercambiáveis |
| Seleção | Casa, fora, empate, mais, menos, participante | Inverter a orientação cria diferenças falsas |
| Fonte | Feed e casa de apostas subjacente | Um agregador e sua fonte são identidades diferentes |
Não infira regras de prorrogação a partir do nome de um esporte nem atribua um padrão não documentado. Uma regra de liquidação desconhecida deve bloquear uma comparação que dependa dela. Distinga mercados indisponíveis, suspensos, fechados e abertos; um valor ausente não é uma odd decimal de zero.
Um registro mínimo de observação
Estes são dados sintéticos ilustrativos, não uma resposta real de feed nem uma observação medida:
Os exemplos de integração usam endpoints fictícios. Defina a URL base da API e as credenciais do seu provedor e verifique o esquema atual dele antes de fazer uma requisição real.
{
"schemaVersion": 1,
"canonicalEventId": "example-event-001",
"feedId": "example-feed",
"sourceEventId": "example-source-event",
"bookmakerId": "example-bookmaker",
"period": "full_game",
"market": "total",
"settlementRule": "regulation_only",
"line": "2.5",
"selection": "over",
"decimalOdds": "1.95",
"status": "open",
"sourceUpdatedAt": null,
"receivedAt": "2026-09-26T10:00:00Z",
"sourceSequence": null,
"mappingVersion": "example-v1"
}
Strings decimais tornam explícitas as escolhas de precisão. Faça o parse delas com uma representação numérica que entenda decimais quando a identidade exata da linha importar. Normalize 2.50 e 2.5 para a mesma linha canônica enquanto mantém o valor bruto original em um armazenamento de proveniência permitido. Rejeite preços malformados, números não finitos e odds decimais iguais ou inferiores a um.
O conversor de odds pode demonstrar formatos de exibição; ele não resolve a identidade do mercado. Mantenha a representação da fonte se o arredondamento importar para análises posteriores.
Dê um trabalho a cada timestamp
sourceUpdatedAt deve significar exatamente o que a fonte diz que significa. receivedAt registra quando seu coletor recebeu a observação. Um início de evento agendado não é nenhum dos dois. Represente timestamps com fuso horário, como valores RFC 3339 em UTC; um formato de string padronizado não estabelece a precisão do relógio. RFC 3339.
Se nenhum horário de atualização da fonte estiver disponível, preserve o nulo. Não o preencha com o horário de recebimento para depois chamar a diferença de latência do feed. Quando tiver um timestamp da fonte, registre sua resolução e se ele se aplica a uma seleção individual, a uma casa de apostas ou a um snapshot inteiro.
Torne a ingestão idempotente
Defina uma chave de deduplicação a partir de fonte, evento, mercado, seleção e sequência documentada ou identidade da observação. Se um feed não tiver sequência durável, hashes de conteúdo podem suprimir repetições idênticas, mas não podem provar que você recebeu cada mudança intermediária.
Mantenha uma visão de estado atual separada do histórico de observações. Um upsert de estado atual responde o que foi visto por último; uma tabela de observações apenas de anexação responde o que o coletor viu ao longo do tempo. Versione o mapeador para que uma definição de mercado corrigida possa ser recalculada sem reescrever o significado dos registros antigos.
Antes de mostrar uma diferença, exija chaves de mercado compatíveis, preços válidos, status conhecido, idade de observação aceitável e um mapeamento revisado. Continue com a avaliação de dados históricos ou a metodologia de benchmark, dependendo do produto que você está construindo.
Fontes 2 referências
Documentação primária usada neste guia. As datas de verificação referem-se à revisão da fonte.
- RFC 3339: data e hora na internetVerificado em 26 de set de 2026
- Referência técnica da API de dados da PinnacleVerificado em 26 de set de 2026