Use the REST endpoints below to query tracks and replays, inspect leaderboards, analyze GBX files, and submit authenticated replay uploads.
Public reads require no session unless an endpoint states otherwise. Uploads require an authenticated session. Administrative mutations also require the documented role and same-origin protections. Private event and TAS-of-the-Day data remain subject to server-side visibility rules.
Ping
GET /ping
A simple endpoint to check if the API is responsive.
Returns: A string "POnG".
Example Request:
curl https://tmtas.exchange/api/pingTracks
GET /tracks
Retrieves a list of tracks. Supports filtering, sorting, and pagination.
Filtering Parameters:
tmx_id: (optional) Filter by TMX ID (default: "0", which means no filtering)exchange: (optional) Filter by exchange (default: "*" for all exchanges, e.g. "tmnf", "tmuf")name: (optional) Filter tracks by name (case-insensitive, partial match)environment: (optional) Filter by environment- Accept values: "snow", "desert", "rally", "island", "coast", "bay", "stadium"
Sorting Parameters:
sortBy: (optional) Field to sort by (default: "name")- Valid options: "name", "exchange", "environment", "tmx_id", "latest_replay_date", "tas_time"
sortOrder: (optional) Sort order (default: "asc")- Valid options: "asc" (ascending), "desc" (descending)
Pagination Parameters:
amount: (optional) Number of results to return (default: 1, max: 50)fromResultIndex: (optional) 1-indexed starting position for pagination (default: 1)
Response Format:
results: Array of track objectstotal: Total number of tracks matching the filter criteria
Example Requests:
Basic query (returns first track, sorted by name):
curl https://tmtas.exchange/api/tracks Filter by Snow environment, sorted by latest replay date:
curl https://tmtas.exchange/api/tracks?environment=Snow&sortBy=latest_replay_date&sortOrder=desc&amount=10 Get tracks from all exchanges, sorted by fastest TAS time:
curl https://tmtas.exchange/api/tracks?exchange=*&sortBy=tas_time&amount=5POST /add_track
Adds one TMX track to the exchange. This is an administrator-only, same-origin mutation and is not a public ingestion endpoint.
Authentication and request requirements:
- An authenticated administrator session is required.
- The request must pass the platform's same-origin verification.
Content-Typemust beapplication/json.- Batch track ingestion is not supported by this route.
JSON fields:
tmx_idortmxId: required TMX IDexchange: optional supported exchange identifier
Authenticated same-origin request body:
{
"tmx_id": 12345,
"exchange": "tmnf"
}Suggest
GET /tracks/suggest
Typeahead search suggestions for track names. Returns up to 8 matching tracks.
Query Parameters:
q: (required) Search query string (minimum 2 characters)
Response Format:
Returns an array of objects (max 8) with the following fields:
name: Track nameexchange: Exchange the track belongs totmx_id: TMX ID of the track
Example Request:
curl https://tmtas.exchange/api/tracks/suggest?q=islandLeaderboards
GET /leaderboard
Retrieves the main leaderboard for a specific track.
Query Parameters:
track_id: (required) The ID of the trackamount: (optional) Number of results to return (default: 50, max: 50)
Example Request:
curl https://tmtas.exchange/api/leaderboard?track_id=123&amount=10GET /leaderboardCategories
Retrieves leaderboards for all categories of a specific track.
Query Parameters:
track_id: (required) The ID of the trackamount: (optional) Number of results to return (default: 50, max: 50)
Example Request:
curl https://tmtas.exchange/api/leaderboardCategories?track_id=123&amount=10Replays
GET /replays
Retrieves a lightweight list of matching replays. This endpoint always returns at most 500 results and does not expose full replay metadata like /replayData.
Query Parameters:
track_id: (optional) Filter by internal track IDtmx_id: (optional) Filter by TMX track IDminReplayTime: (optional) Minimum replay time in millisecondsmaxReplayTime: (optional) Maximum replay time in millisecondsminDate: (optional) Minimum replay date as a Unix timestampmaxDate: (optional) Maximum replay date as a Unix timestamp
At least one filter parameter is required. Results are sorted by newest first.
Response Fields:
id: Replay IDtrack_id: Internal track IDtmx_id: TMX track IDtime: Replay time in millisecondsdate: Replay upload date as a Unix timestampauthor: Comma-separated author names, if available
Example Requests:
curl "https://tmtas.exchange/api/replays?track_id=123" curl "https://tmtas.exchange/api/replays?tmx_id=456&minReplayTime=25000&maxReplayTime=26000" curl "https://tmtas.exchange/api/replays?minDate=1711929600&maxDate=1714607999"GET /replay
Downloads a replay file (.gbx) as an attachment.
Query Parameters:
id: (required) The ID of the replay
Example Request:
curl https://tmtas.exchange/api/replay?id=123 -o replay.gbxPOST /get_replay
Analyzes a replay file (.gbx) and returns metadata.
Request Body:
- The .gbx replay file as binary data
Example Request:
curl -X POST https://tmtas.exchange/api/get_replay \
--data-binary @/path/to/your/replay.gbxGET /replayData
Retrieves replay metadata and, optionally, formatted player inputs.
Query Parameters:
id: (required) The ID of the replayinputs: (optional) Set to "true" to include player inputs
Example Request (Metadata only):
curl https://tmtas.exchange/api/replayData?id=123 Example Request (with Inputs):
curl https://tmtas.exchange/api/replayData?id=123&inputs=trueUsers
GET /users
Retrieves a list of all registered users.
Example Request:
curl https://tmtas.exchange/api/usersCategories
GET /categories
Retrieves a list of all available run categories.
Example Request:
curl https://tmtas.exchange/api/categoriesUpload
POST /upload
Uploads a new TAS replay. Requires authentication via cookie. The request body must be `multipart/form-data`.
Form Fields:
replay: The .gbx replay fileauthors: JSON string of authors. Format: `[{"name": "user1"}]` for unregistered users or `[{"id": "123"}]` for registered userscategories: JSON string of run categories. Available categories: "Vanilla", "NOseboost", "Unrestricted", "LIS"routeTypes: (optional) JSON string of route type flags. Available route types: "No Cut", "WR Route"date: (optional) Date of the replayexchange: (optional) The exchange to use (default: "*")videoUrl: (optional) URL to a video of the TAS run (must use http or https)timestamp: (optional) When the TAS starts in the video (format: mm:ss or seconds, e.g. "1:30" or "90")
Authentication:
Requires the `auth-session` cookie for authentication.
Example Request:
curl -X POST https://tmtas.exchange/api/upload \
-H "Cookie: auth-session=YOUR_SESSION_TOKEN" \
-F "replay=@/path/to/your/replay.gbx" \
-F 'authors=[{"name":"user1"}]' \
-F 'categories={"noseboost":false,"lowInputStrat":false}' \
-F 'routeTypes={"noCut":true,"wrRoute":false}'TICK — Trackmania 2020
These public endpoints are for the TICK TAS client and Trackmania 2020 only. No API key or cookie is required, but replay uploads are accepted only when the replay's embedded Trackmania account is linked to a TMTAS Exchange account. Leaderboard reads use the normal TMTAS replay archive. Replay uploads normally publish there too, except while the replay's map is in an active TMTAS competition, when they are routed to that event.
GET /tick/leaderboard
map_uid is required and case-sensitive. The leaderboard returns only each player's best replay in each category, ordered by finish time in integer milliseconds, then replay ID. Author names include coauthors in their stored order. Deleted and private replays are excluded.
A well-formed UID with no TM2020 records returns HTTP 200 with an empty records array. Categories contain Unrestricted plus any other categories represented by the returned records. Category IDs are database IDs, not constants. Successful results may be cached for 10 seconds.
curl "https://tmtas.exchange/api/tick/leaderboard?map_uid=YOUR_MAP_UID" {
"records": [
{
"name": "player-nickname-or-linked-username",
"time_ms": 52341,
"replay_url": "https://tmtas.exchange/api/replay?id=12345",
"category_id": 3
}
],
"categories": [
{
"name": "Unrestricted",
"id": 3
}
]
} POST /tick/replays
Send the raw .Replay.Gbx bytes with Content-Type: application/octet-stream. Multipart forms, JSON, and query parameters are not accepted. The optional X-Replay-Filename header supplies the download filename; it defaults to TICK.Replay.Gbx. Maximum size: 25 MiB (26,214,400 bytes).
curl --fail-with-body "https://tmtas.exchange/api/tick/replays" \
-H "Content-Type: application/octet-stream" \
-H "X-Replay-Filename: MyRun.Replay.Gbx" \
--data-binary "@MyRun.Replay.Gbx" The server reads the game, map UID, finish time, and playerLogin from the structured replay header. It checks for an active TM2020 competition using that exact map UID before attempting normal map discovery. If no active competition matches, it resolves existing TM2020 maps or imports their metadata by exact UID from Trackmania Exchange, then independently from Nadeo Core services. It never falls back to another game. Nadeo-only maps have no TMX numeric ID; their track_url uses an internal TMTAS ID. Normal archive uploads receive the existing Unrestricted category.
Player logins are converted to their Trackmania account UUID for linked-account lookup (legacy login-form links also work). The linked TMTAS account becomes both the uploader and replay author. If no matching link exists, the endpoint returns HTTP 403 trackmania_account_link_required and does not resolve the map, create an unregistered author, or store replay data.
Active competitions: when the map belongs to an event that is currently inside its submission window, TICK does not publish the replay to the standard leaderboard. The replay is submitted to the event as the linked account and goes through the event replay validator. Events that require coauthors, input-count scoring, or required custom fields cannot be represented safely by an automatic TICK submission and return HTTP 409 with instructions to use the event page instead. After the event ends, uploads for that map use the normal archive path again.
Validation scope: normal archive uploads check TM2020 header structure and metadata consistency, not driving physics or account ownership. Active-competition uploads additionally use the event's existing TM2020 replay validation service before acceptance. File metadata can still be edited, and no TICK detector signature is required.
Normal archive success — HTTP 201
{
"replay_id": 12346,
"map_uid": "YOUR_MAP_UID",
"time_ms": 51987,
"category_id": 3,
"replay_url": "https://tmtas.exchange/api/replay?id=12346",
"track_url": "https://tmtas.exchange/trackshow/334551?exchange=tm2020"
} Active competition success — HTTP 201
{
"submission_target": "event",
"event_id": 230,
"event_replay_id": 9876,
"map_uid": "YOUR_MAP_UID",
"time_ms": 51987,
"event_url": "https://tmtas.exchange/events/230"
} Nadeo map-service authentication is server-side and does not require client credentials. TICK replay upload authorization still comes from the replay's linked Trackmania identity. Map metadata is cached for up to 24 hours, genuine misses for five minutes. Successful imports are stored locally. The upload fast path checks local tracks first; a cold TMX lookup is bounded to one second before Nadeo fallback so a slow Trackmania Exchange request cannot hold every upload for the previous five-second timeout. The leaderboard remains a read-only list of records; an empty list does not mean a map cannot be uploaded.
Errors and retries
Errors always use a JSON error string and may also include a human-readable message. HTTP 400 covers malformed replays, missing/invalid player login or UID, unexpected parameters, and failed competition replay validation; 403 trackmania_account_link_required; 404 map_not_found; 409 duplicate_replay, competition_requires_web_submission, multiple_active_competitions, or competition_closed_or_changed; 413 file_too_large; 415 unsupported_media_type; 422 not_tm2020; 429 rate_limited; 503 service_unavailable, replay_validation_unavailable, category_unavailable, or an upstream map-service error. A 404 map_not_found is returned only after both map sources confirm a miss; missing credentials, timeouts, and upstream failures remain retryable 503 responses.
{
"error": "not_tm2020"
} POST is limited to 10 attempts per connecting IP in each fixed 10-minute window, including rejected requests. GET is not subject to this upload limit. A 429 response includes Retry-After in seconds; RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset (Unix seconds) are also returned. CORS permits the filename header. Do not automatically retry 400/404/413/415/422 responses; check the leaderboard after an uncertain upload response or 409.
Misc
POST /get_track_info
Analyzes a track file (.gbx) and returns its unique ID.
Request Body:
- The .gbx track file as binary data
Example Request:
curl -X POST https://tmtas.exchange/api/get_track_info \
--data-binary @/path/to/your/track.gbxPOST /detectSO
Analyzes a replay to detect special techniques like Uberbug and Noseboost. Returns detected speedrun options and reasons.
Form Fields:
replay: The .gbx replay file
Example Request:
curl -X POST https://tmtas.exchange/api/detectSO \
-F "replay=@/path/to/your/replay.gbx"