{"openapi":"3.1.0","info":{"title":"Vietlott historical statistics API","version":"1.0.0","description":"Public read-only Mega 6/45 and Power 6/55 data. Stats computed outside Cloudflare. Power special_number is the seventh ball, excluded from main-number statistics. Percentages use 0..100. Draw codes are strings preserving leading zeros. Stats metadata reports its own coverage; source sync can precede snapshot publication. Scheduled hourly on a Vietnam-network runner; requires that runner to be awake and online. Full history rechecked at least every seven days when runner is available."},"externalDocs":{"description":"Static full datasets and statistics: no request-time Functions or D1. Paths contain game; query filters are not supported.","url":"https://lott-data.pages.dev/v1/index.json"},"servers":[{"url":"https://lott.zindo.info/api/v1"}],"security":[],"paths":{"/games":{"get":{"summary":"Available games and last successful sync","parameters":[],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/SyncStatus"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sync-status":{"get":{"summary":"Sync coverage (all games when game omitted); stale after 3 hours","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"$ref":"#/components/schemas/SyncStatus"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/overview":{"get":{"summary":"Latest draw and verified sync coverage","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"sync":{"$ref":"#/components/schemas/SyncStatus"},"latest_draw":{"$ref":"#/components/schemas/Draw"}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/draws":{"get":{"summary":"Historical results, oldest first; keep game/date filters when following next_cursor","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"cursor","in":"query","schema":{"type":"string","pattern":"^[0-9]{5}$"}},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Inclusive draw date"},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Inclusive draw date"}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","required":["items","limit","next_cursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Draw"}},"limit":{"type":"integer"},"next_cursor":{"type":["string","null"],"description":"Pass as cursor for next page. Null means end. New draws can appear during pagination; rerun after a backfill to include earlier inserts."}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/number-stats":{"get":{"summary":"Precomputed number-stats for full history","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"number":{"type":"integer"},"frequency":{"type":"integer"},"gap":{"type":"integer"},"expected_frequency":{"type":"number"},"deviation":{"type":"number"},"last_seen_draw_code":{"type":["string","null"]}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/patterns":{"get":{"summary":"Precomputed patterns for full history","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"pattern_type":{"type":"string"},"pattern_key":{"type":"string"},"count":{"type":"integer"},"percentage":{"type":"number"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pairs":{"get":{"summary":"Precomputed pairs for full history","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"number_a":{"type":"integer"},"number_b":{"type":"integer"},"count":{"type":"integer"},"expected":{"type":"number"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/deltas":{"get":{"summary":"Precomputed deltas for full history","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"position":{"type":"integer"},"delta":{"type":"integer"},"count":{"type":"integer"},"percentage":{"type":"number"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/positions":{"get":{"summary":"Precomputed positions for full history","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"position":{"type":"integer"},"number":{"type":"integer"},"count":{"type":"integer"},"percentage":{"type":"number"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/weekdays":{"get":{"summary":"Precomputed weekdays for full history","parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string","enum":["mega645","power655"],"default":"mega645"}}],"responses":{"200":{"description":"Success. History/statistics cache for 6 hours; overview 1 hour; games/sync-status 5 minutes. Browser cache up to 1 hour.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"array","items":{"type":"object","properties":{"weekday":{"type":"integer","minimum":0,"maximum":6,"description":"Sunday=0, Monday=1, ..., Saturday=6"},"number":{"type":"integer"},"frequency":{"type":"integer"},"draws_on_weekday":{"type":"integer"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Request or database budget exceeded; retry after 60 seconds. Local per-isolate guard, not a global WAF limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer","example":60}}}},"503":{"description":"Data not yet synced or temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"}}},"Meta":{"type":"object","properties":{"api_version":{"type":"string"},"game":{"type":"string"},"total_draws":{"type":"integer"},"latest_draw_code":{"type":"string"},"latest_draw_date":{"type":"string","format":"date"},"computed_at":{"type":"string","format":"date-time"},"fetched_at":{"type":"string","format":"date-time"},"order":{"type":"string"}}},"Draw":{"type":"object","properties":{"game":{"type":"string"},"draw_code":{"type":"string","pattern":"^[0-9]{5}$"},"draw_date":{"type":"string","format":"date"},"n1":{"type":"integer"},"n2":{"type":"integer"},"n3":{"type":"integer"},"n4":{"type":"integer"},"n5":{"type":"integer"},"n6":{"type":"integer"},"special_number":{"type":["integer","null"],"description":"Power seventh ball; null for Mega"},"source_url":{"type":"string","format":"uri"},"updated_at":{"type":"string","description":"D1 UTC timestamp"}}},"SyncStatus":{"type":"object","properties":{"game":{"type":"string"},"total_draws":{"type":"integer"},"first_draw_code":{"type":"string"},"latest_draw_code":{"type":"string"},"latest_draw_date":{"type":"string","format":"date"},"missing_draw_count":{"type":"integer"},"last_success_at":{"type":"string","format":"date-time"},"last_full_sync_at":{"type":["string","null"]},"source_url":{"type":"string","format":"uri"},"is_stale":{"type":"boolean"}}}}}}