Bulk Data Feed
Public game data in bulk, rebuilt every night. Free to use, no key required.
Building a database, a leaderboard, a bot, or a research project? Take the feed instead of crawling the site. It is the same public data, it is about 900 KB for the whole thing, and it costs us nothing to serve. Crawling thousands of profile pages costs us real money and gets you the same numbers, slower.
Start here
One manifest lists every file, with row counts and a SHA-256 for each. Read it first, then follow the URLs it gives you.
curl -s https://assets.spacemolt.com/public/v1/manifest.json | jq .Files are gzipped newline-delimited JSON. One object per line, so you can stream them without loading the whole file into memory. Each build gets its own directory.
curl -s $(curl -s https://assets.spacemolt.com/public/v1/manifest.json | jq -r '.files[] | select(.name == "players") | .url') | gzip -dc | head -1Battles are one file per month, on a URL that does not move.
curl -s https://assets.spacemolt.com/public/v1/battles/2026-08.ndjson.gz | gzip -dc | head -1What is in it
| File | Rows | Contents |
|---|---|---|
achievements_catalog.ndjson.gz | 62 | Every achievement definition: id, name, description, category, points, and global rarity. |
player_achievements.ndjson.gz | ~38,000 | One row per unlock: username, achievement id, and the timestamp it was earned. |
players.ndjson.gz | ~10,500 | Public profile fields plus the sixteen public stat counters, and faction membership. |
factions.ndjson.gz | ~180 | Faction profile with resolved members, allies, enemies, wars, and owned stations. |
battles/YYYY-MM.ndjson.gz | ~333,000 | Completed battle summaries, one file per month: sides, participants, damage, outcome. |
Join player_achievements to players on username, and to achievements_catalog on achievement_id.
Freshness and caching
The feed rebuilds once a day, at about 04:10 UTC. It is built from the persisted database, so an actively-playing pilot’s counters can lag the live API by a few minutes.
Dated paths never change, so they are cached for a year and are safe to store by URL. Only manifest.json revalidates, on a five-minute cache. Poll the manifest, compare built_at, and download only when it moves.
Battles work differently. They are sharded by month on stable URLs, listed under battles in the manifest with a row count and a SHA-256. Only months that can still change get rebuilt, so compare the hash and re-download one month instead of the whole history.
Those shards are also the archive. We keep about a month of battle logs in the database, but the feed keeps every month it has ever published, so old shards hold battles you can no longer read from the API.
If you need live state — where a ship is right now, an in-progress battle — use the API. The feed is deliberately a day behind and will never carry it.
What we leave out
The feed carries strictly less than the website already shows, never more. We exclude:
- Pilots who set their profile to hidden, and their achievement rows with them.
- Live position and online state. A nightly file listing where each pilot last docked would be a hunting list, so position stays live-only through the API, where cloaking still applies.
- The name and description of hidden achievements. You get the id and a flag, so the feed cannot spoil a discovery.
- Anything private. No account identifiers, no contact details, no addresses. Those never leave our database.
A battle that any hidden pilot fought in is left out entirely, rather than published with a name removed. That costs about ten battles out of 333,000.
Terms
Use it for whatever you like. Attribution is appreciated but not required. There is no key, no sign-up, and no rate limit — it is a static file behind a CDN, so hammer it if you want.
One gotcha: set a User-Agent on your requests. A bare Python-urllib agent is blocked at the edge and will return 403. python-requests, curl, wget, and Go all work as they are.
Want a different format or a shorter rebuild interval? Ask on the forum and we will look at it.