The /sites
method is used to enumerate all sites in the network. If your [app] is meant to run against more than a single site (and many are) this method is how you should be discovering new sites in the network.
As there's been some confusion about how this method is meant to be used, I've written this to help make sure you're "doing it right."
/sites
returns the following data for each site:
- Name
- Url
- Logo Url
- Icon Url (158x158; any "web" image format)
- Api Url
- Short Description
- Its State
- Some Minor Style Information
- A List Of Old Urls (under the name aliases)
- Currently no sites return any aliases, this will change in the future
For Stack Overflow the returned object currently looks like this:
{
"name": "Stack Overflow",
"logo_url": "http://sstatic.net/stackoverflow/img/logo.png",
"api_endpoint": "http://api.stackoverflow.com",
"site_url": "http://stackoverflow.com",
"description": "Q&A for professional and enthusiast programmers",
"icon_url": "http://sstatic.net/stackoverflow/img/apple-touch-icon.png",
"state": "normal",
"styling": {
"link_color": "#0077CC",
"tag_foreground_color": "#3E6D8E",
"tag_background_color": "#E0EAF1"
}
}
state
can be one of normal, closed_beta, open_beta, or linked_meta. Normal is a fully functional site, with its own domain and styling. Closed and open betas are provisional sites, which may be shutdown should they fail to achieve critical mass; they differ only in that closed_beta sites only allow participation by users who committed to them on Area 51. A linked_meta site inherits user accounts (including reputation) from a parent site; their parent can be inferred by removing "meta." from its domain name.
There is no ordering (implied or otherwise) of the objects returned by /sites
, your [app] should enforce any rules w.r.t ordering before presenting this data to the user.
All Returned Values Can Change
While rare (occurring once during the lifetimes of most sites), all values in a site
object are fluid. The only constraint is as follows:
If a site has ever legitimately gone under a Url, and that Url is not its current one, it will appear in aliases
For most [app]s this shouldn't be relevant, as if you have a cached copy of a sites data and you find that it has become invalid (the api_endpoint
returning 3xx errors) you can simply re-query /sites
and continue normally.
Maintain Site References Over Time
If you have cached content keyed or otherwise related to an old site context, you can use the values in aliases
to determine which site now corresponds to the old site context. This means you must keep the site_url
around for cached site content, a site's name is not sufficient.
Conceptually, this is basically saying that there is a many to one relationship between the urls (ie. aliases
) a site has used and the data for the site itself.
To help clarify, the following (pseudo-)code will build a Dictionary which can be used to lookup a sites data given its url, even if that url comes from a cache.
// Let sites be a Site[] where Site is a naive impl of the /sites return
var siteLookup = new Dictionary<string, Site>();
foreach(var site in sites)
{
siteLookup[site.site_url] = site;
foreach(var alias in site.aliases)
siteLookup[alias] = site;
}
// siteLookup is now the aforementioned Dictionary
Caveats
By "legitimately gone under" I mean was not the result of an error or misconfiguration and was the primary url (ie. was at some point a site_url
returned as part of /sites
). Some sites have redirects from similar domains, these urls will not appear in aliases
as they are not considered "primary".
These constraints only apply from the time the API was released. While StackOverflow, ServerFault, and others have gone under different urls in the distant past those will not be in aliases
.
When an API endpoint responds with any 3xx error, there is no guarantee that the payload of the response will contain an equivalent API call on the new endpoint.
Common Questions
Why not return a site_key
or similar?
There is currently no concept* of a site_key
in the SO code base. The idea itself is fraught with problems (consider how catastrophic it would be for two sites to get the same "id" while running under different names), but the basic reason is its lack of existence.
Common suggestions for keys are things like (or equivalent to) a database row number or a resource name (like "mso", "so", et. al used to be). Neither of these have been unchanging even over the course of the APIs development, much less over the lifetimes of the sites. Their unsuitability is demonstrated by the facts on the ground in addition to the above concerns about fragility.
How often should I query for new sites?
/sites
can be expected to change no more frequently than once a day, under normal circumstances. If you encounter data that makes it appear that a site has changed, a new site has been added, or an old site has been deleted you should re-query /sites
immediately.
Given that /sites
is so comparatively static, most [app]s should strongly consider caching it if possible.
Is old /sites
data available?
No, and intentionally so (outside of aliases
). The current state of the sites is what should be presented to users; old names, descriptions, etc. have been disregarded for a reason, and an [app] should reflect that.
* Where this concept equates to "a value that will not change, ever, for the site"
/sites
and restart the query from scratch. There will be no pointer to the new domain in the response.