Odds da Pinnacle no Google Sheets
Este guia grava os 1X2 de futebol da Pinnacle numa planilha do Google Sheets: uma linha por partida, com odds decimais, odds justas sem margem e a margem do mercado. Um acionador por tempo atualiza a aba a cada 15 minutos. O script usa a API REST da PinnFeed, então roda no plano Free (€0, 30 segundos de atraso, 1.000 requisições/dia).
Passo 1 — Pegue uma chave Free#
- Crie uma conta em pinnfeed.io e abra o painel.
- Crie uma chave e copie. As chaves têm o formato
pf_live_…. - No Free, escolha até dois esportes no painel. O script usa futebol (
soccer) por padrão; troqueSPORTse escolheu outro.
Você não precisa do Builder para o Sheets. O Builder (€99/mês, o plano WebSocket) é para clientes push em tempo real, como os do guia de Python e Node.
Passo 2 — Crie a planilha#
- Crie uma planilha nova no Google Sheets.
- Renomeie a primeira aba para Odds (nome exato; o script procura por ele).
- Abra Extensões → Apps Script. Apague a função de exemplo
myFunctione deixe o projeto vazio para o próximo passo.
Passo 3 — Cole o script e defina as propriedades#
Cole isto em Code.gs:
// Google Apps Script: Extensões → Apps Script, cole este arquivo.
// Propriedades do script (Configurações do projeto → Propriedades do script):
// PINNFEED_BASE = https://pinnfeed.io
// PINNFEED_KEY = pf_live_...
// Crie uma aba chamada "Odds", rode refreshOdds uma vez e adicione um acionador a cada 15 minutos.
const PROPS = PropertiesService.getScriptProperties();
const BASE = PROPS.getProperty('PINNFEED_BASE') || 'https://pinnfeed.io';
const KEY = PROPS.getProperty('PINNFEED_KEY');
const SPORT = 'soccer'; // troque para basketball, tennis, … (precisa estar no seu plano)
function refreshOdds() {
if (!KEY) {
console.error('Set script property PINNFEED_KEY first');
return;
}
const url = BASE + '/v1/odds'
+ '?sport=' + encodeURIComponent(SPORT)
+ '&market=moneyline&main=true&live=false&limit=500';
const res = UrlFetchApp.fetch(url, {
headers: { 'x-api-key': KEY },
muteHttpExceptions: true,
});
const code = res.getResponseCode();
if (code !== 200) {
console.warn('PinnFeed HTTP ' + code + ': ' + res.getContentText().slice(0, 300));
return; // se a chamada falhar, a aba não é alterada
}
const data = JSON.parse(res.getContentText());
const rows = [];
for (const ev of data.events || []) {
const ml = (ev.markets || []).find((m) => m.type === 'moneyline' && m.main);
if (!ml) continue;
const byName = {};
for (const o of ml.outcomes || []) byName[o.name] = o;
const home = byName.home || {};
const draw = byName.draw || {};
const away = byName.away || {};
rows.push([
ev.startTime ? new Date(ev.startTime) : '',
(ev.league && ev.league.name) || '',
ev.home || '',
ev.away || '',
home.decimal || '',
draw.decimal || '',
away.decimal || '',
home.fair || '',
draw.fair || '',
away.fair || '',
ml.margin != null ? ml.margin : '',
ev.id,
]);
}
const sheet = SpreadsheetApp.getActive().getSheetByName('Odds');
if (!sheet) {
console.error('Create a tab named Odds first');
return;
}
sheet.clearContents();
sheet.appendRow([
'Starts', 'League', 'Home', 'Away',
'1', 'X', '2',
'Fair 1', 'Fair X', 'Fair 2',
'Margin', 'Event id',
]);
if (rows.length) {
sheet.getRange(2, 1, rows.length, 12).setValues(rows);
}
console.log('Wrote ' + rows.length + ' moneyline rows for ' + SPORT);
}
Depois abra a engrenagem do projeto (Configurações do projeto) e, em Propriedades do script, adicione:
| Propriedade | Valor |
|---|---|
PINNFEED_KEY | sua chave (pf_live_…) |
PINNFEED_BASE | https://pinnfeed.io (opcional; é o padrão) |
Nunca cole a chave nas células da planilha nem compartilhe publicamente o projeto do Apps Script.
Passo 4 — Rode uma vez e autorize#
- Escolha
refreshOddsno menu de funções e clique em Executar. - O Google pede permissão para conectar a um serviço externo e editar a planilha. Autorize para sua conta.
- Recarregue a planilha. A aba Odds deve mostrar as colunas
Starts,League,Home,Away,1,X,2, as três odds justas,MargineEvent id.
Se uma chamada falhar (chave errada, limite de requisições, esporte fora do plano), o script registra um aviso e mantém as linhas anteriores, então um minuto ruim nunca apaga o quadro.
Passo 5 — Adicione um acionador a cada 15 minutos#
- No Apps Script, abra Acionadores (ícone de relógio) → Adicionar acionador.
- Função:
refreshOdds. Origem do evento: Baseado no tempo. Tipo: Contador de minutos. Intervalo: A cada 15 minutos. - Salve.
São 96 chamadas por dia para um esporte, bem dentro das 1.000 requisições/dia e 1 req/s do plano Free. Dois esportes a cada 30 minutos também dão 96. Veja planos e limites (em inglês).
| Acionador | Chamadas / dia | Cabe no Free? |
|---|---|---|
| A cada 15 min, 1 esporte | 96 | sim |
| A cada 30 min, 2 esportes | 96 | sim |
| A cada 15 min, 2 esportes | 192 | sim |
| A cada 1 min, 1 esporte | 1.440 | não — precisa do Hobby ou acima (sem cota diária) |
O Apps Script tem cotas próprias além dessas; o acionador por tempo mais curto é de um minuto.
Passo 6 — Leia as odds justas e as margens#
Cada linha de 1X2 traz os campos sem margem da PinnFeed descritos no schema:
Fair 1/Fair X/Fair 2— a odd decimalfairde cada resultado (margem removida, método multiplicativo).Margin— amargindo mercado (overround = soma das probabilidades implícitas − 1).
Use essas colunas para comparar uma odd de casa soft em outra aba: o valor esperado é soft × (1 / fair) − 1, a mesma conta do guia de value bet. Para movimentos de steam ao vivo, o Sheets não é a ferramenta certa: use o WebSocket no Builder e o guia de detecção de steam.
Perguntas frequentes#
Qual plano da PinnFeed eu preciso?#
O Free basta para um quadro com atraso atualizado a cada poucos minutos. O Hobby (€29/mês) tira a cota diária e os 30 segundos de atraso, mas continua só REST. Push em tempo real precisa do Builder (€99/mês).
Por que o script usa x-api-key em vez de parâmetro na URL?#
É o cabeçalho de autenticação recomendado na documentação. O UrlFetchApp do Apps Script consegue enviar cabeçalhos, então não há motivo para colocar a chave na URL (onde ela pode vazar em logs).
Posso fazer um gráfico do histórico de preços?#
Sim. Mantenha a aba Odds como quadro ao vivo (limpa e reescrita a cada execução). Crie uma segunda aba que só acrescenta linhas depois de cada atualização e insira um gráfico de linhas. Não limpe a aba do histórico.
Este conteúdo é educativo e para maiores de idade?#
Sim. Dados de odds e ferramentas de planilha são material educativo para maiores de 18 anos. Nada aqui é palpite, aposta certa ou promessa de lucro.
Relacionado#
- Referência da API REST (em inglês) — filtros e paginação de
/v1/odds - Value bet com odds justas sem margem
- Bot de palpites no Telegram — quando a planilha ficar pequena
- Preços