rcemaps API
Map images for any Rust Console Edition seed, over plain HTTP. No signup, no OAuth — point an <img> or a Discord embed at a URL and you get a PNG.
Quick start
https://rcemaps.com/api/v1/map.png?seed=1234567&size=4500&clean=1That is the entire integration for most bots. In discord.js:
const seed = 1234567, size = 4500;
const url = `https://rcemaps.com/api/v1/map.png?seed=${seed}&size=${size}&clean=1`;
await interaction.reply({ embeds: [{
title: `Rust Console — seed ${seed}`,
url: `https://rcemaps.com/?seed=${seed}&size=${size}`,
image: { url },
}] });Discord fetches the image itself and caches it, so a popular map costs you one request no matter how many people see the message.
Authentication
Optional. Without a key you are metered by IP at the anonymous rate, which is enough for a small bot. If you need more, ask for a free key and send it as an X-API-Key header. A ?key= query parameter also works where headers are awkward, but prefer the header — query strings end up in server logs and browser history.
curl -H "X-API-Key: rce_…" \
"https://rcemaps.com/api/v1/limits"Rate limits
Two separate budgets, because the two kinds of request cost very different things. Asking for a map that has been rendered before is nearly free; asking for one that has not means generating it. Only the second draws from the “new maps” budget — re-posting maps you have already requested is effectively unmetered.
| Tier | Requests | New maps |
|---|---|---|
| anon | 60/min (burst 30) | 5/min (burst 3) |
| key | 600/min (burst 120) | 60/min (burst 20) |
Every response carries X-RateLimit-Limit and X-RateLimit-Remaining; a 429 also carries Retry-After. Check X-Cache on an image response to see whether you paid for a generation: HIT means you did not.
If you are backfilling a lot of seeds, request them slowly rather than in a burst, and cache the PNGs at your end. Ask for a key and say what you are building — that is easier for both of us than being rate-limited.
Endpoints
The map image, 512×512 PNG. Takes the parameters below.
Metadata for the same map: the image URL, a link to the interactive version, land_pct when known, whether it is already rendered, and a projection block giving the world→pixel transform for overlays. Validates your parameters without generating anything.
Which seeds the official Console servers are currently running, and how many servers are on each. Use it to show “your server’s map” without asking anyone to type a seed.
A rolling feed of freshly generated maps — the same one the site’s Discover tab shows. Every entry carries a ready-to-embed image URL, so a bot can post a new map on a timer without generating anything itself. Newest first. Filter with size, page with limit, and poll cheaply with after (pass the newest value from your last reply and you get only what has appeared since).
The ground height (world Y) at any point of a map, with a safe spawn height above it — for spawn commands, route planners, anything that needs to know where the ground is. One point with x and z, or up to 50 on one map with points=x,z;x,z. See Ground height below.
Your tier and how much of each budget is left.
Parameters
| Name | Default | Accepts | Notes |
|---|---|---|---|
seed | required | 0 – 2147483647 | The world seed. |
size | 4500 | 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500 | World size in metres. |
style | ingame | ingame, height, biome, topo | Map view: the in-game look, a heightmap, biome colours, or topography. |
quality | fast | fast, quality | quality resolves finer terrain detail and is slower to produce. |
clean | 0 | 0 or 1 | 1 drops the grid and the info bar, leaving just the map — best for a Discord embed. |
The Discover feed
Poll it for something new to post. The reply gives you maps (newest first), count, total matching your filter, and newest — feed that back as after next time so you only ever fetch what you have not seen. Each map’s img is the full 512 px picture; thumb is a small copy (384 px, about a tenth of the size) for a grid or a list.
https://rcemaps.com/api/v1/discover?size=4500&limit=5{
"maps": [
{ "seed": 1288469066, "size": 4500,
"land": 42.7,
"img": "https://rcemaps.com/discover/img/4ac944e5.png",
"thumb": "https://rcemaps.com/discover/thumb/1/4ac944e5.webp",
"url": "https://rcemaps.com/?seed=1288469066&size=4500",
"ts": 1788072848 }
],
"count": 5, "total": 118, "newest": 1788072848
}Drawing on top of the map
If you are plotting anything — player positions, monuments, a heatmap, your own markers — you need to know where a world coordinate lands in the image. map.json tells you, in a projection block, so you never have to measure it yourself or re-check it when something changes.
Two things catch people out, so they are stated outright in the reply: the map fills the whole image (there is no border to subtract), and the z axis is inverted — north is +z in the world but the top of the image, where y is 0.
{
"projection": {
"image": { "width": 512, "height": 512 },
"world": { "size": 4500, "min_x": -2250, "max_x": 2250, "min_z": -2250, "max_z": 2250 },
"metres_per_pixel": 8.7890625,
"origin_px": { "x": 256, "y": 256 }
}
}Which is two lines in any language:
px = (x + size / 2) / size * width
py = height - (z + size / 2) / size * heightand back the other way, for a click on the image:
x = px / width * size - size / 2
z = size / 2 - py / height * sizeThese are the same numbers this site uses to draw its own monument markers, so anything you place with them lines up with anything we draw.
Ground height
/api/v1/ground gives the ground’s world Y at a point, so you can build a spawn or teleport command without going in-game to find it. Pass the map exactly as you would to map.png — seed, size and any terrain commands — plus x and z, or points=x,z;x,z for up to 50 at once.
https://rcemaps.com/api/v1/ground?seed=11239&size=4500&points=1125,1125;0,0Each point comes back with ground_y, a spawn_y a safe margin above it (5 m unless you pass margin=2|5|10|20), underwater and water_depth, and its grid square. In the sea, spawn_y is measured up from the water surface.
How close is it? On unmodified 4500 maps the typical error is about half a metre. The margin is there because monuments, roads, rivers and canyons reshape the ground after the map is made, and this can’t see them. Each reply lists, per margin, how much of the map that margin still isn’t enough for (margins) — they are measured, not guessed. Reading high is harmless, the thing just drops; reading low would bury it, so the margin is one-sided on purpose.
Lookups read the map’s height data, which the server keeps in memory only for maps generated recently. When it is there the answer is instant and costs nothing extra. When it isn’t, the map is generated first, which costs one new-map token — the same as an uncached map.png. Fetching map.png first doesn’t avoid it: a cached picture keeps no heights. So ask for all your points on a map in one call — up to 50 cost at most one token. Out of tokens, you get a 429 with Retry-After: wait that long and try again.
Terrain commands
Every terrain.* and env.oceanlevel command the game takes works here too, so you can render the map a server is actually running rather than the stock one for that seed. Drop the terrain. prefix and pass the command as a query parameter — terrain.elevation_hill 0.8 becomes elevation_hill=0.8, and env.oceanlevel 5 becomes oceanlevel=5.
So a server booted with:
server.seed 1234567
server.worldsize 4500
--terrain.elevation_hill 0.8
--terrain.center_falloff 1200
env.oceanlevel 5is this request:
https://rcemaps.com/api/v1/map.png?seed=1234567&size=4500&clean=1
&elevation_hill=0.8¢er_falloff=1200&oceanlevel=5The ten noise_* commands take Rust's own syntax, url-encoded because of the = and ,:
&noise_base_land=oct%3D6%2Cfreq%3D1%2Camp%3D4%2Coffset%3D-0.4Most HTTP clients encode that for you — in JavaScript, build it with new URLSearchParams({ seed, size, noise_base_land: 'oct=6,freq=1,amp=4,offset=-0.4' }).
Every distinct set of commands is a different map, so the first request for one has to render and comes out of your new-maps budget. Repeats are cached like any other map. If your bot lets people tweak sliders live, debounce it.
Command names are validated: an unknown parameter or an unparseable value is a 400 naming the offender, rather than a stock map handed back as though nothing were wrong. The full list of commands and what each one does is in the command guide.
Errors
Errors are JSON: {"error": "bad_size", "message": "…"}. Switch on error, show message.
| Status | error | What to do |
|---|---|---|
400 | missing_seed, bad_seed, bad_size, bad_style, bad_quality, bad_terrain, unknown_parameter | Fix the request; it will never succeed as sent. unknown_parameter also lists the offending names in an unknown array. |
401 | invalid_key | The key was not recognised. Omit it to fall back to the anonymous tier. |
429 | rate_limited, generate_rate_limited | Wait retry_after seconds. Honour the Retry-After header. |
503 | busy, unavailable, maintenance | Temporary. Retry with backoff. |
Using the images
Free to use, including in bots on servers you monetise. One ask: leave the rcemaps.com mark on the image.
Maps are deterministic: the same seed and size always produce the same image, so they are safe to cache forever at your end.
This API is versioned. /api/v1 will not change under you in a breaking way; anything incompatible arrives as /api/v2.