API V2 Beta Documentation

And I’ve heard the old system before reviews were asynchronous (eg, you had to wait for the server to respond to each review before proceeding) was maddening, which is where you’d get without JS. You could probably use the same backend REST interfaces in a custom client, but they’re not public/documented.

1 Like

This is getting a little off topic. Please keep discussion in regards to API v2.

1 Like

I’m seeing some oddly encoded responses. Try this one, @viet:

curl -X GET -H 'Authorization: Token token=3d24d68d-e356-4ec4-bfb5-06214e78b0c4' 'https://www.wanikani.com/api/v2/subjects?updated_after=2017-10-13T22:15:45.085404Z'

I get:

{"object":"collection","url":"https://www.wanikani.com/api/v2/subjects?updated_after=2017-10-13T22%3A15%3A45.085404Z","pages":{"next_url":null,"previous_url":null,"last":1,"current":1},"total_count":1,"data_updated_at":"2017-10-13T22:15:45.085404Z","data":["{:id=\u003e2945, :object=\u003e\"vocabulary\", :url=\u003e\"https://www.wanikani.com/api/v2/subjects/2945\", :data_updated_at=\u003eFri, 13 Oct 2017 22:15:45 UTC +00:00, :data=\u003e{:level=\u003e7, :created_at=\u003eTue, 27 Mar 2012 18:00:47 UTC +00:00, :slug=\u003e\"未だ\", :document_url=\u003e\"https://www.wanikani.com/vocabulary/%E6%9C%AA%E3%81%A0\", :characters=\u003e\"未だ\", :meanings=\u003e[{\"meaning\"=\u003e\"Not Yet\", \"primary\"=\u003etrue}, {\"meaning\"=\u003e\"Still\", \"primary\"=\u003efalse}], :readings=\u003e[{\"primary\"=\u003etrue, \"reading\"=\u003e\"まだ\"}], :parts_of_speech=\u003e[:adverb], :component_subject_ids=\u003e[656]}}"]}

Note that the first item in the collection is a string encoding of a ruby inspection string. Odd!

Edit: even simpler reproduction case, which I suspect will happen for all api_keys:

curl -X GET -H 'Authorization: Token token=3d24d68d-e356-4ec4-bfb5-06214e78b0c4' 'https://www.wanikani.com/api/v2/subjects

I started seeing the error around 12 hours ago. Thanks!

1 Like

Thanks for the detailed information. I was able to reproduce the encoding issue when using CURL. Our tests and Paw output the response without issue. Very odd. We are going to look into this. Thanks again.

1 Like

@viet, I also noticed this problem earlier today. The problem is not consistent throughout your data. My guess is that it started happening to recent updates (in the past 24 hours approx).

Today I tried to retrieve from your subjects endpoint with the criteria “updated_after=2017-10-13T01:16:22Z”. There were four entries. They were all affected as shown by @hitechbunny. The problem was only in the “data:” part of the content I retrieved. The higher level fields (e.g. data_updated_at, url, object etc) looked fine.

subject_id: 2829, 2945, 6221, 7517

I also noticed similar coding in some of the the review_statistics and assignment content earlier today. They seem to be OK now.

1 Like

We were working on some optimizations for the API on Friday, especially around caching. It looks like there’s some double encoding going on for the nested results. @viet and I will dig into it on Monday.

In the meantime, I rolled back the changes and cleared out the cache, so the results should be happy again. Hit up either Viet or myself if they’re not.

4 Likes

I’d just like to say that it’s awesome that you’re so responsive to issues! :smiley:

2 Likes

It looks like the same problem is still there, but just reduced down to the microsecond level now.

I ran a /subjects query, the first time using “?updated_after=1999-01-01T12:00:00Z”.
As expected, it returned everything.

Next, I extracted the “data_updated_at” timestamp from the response, which is 2017-10-19T17:19:25.618734Z
So, I ran /subjects again, this time with “?updated_after=2017-10-19T17:19:25.618734Z”
And it returned 1 record with that exact timestamp.
If I increment the microsecond by 1, I get zero records.

So, I think either the backend database is retaining sub-microsecond resolution, or the database query is using >= instead of >.

For now, I’m just incrementing the requested cutoff time by 1 microsecond.

2 Likes

Thanks for the info.

The comparison is definitely done without the equality.

The date column in our db shouldn’t be more than microsecond precise, which is why we are now rolling such precision in the filters. Guess we’ll have to dig deeper and see whats up.

2 Likes

Gotta eat my words after some digging.

Some endpoints had inequality filter comparisons and at least one had the equality (subjects). Easy fix. Also an indicator for us to DRY up the code a bit.

4 Likes

I tried the API a bit, but I noticed that it didn’t update summary endpoint (which is the only one I tried) after the first try. I tried changing cache policies, using “If-None-Match” and “If-Modified-Since”. C# and HttpWebRequest.

Is there a way I can force to get the newest information?

1 Like

Basic question to start, but did any of the assignments change between your first request and subsequent requests? If so, how? It’ll help me recreate what you’re seeing.

The code on there looks at the latest updated_at or the time at the beginning of the hour, and busts the cache if the max of those two change — that covers new reviews becoming available or someone doing lessons/reviews/whatever to those assignments. If something changed, and the cache didn’t get busted, I’ll dig into.

1 Like

Assignments? As in what I requested from the endpoint? Not really, I tried a few of different things (Headers, policy changes on httprequest) after I noticed that it’s not getting updated. I got the same information about reviews and upcoming reviews, the time on them stayed the same even though that time had passed hours ago. So for example it said that I would get several new review ID’s in the next hour… after 6 hours the API retrieval information was the same as six hours ago. Nothing had changed.

            string token = <my token>;
            string result = "";
            Uri uri = new Uri("https://www.wanikani.com/api/v2/summary");
            HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(uri);
            httpReq.Headers.Add(HttpRequestHeader.Authorization, token);
                        
            DateTime ifUpdatedSince = DateTime.Now;
            ifUpdatedSince = ifUpdatedSince .AddHours(-2.0);
            httpReq.IfModifiedSince = ifUpdatedSince;
            
            try
            {
                using (HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse())
                using (Stream streamResp = httpResp.GetResponseStream())
                using (StreamReader r = new StreamReader(streamResp))
                    result = r.ReadToEnd();                
            }

Edit:
The problem I talked about was some days ago. But I tried it again now, I compiled the program and got the API info 30 mins or so ago… The hour changed, ran the program again but it was the same as before. Upcoming review info’s time hadn’t changed. Oh, it wasn’t the same as date as the one I tried days ago, so it updated at some point. I don’t think I’ve cleared my cache on my computer or anything like that in the meantime.

1 Like

It’s a caching problem — the key that we’re checking expiry against doesn’t change, and it should expire at the top of the hour. I’m digging into it and will let you know when we’ve got a fix up on the site.

3 Likes

Fix will be live in a couple minutes.

3 Likes

Fix will be live in a couple minutes.

3 Likes

Thank you for the fix. It works correctly now. :slight_smile:

1 Like

The page object size has been reduced from 500 to 250 for now.

2 Likes

Probably a dumb question. But if I wanted to obtain the info about each item in my review list I would have to request /review_subject_ids then for each subject ID I would do /subjects/?subject_ids=1,2,3,4...etc and then from that data dump I could extract the information about each subject?

I just tried that then. I have 64 reviews in my queue, with varying ID’s. When I try to grab the specific subject data for those ID’s it just returns a list of all available subjects starting at ID#1. Am I doing this wrong?

1 Like

@darkhawx,
subject_ids isn’t listed as one of the filters on /subjects. But the documentation does say you can use /subjects/:id. So, for example, /subjects/2136

I’m not sure if you can comma-separate IDs like /subjects/1,2,3, but you could try.

1 Like