Blog Docs Markets Portal Sign up
HomeBlog › How to Source 1X2 Odds Programmatically

How to Source 1X2 Odds Programmatically: A Practical Guide

Tutorial 27 May 2026 · 7 min read

1X2 — home win, draw, away win — is the most-traded market in soccer and the first thing any new sportsbook needs. It's also the cleanest market to learn an odds API on: three outcomes, no lines, no exotic settlement rules.

The minimum endpoint call

curl -X POST https://api.euro365.bet/v1/odds \
  -H 'X-API-Key: YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"sport":1,"market":1001,"events":["s5_p18983062"]}'

Market ID 1001 is the canonical 1X2 market in Euro365's catalog (see /v1/markets?sport=1). The response is shaped like:

{
  "s5_p18983062": {
    "1001": {
      "s": {
        "2001": [356, 0, 2533, 0, 1779865578168],
        "2002": [282, 0, 3201, 0, 1779865578168],
        "2003": [211, 0, 4270, 0, 1779867091328]
      }
    }
  }
}

Three outcomes: 2001 (home), 2002 (draw), 2003 (away). The number you care about is the first element of each array: 356 = decimal odds 3.56, 282 = 2.82, 211 = 2.11.

Normalizing into your domain model

The wire format above is compact-on-purpose (we're shipping millions of these per minute), but most application code wants a friendlier shape:

function normalize1x2(payload, eventId) {
  const o = payload[eventId]?.['1001']?.s ?? {};
  return {
    home: o['2001']?.[0] / 100,
    draw: o['2002']?.[0] / 100,
    away: o['2003']?.[0] / 100,
    ts:   Math.max(o['2001']?.[4] ?? 0, o['2002']?.[4] ?? 0, o['2003']?.[4] ?? 0),
  };
}

Computing the bookmaker margin

Every 1X2 set has an implied margin (overround). If the three implied probabilities sum to more than 1, the bookmaker is built in profit:

function margin({ home, draw, away }) {
  const impl = 1/home + 1/draw + 1/away;
  return (impl - 1) * 100;  // % overround
}

Typical T1 leagues sit at 4–7% margin; lower leagues run 8–15%. Anything > 15% on a top match means the upstream is being defensive (usually because of late team news or a thin market).

Live 1X2 over WebSocket

If you want every price tick (rather than polling), open a WebSocket subscribed to the event:

const ws = new WebSocket('wss://api.euro365.bet/ws?api_key=YOUR_KEY');
ws.onopen = () => ws.send(JSON.stringify({
  subscribe: { event_id: 's5_p18983062', markets: ['1001'] }
}));
ws.onmessage = m => {
  const d = JSON.parse(m.data);
  if (d.market === '1001') update1x2(d.outcomes);
};

Note the 5-connections-per-key cap (docs) — fan out from your own backend, don't open one connection per browser tab.

Edge cases worth handling on day one

Get a free key All soccer markets