← ResultsZA

South African Lottery API: building without the scraping headache

A practical guide to getting Lotto, Powerball and Daily Lotto results into your app as clean JSON, without writing a single scraper.

resultsza.co.za  /  For developers

At some point a developer in South Africa decides they want lottery results in their app. Maybe it is a WhatsApp bot for a work syndicate. Maybe it is a mobile app that sends a notification the moment results drop. Maybe it is a website, a dashboard, a Google Sheet that updates automatically. The idea is straightforward. Then they go looking for a South African lottery API and discover the official site has nothing.

The National Lottery website was not built for developers. There is no public API. The HTML changes without notice. A scraper that works on Monday can silently break by Thursday, returning stale results to your users while you have no idea anything is wrong. Plenty of good projects have died in that maintenance loop.

The ResultsZA API is the shortcut past all of that. One HTTPS GET request with your API key and you have structured JSON back in under a second. No parsing, no brittle selectors, no cron job watching a website.

What you can build with this

To make this concrete, here are things developers have built or are building with SA lottery data:

The common thread is that none of these need you to think about data infrastructure. You call the endpoint, you get the data, you build the thing you actually wanted to build.

What comes back

Here is the full response from the Lotto endpoint, nothing trimmed. This is exactly what arrives in your application:

JSON response
{ "status": "success", "results": [{ "game_type": "Lotto", "draw_id": 2412, "draw_date": "2026-06-14T21:00:00Z", "draw_day": "Saturday", "draw_machine": "RNG4", "winning_numbers": [3, 14, 22, 31, 44, 48], "bonus_ball": 17, "total_pool_size": 4250000.00, "total_sales": 14876543.00, "next_draw_date": "2026-06-17T21:00:00Z", "next_jackpot": 5000000.00, "rollover_amount": null, "rollover_no": 0, "divisions": [ { "division": 1, "match": "6 of 6", "winners": 0, "winning_amount": 0.00 }, { "division": 2, "match": "5 of 6 + Bonus", "winners": 2, "winning_amount": 98432.50 }, { "division": 3, "match": "5 of 6", "winners": 47, "winning_amount": 3241.80 } ] }] }

A couple of things that will save you time. Dates come back as ISO 8601 with a UTC offset, so you can feed draw_date directly into any date library without string wrangling. The divisions array contains the full prize breakdown for every tier, not just the jackpot. That is the part that makes a results display actually useful to your users, rather than just showing the six winning numbers.

Historical draws are included

Need results from five years ago for an analysis project? Add a date parameter in YYYY-MM-DD format and you get the draw for that day. Leave it off and you get the most recent draw. The archive covers years of data across all games.

Query parameters
# Most recent draw GET /api/get_lotto_results?api_key=YOUR_KEY # Specific date GET /api/get_lotto_results?api_key=YOUR_KEY&date=2025-01-04

South African Lottery API endpoints

There is a dedicated endpoint for each SA game. The same request pattern applies to all of them.

UK 49s (Brunchtime, Lunchtime, Drivetime and Teatime), EuroMillions, US Powerball and US Mega Millions are also available. See the full API documentation for those endpoints.

Making your first request

Here is everything it takes to pull the latest Lotto result in Python. No database to set up, no parsing to write. You go from zero to working in the time it takes to read this.

import requests API_KEY = "your_api_key_here" response = requests.get( "https://resultsza.co.za/api/get_lotto_results", params={"api_key": API_KEY} ) data = response.json() result = data["results"][0] print(result["draw_date"]) print(result["winning_numbers"]) print(result["bonus_ball"]) # Historical draw hist = requests.get( "https://resultsza.co.za/api/get_lotto_results", params={"api_key": API_KEY, "date": "2025-01-04"} )
const API_KEY = "your_api_key_here"; const res = await fetch( `https://resultsza.co.za/api/get_sa_powerball_results?api_key=${API_KEY}` ); const data = await res.json(); const result = data.results[0]; console.log(result.draw_date); console.log(result.winning_numbers); console.log(result.powerball); // Powerball uses this field, not bonus_ball console.log(result.next_jackpot); // Historical draw const hist = await fetch( `https://resultsza.co.za/api/get_sa_powerball_results?api_key=${API_KEY}&date=2025-03-18` );
# Latest draw curl "https://resultsza.co.za/api/get_daily_lotto_results?api_key=your_api_key_here" # Specific date curl "https://resultsza.co.za/api/get_lotto_results?api_key=your_api_key_here&date=2025-06-07"

One thing to watch for: Powerball uses a different field name

Lotto games return a bonus_ball. Powerball and Powerball Xtra return a powerball field instead. Everything else in the response is identical across all games, which makes it straightforward to build a single display component and reuse it. The documentation has the full field reference for each endpoint.

Why not just scrape the results page?

A scraper that works today will break without warning. An API is a contract.

The National Lottery website was not built for developers. When they update a page layout or move data around, your scraper breaks and keeps returning the last cached result. You find out when a user reports that the numbers look wrong, not when the change happened. ResultsZA monitors the source, handles all of that on our end, and your integration keeps working without any action from you.

There is also data you simply cannot get by scraping the results page: years of historical draws, full prize breakdown tables for every division, rollover amounts, next jackpot estimates, and the exact timestamp of the next draw. All of it comes back in a single API response.

Authentication takes about 30 seconds to set up

Pass your API key as the api_key query parameter on every request. There is no OAuth flow, no token refresh cycle, no headers to configure. Register, choose a subscription plan, verify your email, and you have a working key. The response includes your remaining monthly quota in the headers, so you can track usage from inside your application without ever logging into a dashboard.

Start building today

Register, choose a subscription plan, verify your email, and your API key is ready immediately. Most developers have data in their app within the first 15 minutes.

Get your API key Read the full documentation →