Huge omega thanks to @wasif for emailing me this challenge idea in its basic form

Everyone knows that questions on StackExchange require tags - labels that allow posts to be grouped together by category. However, most of the time, I barely know which tags exist, because there's just so many of them. Henceforth, today's task is to tell me every single tag that exists on the Code Golf and Coding Challenges Stack Exchange.

The Challenge

Write a program or function that prints/returns a list of all available tags on https://codegolf.stackexchange.com As tags can be created/deleted at any time, simply hard-coding a list of tags is not a valid solution - the list must be correct at run-time regardless of when the program/function is executed. The tags avaliable can be seen here


  • As this is an challenge, internet connections are allowed. However, web requests can only be made to codegolf.stackexchange.com and api.stackexchange.com domains.
  • Output can be given in any convenient and reasonable format.
  • The tags can be in any order, so long as all current tags are returned.
  • The exact name of the tags must be used (e.g. code-golf is valid, code GOLF is not valid.)
  • And as usual, standard loopholes apply, shortest code wins

Example Program

import urllib.request
import regex

pobj = regex.compile('rel="tag">(.*)</a>')
page_number = 2
req = urllib.request.urlopen(f"https://codegolf.stackexchange.com/tags?page=1&tab=name")
data = req.read().decode('utf-8')
tags = []
while data.count("tag") != 43:
    tags += pobj.findall(data)
    req = urllib.request.urlopen(f"https://codegolf.stackexchange.com/tags?page={page_number}&tab=name")
    data = req.read().decode('utf-8')
    page_number += 1
  • \$\begingroup\$ Can we assume amount of tags stable enough? so we can hardcode page amount \$\endgroup\$ – l4m2 Apr 20 at 3:00
  • \$\begingroup\$ @l4m2 the program has to output every tag at time of execution, so hard coding probably isn't a valid option \$\endgroup\$ – lyxal Apr 20 at 3:03
  • \$\begingroup\$ But it's unlikely that there's at some time lot more tags or lot less tags \$\endgroup\$ – l4m2 Apr 20 at 3:05
  • \$\begingroup\$ I'm still going to say no in this case. Answers should work regardless of tag count \$\endgroup\$ – lyxal Apr 20 at 3:10
  • 1
    \$\begingroup\$ I must be getting old - what is the significance of omega in Huge omega thanks? \$\endgroup\$ – Digital Trauma Apr 20 at 18:06

05AB1E, 60 57 bytes


Beats all other answers.

[N>’...’.wD2è'eQ#“e":"“¡¦ε'"¡н]\)˜  # trimmed program
[               #                   # while...
            è                       # character in...
        .wD                         # data of response from URL...
                                    # (implicit) "http://" concatenated with...
   ’...’                            # "api.stackexchange.com/tags?site=codegolf&page=ÿ"...
                                    # (implicit) with ÿ replaced by...
 N                                  # current index in loop...
  >                                 # plus 1...
            è                       # at index...
           2                        # literal...
                #                   # is not...
               Q                    # equal to...
             'e                     # literal...
        .w                          # push data of response from URL...
                                    # (implicit) "http://" concatenated with...
   ’...’                            # "api.stackexchange.com/tags?site=codegolf&page=ÿ"...
                                    # (implicit) with ÿ replaced by...
 N                                  # current index in loop...
  >                                 # plus 1...
                      ¡             # split by...
                “e":"“              # literal...
                       ¦            # excluding the first...
                        ε           # with each element replaced by...
                            н       # first element of...
                                    # (implicit) current element in map...
                           ¡        # split by...
                         '"         # literal
                             ]      # exit map
                             ]      # exit infinite loop
                              \     # delete top element of stack
                               )    # push stack...
                                ˜   # flattened
                                    # implicit output
  • 3
    \$\begingroup\$ I was about to suggest using dictionary compression and then realised I was being a stupid idiot because I was looking at the unpacked strings in the explanation. Very well done! \$\endgroup\$ – lyxal Apr 20 at 7:14
  • \$\begingroup\$ @Lyxal Thanks! I also just checked the source code and turns out that 05AB1E does in fact implicitly add http:// if it's not present, saving me three bytes. :) \$\endgroup\$ – Makonede Apr 21 at 20:01

Python 3 + requests, 143 bytes

from requests import*
while[print(x["name"])for x in get(f"http://api.stackexchange.com/tags?page={p}&site=codegolf").json()["items"]]:p+=1

-19 bytes thanks to Jonathan Allan
-5 bytes thanks to dingledooper

  • 3
    \$\begingroup\$ Would while a:a=[print(x["name"])for...];p+=1 work? ...Edit: or even while[print(x["name"])for...]:p+=1? \$\endgroup\$ – Jonathan Allan Apr 20 at 1:20
  • 1
    \$\begingroup\$ @JonathanAllan Yep, looks like it does! Thanks! \$\endgroup\$ – hyper-neutrino Apr 20 at 1:22
  • \$\begingroup\$ -2 by using "https://api.stackexchange.com/2.2/tags?site=codegolf&page="+p instead of f"https://api.stackexchange.com/2.2/tags?page={p}&site=codegolf". \$\endgroup\$ – Makonede Apr 20 at 1:38
  • \$\begingroup\$ @Makonede you can't add strings and integers in python \$\endgroup\$ – hyper-neutrino Apr 20 at 1:42
  • \$\begingroup\$ @hyper-neutrino I knew that, just forgot that p was an int \$\endgroup\$ – Makonede Apr 20 at 1:46

JavaScript (Firefox chrome), 135 bytes

f=async(i=1)=>(await((await fetch('http://codegolf.stackexchange.com/tags?page='+i)).text())).match(/[\w-]+(?=&#3)/g).map(alert)|f(i+1)
  1. Open Browser Console of Firefox; You may however open console on this page instead;
  2. Paste codes there;
  3. Invoke it by running f();
  4. Click to close many many alert's

Source codes for tags page contains line

<a href="/questions/tagged/code-golf" class="post-tag" title="show questions tagged &#39;code-golf&#39;" rel="tag">code-golf</a>

We match the text code-golf between &#39; by /[\w-]+(?=&#3)/g.

The recursion terminate when ith page contains no tags. While the match result is null, and .map on null cause an error.

  • 1
    \$\begingroup\$ Would that work on Run Snippet? \$\endgroup\$ – l4m2 Apr 20 at 9:30
  • \$\begingroup\$ @l4m2 As long as you have permission to access that domain. Either by executing on same origin or as chrome code. \$\endgroup\$ – tsh Apr 20 at 10:28
  • \$\begingroup\$ I mean if so you'd make a run in your post? \$\endgroup\$ – l4m2 Apr 20 at 10:30
  • \$\begingroup\$ @l4m2 The code snippets in SE sites run under a different domain as I know \$\endgroup\$ – tsh Apr 20 at 10:33
  • \$\begingroup\$ f=async i=>(await((await fetch('http://codegolf.stackexchange.com/tags?page='+-~i)).text())).match(/[\w-]+(?=&#3)/g).map(alert)|f(-~i)? \$\endgroup\$ – l4m2 Apr 20 at 23:24

JavaScript, 176 bytes

async _=>{t=[];i=1;do t.push(...(j=await (await fetch("http://api.stackexchange.com/2.2/tags?site=codegolf&page="+i++)).json()).items);while(j.has_more)return t.map(d=>d.name)}

Must be run on api.stackexchange.com subdomain; I use /docs for testing.

  • \$\begingroup\$ If you're going to run it on the api.stackexchange.com domain, why don't you use a relative path? \$\endgroup\$ – Neil Apr 20 at 7:53
  • \$\begingroup\$ @Neil Something like this? storing info in URL bar should be disallowed \$\endgroup\$ – l4m2 Apr 20 at 9:33
  • 1
    \$\begingroup\$ @l4m2 Program already only works on the api.stackexchange.com domain, so I don't see the problem here. \$\endgroup\$ – Neil Apr 20 at 10:21
  • \$\begingroup\$ @Neil It also runs on, for example, api.stackexchange.com/docs. Either way I think it'd be kind of cheaty to use a relative path anyway. \$\endgroup\$ – Redwolf Programs Apr 20 at 12:32
  • \$\begingroup\$ Well, it only needs to be relative from http://api.stackexchange.com (because you don't know which page you're on) but that still saves 28 bytes... \$\endgroup\$ – Neil Apr 20 at 15:28

Bash + wget + jq, 86

Assumes there are no more than 99 pages of results (currently 10 pages).

wget -qO- api.stackexchange.com/tags?site=codegolf\&page={1..99}|zcat|jq .items[].name

Testing this blew through my daily API requests limit pretty quick.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.