The Stack Exchange API is based on HTTP and URLs, just like the web page you're browsing now. Except instead of HTML, the responses are all in JSON.

Let's say we wanted to call the /info method:

https://api.stackexchange.com/2.2/info?site=stackoverflow&key=app key

  • 2.2 - the current api version
  • info - the method
  • site=site name - the site to query
  • key=app key - a parameter to pass to the method

The response:

    "items": [
            "api_revision": "2014.1.3.9409",
            "total_questions": 6381965,
            "total_unanswered": 1490184,
            "total_accepted": 3767695,
            "total_answers": 11393820,
            "questions_per_minute": 2.24,
            "answers_per_minute": 3.99,
            "total_comments": 29151387,
            "total_votes": 41269191,
            "total_badges": 8166497,
            "badges_per_minute": 2.86,
            "total_users": 2684447,
            "new_active_users": 23
    "quota_remaining": 299,
    "quota_max": 300,
    "has_more": false

(For a full list of possible API methods, refer to the documentation.)

Do I need an API key?

A single IP address can only make a limited number of requests per day to the API. This limit is determined at by the presence of an API key. Should an IP address be using more than one key, the highest request limit will be used.

API daily limits:

  • Key: 10,000
  • No Key: 300

The No Key limit is meant to facilitate experimentation, not for deployed apps.

Requests with invalid or revoked keys are not stepped down to the No Key limit; they just aren't completed.

For further discussion of keys, refer to How API Keys Work.

Register for an API Key

How do I announce my application, library, wrapper, or userscript?

Create a question here and tag it , , or .

Please refer to How to list your application/library/wrapper/script here for suggested formatting.

  • So if I called and evaled 'stats' in JS I could say stats.statistics.0.total_users. That seems extremely odd compared to just stats.total_users. Would anything ever exist at stats.statistics.1 or 2 or 3? – Rob Van Dam May 25 '10 at 2:08
  • 1
    @Rob Van Dam - currently, no. – Kevin Montrose May 25 '10 at 2:19
  • Please correct me if I am wrong, the limit of 10000 is per IP per API Key, right? – Abhinav Sarkar Sep 14 '10 at 8:19
  • @abhin4v - the daily limit for an IP is the maximum of the limits of keys it is using. With no keys, an IP can make 300 requests. With 1 [app] using a key, 10,000 requests. With N [app], each with a key, still 10,000 requests. Keys are mostly for usage tracking. – Kevin Montrose Sep 14 '10 at 19:08
  • 1
    @Rob Identifiers cannot start with numbers in JS, so it's stats.statistics[0].total_users. But you could do var stats = JSON.parse( jQuery.getJSON('http://api.stackoverflow.com/1.0/stats') ); stats = stats.statistics; so it becomes stats[0].total_users. And eval is evil, it's better to use a JSON parser or the native JSON.parse – if supported. – nyuszika7h Feb 26 '11 at 8:51

Protip: when working with any API that returns JSON, install the JSONView Firefox Extension.

By default, Firefox wants to download the application/json content type. This is not very helpful. JSONView changes the behavior so that you view the JSON in the browser, and additionally get syntax hi-lighting and expand/collapse.

image of JSONView

  • but if you need to process the application/json response in programme, how could you do? – jianpx Dec 16 '10 at 5:31
  • @jianpx You need to send an Ajax request. If you want a simple solution, use a library, e.g. jQuery. var stats = jQuery.getJSON('http://api.stackoverflow.com/1.0/stats'); – nyuszika7h Feb 26 '11 at 8:53
  • @Nyuszika7H thanks for your advice. But in fact, I mean to handle response in server side, not client side. I use python to handle it finally. If you are interested in , I appreciate you to see my article – jianpx Apr 27 '11 at 5:13
  • What about for poor people stuck on IE8? – Adam Baxter Jun 8 '11 at 22:27
  • Firefox supports this by default in later versions. – Zoe May 26 at 14:43

A very low friction introduction to the API can be had with SOAPI-EXPLORE.

It is always in sync with the current API and provides a documented interface for querying each route.

It is a single file JavaScript application and requires no installation and may be right-click/saved or view source/saved and run locally if desired.


Another very useful tool when working with APIs is the Chrome app "Postman - REST Client". You can even make POST requests, save the requests you make and organize them into collections. Check it out here!



Below is python code to get minimal info results. See bottom on how to run.

import requests

BASEURL = "https://api.stackexchange.com/2.2/info"

params = {
  "site" : "stackoverflow"

r = requests.get(BASEURL, params=params)

print r.json()

Expected output is like:

{u'has_more': False,
 u'items': [{u'answers_per_minute': 4.68,
   u'api_revision': u'2017.1.3.24329',
   u'badges_per_minute': 4.74,
   u'new_active_users': 14,
   u'questions_per_minute': 2.95,
   u'total_accepted': 7109267,
   u'total_answers': 20764568,
   u'total_badges': 21064205,
   u'total_comments': 64348720,
   u'total_questions': 13084294,
   u'total_unanswered': 3663230,
   u'total_users': 6546678,
   u'total_votes': 93817071}],
 u'quota_max': 300,
 u'quota_remaining': 299}

You can paste the code into a jupyter notebook cell and run, or put the code into a file stack-api.py and run from terminal or command line with python stack-api.py.

  • I couldn't find any examples to decode the Gzip results in python. – Adam Smith-MSFT Jan 22 at 23:55

Chrome users, check out the Chrome extension JSONView for Chrome. It's an unofficial port of JSONView for Firefox.



Here is a bare-bones javascript, and you can run it from the console of decent modern browsers. It returns the 5 most recently active economics questions, tagged inflation:

fetch (
.then (function (response) {
    if (response.ok) { return response.json(); }
} )
.then (rJsn => console.log (rJsn) );

It returns rJsn as an object like:

{ items: Array[5], has_more: true, quota_max: 300, quota_remaining: 288 }

where rJsn.items is the payload and is like:

        "tags": ["inflation"],
        "owner": { "display_name": "Bob Umadbro" },
        "view_count": 408,
        "answer_count": 3,
        "score": 6,
        "last_activity_date": 1488986618,
        "creation_date": 1449974376,
        "question_id": 9767,
        "title": "Inflation without Increase in Money Supply?",
    }, {
        "tags": ["inflation", "growth", "money-supply"],
        "owner": { "display_name": "gabyarg25" },
        "view_count": 91,
        "answer_count": 1,
        "score": 4,
        "last_activity_date": 1488804578,
        "creation_date": 1483498408,
        "question_id": 14897,
        "title": "What happens if money supply grows more slowly than inflation?",

A more robust starter example:

fetch (
.then (function (response) {
    if (response.ok) {
        return response.json();
    throw new Error (`API problem: Error ${response.status}, ${response.statusText}`);
} )
.then (function (rJsn) {
    if (rJsn.backoff  ||  rJsn.error_id) {
        throw new Error (`From API: Backoff ${rJsn.backoff}, Error: ${rJsn.error_id}, ${rJsn.error_message}, ${rJsn.error_name}`);
    console.log (`Quota remaining: ${rJsn.quota_remaining}; Items found: ${rJsn.items.length}`);

    let zQuestions = rJsn.items;
    console.log ("\nQuestion Titles\n---------------");
    for (let qst of zQuestions) {
        console.log (qst.title);
} );


  1. Always check for error codes and responses!
  2. Always check for the backoff value! If present you do not need to error-out though. Your code can wait the indicated interval and try again.
  3. Monitor quota_remaining. When it gets to 0, you are done for the day.
  4. API key not shown. Just add &key=YOUR_API_KEY to the fetch URL.
  5. Use a filter every time.
  6. For lots of results, monitor has_more and keep fetching the next page as necessary.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .