On the wire · 04:52:47 UTC Live 548 · Prematch 14,380 · Markets 56,967 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Tutorial · Cloudflare · REST

Quote Pinnacle su un Cloudflare Worker

Aggiornato il · PinnFeed · 2 min di lettura

Risposta: salva la chiave con wrangler secret put PINNFEED_KEY. L'handler fetch del Worker fa da proxy di /v1/odds per il front con una cache edge breve (la chiave non raggiunge mai il browser); l'handler scheduled gira su un cron, chiama /v1/drops e posta i nuovi drop su un webhook Discord. Tutto REST — funziona da Free (ritardo 30 s).

wrangler.toml#

name = "pinnfeed-worker"
main = "src/index.js"
compatibility_date = "2026-11-01"

[triggers]
crons = ["*/2 * * * *"]
npx wrangler secret put PINNFEED_KEY      # ps_live_...
npx wrangler secret put DISCORD_WEBHOOK   # https://discord.com/api/webhooks/...
npx wrangler deploy

src/index.js#

const API = 'https://pinnfeed.io/v1';

export default {
  async fetch(req, env, ctx) {
    const url = new URL(req.url);
    if (url.pathname !== '/odds') return new Response('not found', { status: 404 });
    const sport = url.searchParams.get('sport') || 'soccer';
    const cache = caches.default;
    const cacheKey = new Request(`${url.origin}/odds?sport=${sport}`);
    let res = await cache.match(cacheKey);
    if (!res) {
      const r = await fetch(`${API}/odds?sport=${sport}&market=moneyline&main=true&limit=50`, {
        headers: { 'x-api-key': env.PINNFEED_KEY },
      });
      res = new Response(r.body, { status: r.status, headers: { 'content-type': 'application/json', 'cache-control': 'max-age=5' } });
      if (r.ok) ctx.waitUntil(cache.put(cacheKey, res.clone()));
    }
    return res;
  },

  async scheduled(_event, env) {
    const r = await fetch(`${API}/drops?sport=soccer&minutes=2&min_pct=5&limit=10`, {
      headers: { 'x-api-key': env.PINNFEED_KEY },
    });
    if (!r.ok) return;
    const { drops } = await r.json();
    if (!drops.length) return;
    const lines = drops.map((d) => `${d.home} v ${d.away}: ${d.market} ${d.outcome} ${d.from} → ${d.to} (${d.dropPct}%)`);
    await fetch(env.DISCORD_WEBHOOK, {
      method: 'POST', headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ content: lines.join('\n').slice(0, 1900) }),
    });
  },
};

Limiti da rispettare#

Free: 1 req/s e 1.000/giorno; Hobby 2/s; Builder 10/s. La cache edge evita che i picchi diventino chiamate API. Per push reale tieni il WebSocket su un server sempre acceso con Builder (99 €/mese). Prova 3 giorni; carta richiesta. REST gratis: signup.. Correlato: JS browser / CORS, proxy FastAPI.

Domande frequenti#

Il Worker può aprire il WebSocket?#

No in modo affidabile (esecuzione breve). Usa REST qui; WS su un server long-running.

Discord è obbligatorio?#

No — sostituisci l'URL del webhook con Slack, Telegram, ecc.

Contenuto educativo per adulti?#

Sì (18+).

Contenuto educativo per maggiorenni (18+): non pronostici né promesse di guadagno. In Italia scommetti solo con operatori autorizzati ADM.

Il piano WebSocket: Builder, 99 €/mese.

Quote Pinnacle in tempo reale su un unico WebSocket: tutti i 13 sport, tutti i mercati, quote eque senza margine e quote di chiusura. 3 giorni gratis, disdici con un clic.

Form K-1 · Free API key

Get your free API key.

One field. No password, no card: enter your email, click the link we send, and your key is on screen.

By continuing you agree to the Terms and Privacy Policy.

One free key per email. Link valid for 20 minutes.