Import logs

Import logs

Results (.xml), telemetry (.duckdb) and replay (.Vcr) files from Le Mans Ultimate.

Sign in to send sessions

This server only accepts uploads from accounts. Browsing sessions stays open to everyone.

Sign in

Automatic upload

Windows · CLI

LMU Uploader for Windows lists your sessions, you pick, it sends. The replay is processed on your PC and only the result (about 1 MB) goes up.

Download LMU Uploader

Sends new files once (.xml, .duckdb and .Vcr; replays last, since they are large).

Continuous mode: watches the folders and sends .xml, .duckdb and .Vcr on save, once the file stops growing.

Where LMU keeps its logs

  • UserData\Log\Results results (.xml)
  • UserData\Telemetry telemetry (.duckdb)
  • UserData\Replays replays (.Vcr), with every car in the race. Save the replay in-game when you finish.

Send from a terminal or an agent

curl · MCP

  1. Send with POST https://<este-servidor>/api/ingest, one file per request: .xml (results), .duckdb (telemetry) and .lmur (processed replay). Do not send the raw .Vcr.
  2. Send the .xml files first. The .lmur must be named <xml name>.lmur and is only accepted once the session's .xml is on the server.
  3. Resending is safe. Repeated files come back as duplicates and are not stored again.
  4. This server requires sign-in to send. Without a token the POST returns 401. Send Authorization: Bearer <token>. The token comes from the device flow: POST /api/auth/device/code with client_id lmu-uploader, a signed-in person opens /device?user_code=… and approves, and the script polls /api/auth/device/token until it gets the token (example below).
  5. An AI agent finds all of this on its own at GET /api/ingest and /llms.txt.

Device sign-in (exports LMU_TOKEN)

LMU_URL=https://<este-servidor>
# 1) pede um código de dispositivo
CODE=$(curl -sS -X POST "$LMU_URL/api/auth/device/code" \
    -H "content-type: application/json" -d '{"client_id":"lmu-uploader"}')
DEVICE_CODE=$(printf '%s' "$CODE" | sed -n 's/.*"device_code":"\([^"]*\)".*/\1/p')
USER_CODE=$(printf '%s' "$CODE" | sed -n 's/.*"user_code":"\([^"]*\)".*/\1/p')
# 2) uma pessoa abre o link, entra na conta e aprova
echo "Abra e aprove: $LMU_URL/device?user_code=$USER_CODE"
# 3) espera a aprovação (authorization_pending = ainda não aprovou)
while :; do
  sleep 5
  R=$(curl -sS -X POST "$LMU_URL/api/auth/device/token" -H "content-type: application/json" \
      -d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:device_code\",\"device_code\":\"$DEVICE_CODE\",\"client_id\":\"lmu-uploader\"}")
  LMU_TOKEN=$(printf '%s' "$R" | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p')
  [ -n "$LMU_TOKEN" ] && break
  case "$R" in *authorization_pending*|*slow_down*) ;; *) echo "$R"; break ;; esac
done
export LMU_TOKEN   # use em "Authorization: Bearer $LMU_TOKEN"

One file

# LMU_TOKEN vem do login por dispositivo (exemplo "login"); sem ele o envio volta 401
curl -sS -X POST https://<este-servidor>/api/ingest \
    -H "content-type: application/octet-stream" \
    -H "x-file-name: 2026_07_19_10_06_31-70R1.xml" \
    -H "x-owner: meu-nome" \
    -H "authorization: Bearer $LMU_TOKEN" \
    --data-binary @2026_07_19_10_06_31-70R1.xml

Whole logs folder (xml, duckdb and lmur, in that order)

# LMU_TOKEN vem do login por dispositivo (exemplo "login"); sem ele o envio volta 401
LMU_LOGS=/data/logs   # pasta com os logs do jogo
LMU_URL=https://<este-servidor>
# a ordem importa: .xml primeiro (o .lmur só entra se o .xml da mesma sessão já estiver no servidor)
for ext in xml duckdb lmur; do
  find "$LMU_LOGS" -type f -iname "*.$ext" -not -path "*/.cache/*" -not -path "*/.promo/*" -print0 |
  sort -z | while IFS= read -r -d '' f; do
    curl -sS -X POST "$LMU_URL/api/ingest" \
      -H "content-type: application/octet-stream" \
      -H "x-file-name: $(basename "$f")" \
      -H "x-owner: meu-nome" \
      -H "authorization: Bearer $LMU_TOKEN" \
      --data-binary @"$f"; echo
  done
done

Imported this session

Nothing imported yet

Files you send show up here until you reload the page.