Skip to main content
GET
/
games
/
{gameId}
Get a game with positions, officials, payments
curl --request GET \
  --url https://whistle.huddleup-sports.com/api/v1/games/{gameId} \
  --header 'Authorization: Bearer <token>'
import requests

url = "https://whistle.huddleup-sports.com/api/v1/games/{gameId}"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.text)
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

fetch('https://whistle.huddleup-sports.com/api/v1/games/{gameId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://whistle.huddleup-sports.com/api/v1/games/{gameId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://whistle.huddleup-sports.com/api/v1/games/{gameId}"

req, _ := http.NewRequest("GET", url, nil)

req.Header.Add("Authorization", "Bearer <token>")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.get("https://whistle.huddleup-sports.com/api/v1/games/{gameId}")
.header("Authorization", "Bearer <token>")
.asString();
require 'uri'
require 'net/http'

url = URI("https://whistle.huddleup-sports.com/api/v1/games/{gameId}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
{
  "data": {
    "id": "<string>",
    "leagueId": "<string>",
    "sport": "<string>",
    "startsAt": "2023-11-07T05:31:56Z",
    "location": "<string>",
    "latitude": 123,
    "longitude": 123,
    "source": "<string>",
    "externalId": "<string>",
    "positions": [
      {
        "id": "<string>",
        "label": "<string>",
        "payCents": 123,
        "payDollars": 123,
        "official": {
          "id": "<string>",
          "name": "<string>",
          "email": "<string>",
          "claimStatus": "confirmed"
        },
        "payment": {
          "id": "<string>",
          "positionId": "<string>",
          "officialId": "<string>",
          "amountCents": 123,
          "amountDollars": 123,
          "currency": "<string>",
          "paidAt": "2023-11-07T05:31:56Z",
          "failureCode": "<string>",
          "failureMessage": "<string>",
          "createdAt": "2023-11-07T05:31:56Z"
        }
      }
    ]
  }
}
{
"error": "unauthorized"
}
{
"error": "league_not_found"
}

Authorizations

Authorization
string
header
required

Partner API key: Authorization: Bearer whk_…. Keys are issued by the Whistle team (email tommy@huddleup-sports.com), shown once at issuance, and bound to your source namespace — they access only your leagues (plus explicit grants) and your webhook endpoints. Any auth failure returns 401 {"error":"unauthorized"}; the API never returns 403 — out-of-scope resources answer 404 exactly like nonexistent ones.

Path Parameters

gameId
string
required

Whistle game id (id from game responses).

Response

Game detail

data
object

Same as Game but each position embeds official and payment. A position's official is independent of its status — a cancelled slot can retain its official (no-show record).

Last modified on July 10, 2026