Issuing challenges through the API


When sending the following request:

Headers: { 'Content-Length': '289', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'python-requests/2.8.1', 'Authorization': 'Bearer TOKENHERE', 'Content-Type': 'application/json', 'Connection': 'keep-alive', 'Accept': '*/*' }
Body: { "max_ranking": 15, "challenger_color": "automatic", "min_ranking": 11, "game": { "pause_on_weekends": false, "width": 19, "name": "script-test", "height": 19, "ranked": false, "rules": "japanese", "time_control_parameters": { "total_time": 1200, "time_control": "absolute" }, "handicap": 0 } }
I get the following response:
Headers: { 'Date': 'Sat, 12 Dec 2015 21:11:45 GMT', 'Connection': 'close', 'Content-Language': 'en', 'Transfer-Encoding': 'chunked', 'Vary': 'Accept-Language, Cookie', 'Content-Type': 'text/html', 'Server': 'nginx/1.6.1' }
Body: <h1>Server Error (500)</h1>

Is there something wrong with my request? I did notice that my scope on the auth2/access_token request is read. Does that mean I need to somehow get write permission for my app token?

+1 I think I am having the same problem. @apiarian: did you ever get this resolved?

Yup, just got the same error.

I think there are two problems here:

  1. You must specify "time_control": "absolute" (again) alongside your "time_control_parameters", inside "game".
  2. You must specify "disable_analysis": false inside "game".

So, making these changes to your example body:

"max_ranking": 15,
"challenger_color": "automatic",
"min_ranking": 11,
"disable_analysis": false, // ***changed***
"pause_on_weekends": false,
"width": 19,
"name": "script-test",
"height": 19,
"ranked": false,
"rules": "japanese",
"time_control": "absolute", // ***changed***
"total_time": 1200,
"time_control": "absolute"
"handicap": 0
1 Like

Yup, those seemed to be the issues indeed. Here’s a functional script in case somebody wants to use it as a base.e.

1 Like

It would be nice if these things were documented. Or if the API would return some sort of helpful error, like “missing parameters: [missing-parameter-list]”.

Agreed. But I also appreciate how much work this might be for the developers, and that it would only directly benefit a small fraction of users. :smile:

For now, it seems like the best documentation is the official client itself. Using Chrome’s network panel you can see the API calls it’s making. This, plus some experimentation, is how I found the problems with your body.

1 Like

Thanks for the script! I’m borrowing most of it to use in my webcam+goban setup. How should I give you credit? Is a link to your github okay in the code?

Sure thing. I’ve updated the gist to include a license. Basically you can do whatever you want with it.

What is this webcam+goban of yours, @dustyd?

Great, thanks! It’s still not finished so I’m not sharing it yet, but its close to being done. I’ll come back and post once its up and running. It will be all open source too!

@tomjack: could you elaborate on using chrome’s network panel? I tried playing moves in a game with the network panel open and didn’t get any activity. I was able to see the data being sent using the console (auth,game_id, player_id, move) but I couldn’t see the url it was sending it to (which I think is what is causing my current problems with submitting moves).


Playing moves happens with the real-time API.

Snooping on the real-time API is a bit tricky. What I do is:

  1. Open the network panel, refresh.
  2. In the filter bar (“All, XHR, CSS, …”), select “WS”, and type “ggs” into the “Filter…” text input. This should leave only one request visible, a pending “101 Switching Protocols” websocket request. If you see nothing, either you need to refresh or something is different for you.
  3. Click on that request, then go to “Frames”. Now you can watch everything go by. I have found that unless I filter as described, so that there is only one request visible, Chrome won’t stay put here.

Thanks so much. Did not realize the real-time API was a thing. Gonna check that out now!


I was able to get it mostly working! The only thing I have to do right now is manually copy the authentication key from messages in the Chrome Network Panel. I don’t know how to get the auth key for the real-time api directly. It does not seem to be the same access token I’m getting from using the REST api.

For example I do the following to get my access_token via REST:

d = {
         'client_id': client_id,
         'client_secret': client_secret,
         'grant_type': 'password',
         'username': username,
         'password': password,

    r ='',
               headers = {
                          'Content-Type': 'application/x-www-form-urlencoded',
               data = d,    
               allow_redirects = False,

    print(r.request.method, r.request.url, r.request.body)

    oauth2_json = r.json()
    access_token = oauth2_json['access_token']
    refresh_token = oauth2_json['refresh_token']

But then when I try to do use the real-time api to do submit moves, it doesn’t go through: Note: I’m using the python socketio-client library.

with SocketIO('') as socketIO:
        print("socket is connected: "+str(socket.connected))
                    {'game_id': gameid, 'player_id': playerid, 'chat': 1, 'game_type': "game", 'auth':access_token},
        # try submitting a move

That same code works whenever I copy and paste the auth code string Chrome’s network panel shows me for sending moves. I was able to send a move and play the game (which was so awesome to get it working). Do you know how to get the auth key for the real-time connection? My only clue so far is that it might have to do with using a GET request for switch protocols (it says this under headers instead of frames in the network panel). But OGS’s rest api doesn’t show this anywhere in their online documentation.

I’m glad you asked this – I was also confused about this! Like you, I was thinking you were supposed to just use the REST access token. The docs suggest that something else is going on here, but they don’t explain it clearly.

It looks to me (based on snooping) like you need to hit /api/v1/games/<id> via REST. The result contains “auth” and “game_chat_auth” fields. You’ll need to use the “auth” field there for making moves, I think.

I got it to work, thanks for the help! The auth and chat auth keys are in the game details. this is the REST API call in the docs:

I am trying to get this to work, and it seems to be correct, but my open challenges get deleted after several seconds every time. I get no notifications or error messages, just a seek graph deleted event.

I can play a game just fine if the other player accepts quickly, and if I make an open challenge with the same user, same parameters through the web interface it does not get deleted. Any ideas?