Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/igorek05m/daily-geogame/llms.txt

Use this file to discover all available pages before exploring further.

Saves the user’s guesses for a specific date, calculates geographic relationships, and manages session state. This endpoint handles both creating new sessions and updating existing progress.

Endpoint

POST /api/progress

Request body

date
string
required
The game date in YYYY-MM-DD format
guesses
Country[]
required
Array of country guesses. Each guess should include basic country data that will be enriched with calculated fields.

Response

success
boolean
required
Indicates if the progress was saved successfully
sessionId
string
required
The user’s session ID (UUID v4 format)
won
boolean
required
Whether the user has won the game (guessed correctly)
guesses
Country[]
required
The enriched array of guesses with calculated fields

Geographic calculations

The endpoint enriches each guess with calculated geographic data: Distance calculation uses the Haversine formula:
const distance = Math.round(
  getDistanceFromLatLonInKm(lat, lng, targetLat, targetLng)
);
From app/api/progress/route.ts:39 Bearing calculation computes the angle from guess to target:
const bearing = Math.round(
  getBearingAngle(lat, lng, targetLat, targetLng)
);
From app/api/progress/route.ts:40 Connection logic determines geographic relationships:
if (dailyGame.targetCountry.alpha3Code === g.alpha3Code) {
  connection = "guess"; // Exact match
} else if (dailyGame.targetCountry.borders?.includes(g.alpha3Code)) {
  connection = "neighbor"; // Shares border
} else if (dailyGame.targetCountry.subregion === g.subregion) {
  connection = "subregion"; // Same subregion
} else if (dailyGame.targetCountry.region === g.region) {
  connection = "region"; // Same region
}
From app/api/progress/route.ts:44-49

Session management

The endpoint automatically creates and manages user sessions:
  1. Checks for existing geo_session cookie
  2. Generates new UUID v4 session ID if not present
  3. Sets HTTP-only cookie with 10-year expiration
  4. Associates all progress with the session ID
if (!sessionId) {
    sessionId = uuidv4();
}
From app/api/progress/route.ts:20-22

Win detection

The game is marked as won when the newest guess matches the target country name (case-insensitive):
const newestGuess = guesses[0];
if (newestGuess.name?.toLowerCase() === dailyGame.targetCountry.name.toLowerCase()) {
    isWon = true;
}
From app/api/progress/route.ts:65-68

Example request

curl -X POST https://yourdomain.com/api/progress \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2026-03-02",
    "guesses": [
      {
        "name": "Germany",
        "alpha2Code": "DE",
        "alpha3Code": "DEU",
        "flag": "https://flagcdn.com/de.svg",
        "latlng": [51, 9],
        "region": "Europe",
        "subregion": "Western Europe"
      }
    ]
  }'

Example response

{
  "success": true,
  "sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "won": false,
  "guesses": [
    {
      "name": "Germany",
      "alpha2Code": "DE",
      "flag": "https://flagcdn.com/de.svg",
      "latlng": [51, 9],
      "distance": 516,
      "bearing": 78,
      "connection": "neighbor"
    }
  ]
}
The guesses array in the response is enriched with distance, bearing, and connection fields calculated on the server.

Error responses

Invalid payload:
{
  "error": "Invalid payload"
}
Status: 400 This occurs when:
  • date is missing
  • guesses is not an array
Failed to save:
{
  "error": "Failed to save"
}
Status: 500 This occurs when the database operation fails.

Code example

// Save progress after a guess
const saveProgress = async (date: string, guesses: Country[]) => {
  const response = await fetch('/api/progress', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ date, guesses })
  });
  
  const result = await response.json();
  
  if (result.won) {
    console.log('Congratulations! You won!');
  }
  
  return result.guesses; // Now includes distance, bearing, connection
};

GET /api/progress

Retrieves the user’s progress for a specific date, including guess history and personal statistics.

Endpoint

GET /api/progress

Query parameters

date
string
required
The game date in YYYY-MM-DD format.Validation: Must match the pattern ^\d{4}-\d{2}-\d{2}$

Authentication

Requires geo_session cookie. If no session exists, returns empty progress.

Response

guesses
Country[]
required
Array of the user’s guesses for this date (enriched with distance/bearing/connection)
won
boolean
required
Whether the user won this game
stats
object
required
User’s overall statistics across all games

Example request

curl https://yourdomain.com/api/progress?date=2026-03-02 \
  -H "Cookie: geo_session=a1b2c3d4-e5f6-7890-abcd-ef1234567890"

Example response

With existing progress:
{
  "guesses": [
    {
      "name": "Germany",
      "alpha2Code": "DE",
      "flag": "https://flagcdn.com/de.svg",
      "latlng": [51, 9],
      "distance": 516,
      "bearing": 78,
      "connection": "neighbor"
    }
  ],
  "won": false,
  "stats": {
    "gamesPlayed": 5,
    "wins": 3,
    "winRate": 60
  }
}
No session or no progress:
{
  "guesses": [],
  "winStreak": 0,
  "gamesPlayed": 0
}

Error responses

Invalid date:
{
  "error": "Valid date required"
}
Status: 400 Server error:
{
  "error": "Failed to load"
}
Status: 500

Code example

// Load user progress for today
const loadProgress = async (date: string) => {
  const response = await fetch(`/api/progress?date=${date}`);
  const progress = await response.json();
  
  console.log(`Played ${progress.stats.gamesPlayed} games`);
  console.log(`Win rate: ${progress.stats.winRate}%`);
  
  return progress;
};

Build docs developers (and LLMs) love