API

Sro.gg publishes its server directory as JSON so you do not have to crawl the site. Everything here is public, needs no key, and may be reused under the terms on the data methodology page: attribute sro.gg and link to the page you took the data from.

All endpoints share one limit of 10 requests per minute per IP address. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; going over returns 429 with a Retry-After header. The limit is shared, so spreading requests across endpoints does not raise it.

Identifying yourself

Send a User-Agent header that says who you are and why you are calling. This matters most for AI agents and scripts: without it you arrive as an anonymous request, and we cannot tell a research tool from a scraper.

Name/version (+contact; purpose=what-you-use-it-for)
AcmeBot/1.0 (+https://acme.com/bot; purpose=price-comparison)
ResearchAgent/2.1 (+mailto:you@example.com; purpose=academic research)

The contact is a URL or a mailto: address, prefixed with +. The purpose is a short phrase describing the use, not a sentence. Both parts are required — a name on its own is not a declaration and will still be treated as unidentified.

Clients we cannot identify — curl, bare HTTP libraries, anything with no recognisable agent — receive a notice field at the top of every response asking for this. Declare yourself and the notice disappears. Well-known crawlers such as Googlebot, GPTBot and ChatGPT-User are recognised automatically and never see it, though they may still send a purpose.

Identifying yourself costs nothing and does not change your rate limit today. It means that when we look at who uses the API, you appear as yourself rather than as an anonymous IP address — and if we ever need to contact you about your usage, or raise a limit for you, we can.

Unidentified traffic is the traffic we can least account for. A single IP address sending a sustained volume of anonymous curl-style requests may be throttled or blocked, because from our side it is indistinguishable from scraping. Declared clients are not treated this way: we can see what they are for, and we would reach out before acting. If you are automating anything against this API, sending the header is the cheapest way to stay on the right side of that line.

The server directory

GET https://sro.gg/api/public/servers

Returns every listed server with its level cap, race configuration, player limits, launch dates and last known player count. This is the endpoint to use for questions about population, features or availability.

Each entry carries playersOnline together with playersOnlineAt, the moment that reading was taken. Always publish the timestamp alongside the number. A null count means no counter could be read, not zero players.

Filters

  • status — lifecycle states, comma separated. Accepts live, beta, upcoming and inactive. Example: ?status=live,beta

  • cap — one level cap. Example: ?cap=110

  • openedAfter — servers that opened on or after this date. Example: ?openedAfter=2026-07-15

  • openedBefore — servers that opened on or before this date

  • sortplayersOnline, opensAt or likes

  • localeen or tr. Picks the language of name and description, and points url at that locale. urls always carries every locale regardless.

Closed servers are excluded unless you ask for them with status=inactive or includeInactive=true. They stay listed for reference and are never places to play.

Combining filters covers the site's own listing pages: ?status=upcoming&sort=opensAt is the upcoming calendar, and ?openedAfter= with a date a month back is the new-servers page.

Invalid parameters

A known parameter carrying a value outside its allowed set returns 400 — it is never silently ignored, and you never receive an unfiltered list by mistake:

{
  "error": {
    "code": "invalid_query_parameter",
    "parameter": "status",
    "received": "invalid",
    "allowed": "live, beta, upcoming, inactive (comma separated)",
    "documentation": "https://sro.gg/en/page/api"
  }
}

A parameter we do not recognise returns 400 as well, so a typo like staus=live fails loudly instead of quietly returning the unfiltered directory:

{
  "error": {
    "code": "unknown_query_parameter",
    "parameter": "staus",
    "allowed": ["status", "cap", "openedAfter", "openedBefore", "sort", "includeInactive", "locale"],
    "documentation": "https://sro.gg/en/page/api"
  }
}

Nothing outside that list is accepted — tracking parameters such as utm_source or ref are rejected too. If you get a 200, your filters were applied as written.

GET https://sro.gg/api/public/trending

Servers ranked by how many times their sro.gg page was viewed over the last seven days, with growthPercent comparing that against the seven days before.

Hype

GET https://sro.gg/api/public/hype

Servers ranked by how many people are reading their sro.gg page right now, measured over a 30 minute window.

Both endpoints measure traffic on sro.gg, not players in the game. They answer "which servers are people looking at", never "which servers are the biggest". A server can trend because it just launched, because it was mentioned somewhere, or because it closed.

Do not republish these figures as player counts. For population use the directory endpoint, where every number carries the timestamp of its reading.

Mirrors outside /api/

Some fetchers and agent tools refuse to open any path beginning with /api/, regardless of what robots.txt allows. Every endpoint above is therefore also served from a plain .json path:

GET https://sro.gg/data/servers.json
GET https://sro.gg/data/trending.json
GET https://sro.gg/data/hype.json

These are the same handlers, so the payload, the filters, the rate limit and the cache headers are identical — https://sro.gg/data/servers.json?status=live&cap=110 behaves exactly like the /api/public/servers equivalent. Use whichever your client can open; there is no reason to prefer one over the other otherwise.

Caching

The directory and trending are cached for 15 minutes, hype for 60 seconds. The whole directory arrives in a single request and changes slowly, so caching one response beats polling. If you need a higher limit, get in touch before working around this one.

Markdown

Every page under /page/ is also served as raw markdown by appending .md to its URL — for example /page/api.md. That is the source these pages are rendered from, without navigation or markup around it.

SRO.GG

Discord Community

Chat with players

WTS/WTB Group

Buy & sell listings

Join the Community

Connect with thousands of players

You can only use your Google account for membership. If you don't have a Google account, create one first.

Recent Comments

Latest comments from the community

bumerang·Zeron Online

Efsane <3 nice server <3 IGN= Kraft

1 hr. ago
EldraN·Zeron Online

nice server IGN: EldraN

1 day ago

Sonunda 120 cap. Asıl zevkli oyun simdi baslıyor. Bekliyoruzz

1 day ago
Alastor·Zeron Online

Zeron on Fİre İGN:Dante

1 day ago