NAV Navbar

WaniKani API v2 Revision 20170710

shell javascript

Introduction

Welcome to "WaniKani: The API"! You can use our API to access progress data for a user's account and a ton general reference data for the subjects within WaniKani.

This version is built around a RESTful structure, with consistent, resource-oriented URLs. We support that structure with standard HTTP features: HTTP verbs for all our endpoints to indicate different actions, HTTP authentication headers, and HTTP response codes to indicate both success and various errors. We've turned on cross-origin resource sharing to allow for secure client-side access. We respond to all requests with JSON, making it easy to parse those responses into native objects in a variety of languages. These should open up the API to any client that supports these features and data structures.

We've got information on general usage, like authentication and error codes, in Getting Started. We make a few suggestions on how to optimize your usage of the API in Best Practices and clarify a few obscure topics under Additional Information. Finally, details for all of the available resources and endpoints are under Resources.

Feel free to reach out via email or through the community if you have any questions, comments, or requests about the API.

Getting Started

Authentication

To authorize, use this code:

curl "https://api.wanikani.com/v2/<api_endpoint_here>" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = '<api_endpoint_here>';
var requestHeaders =
  new Headers({
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Make sure to replace <api_token_here> with the API key.

WaniKani uses your secret API token to authenticate requests to the API. You can obtain and manage your v2 token in Settings / Account on WaniKani. The token has to be included with every request, and should be delivered in a HTTP header that looks like:

Authorization: Bearer <api_token_here>

Also note that all requests must be made over HTTPS. Any requests made over HTTP or without authentication headers will fail.

Response Structure

We return JSON from all the API endpoints, even when an error occurs.

There are two main structures we return: resources and collections. Singular resource endpoints deliver information about a single entity, such as an assignment or subject. Collections contain summary data about a bunch of resources, and also include each of the resources.

There's a third type of structure that's less common: a report. Reports summarize disparate or novel information into a single place, and don't follow the same structure as collections.

Resources follow the pattern:

{
  "id": <integer>,
  "object": <string>,
  "url": <string>,
  "data_updated_at": <date>,
  "data": <object>
}

And collections look like:

{
  "object": <string>,
  "url": <string>,
  "pages": {
    "next_url": <string_or_null>,
    "previous_url": <string_or_null>,
    "per_page": <integer>
  },
  "total_count": <integer>,
  "data_updated_at": <date>,
  "data": <array_of_objects>
}

All of the responses have a few shared, high-level attributes: object, url, data_updated_at, and data.

Attribute Description
object The kind of object returned. See the object types section below for all the kinds.
url The URL of the request. For collections, that will contain all the filters and options you've passed to the API. Resources have a single URL and don't need to be filtered, so the URL will be the same in both resource and collection responses.
data_updated_at For collections, this is the timestamp of the most recently updated resource in the specified scope and is not limited by pagination. For a resource, then this is the last time that particular resource was updated.
data For collections, this is going to be the resources returned by the specified scope. For resources, these are the attributes that are specific to that particular instance and kind of resource.

Object Types

Every successful API response contains an object attribute that tells you which kind of thing you're getting. As mentioned before, there are two object types that return information on many different resources:

The following are singular resources:

Data Types

We stick to the common JSON data types in our responses: strings, integers, booleans, arrays, and objects. We follow the Javascript standard for date formatting, returning them in ISO 8601 format, rounded to the microsecond.

Pagination

Collection Size

By default, the maximum number of resources returned for collection endpoints is 500. Some endpoints may return a different size — reviews and subjects have a maximum size of 1,000.

Any collection response has the per-page count in the pages.per_page attribute. Those same responses have a total_count attribute, too. That is a count of all resources available within the specified scope, not limited to pagination.

Pagination in Action

When there are more resources to return than the per-page limit, we use a cursor-based pagination scheme to move through the pages of results. We use the id of a resource as the cursor.

Collections have the following nested within a pages attribute:

Attribute Data Type Description
next_url String The URL of the next page of results. If there are no more results, the value is null.
previous_url String The URL of the previous page of results. If there are no results at all or no previous page to go to, the value is null.
per_page Integer Maximum number of resources delivered for this collection.

The previous page of results can be requested by passing in the page_before_id parameter, with the value being the id you want to look before. Similar logic applies for the next page. Pass in the page_after_id parameter with with the id you want to look after.

If a cursor is outside the range of ids for the collection, an empty result set is returned for data.

Example

Let’s say there are four resources with IDs of 1, 2, 3, 4.

Filters

Collections have optional filters to help narrow the results returned. The filters are passed in as URL parameters, like ?parameter=value&other_parameter=value.

Any time we take a query parameter that's listed as an array data type, we take that array as a comma delimited list of values. A single value is also valid.

So, if a collection endpoint takes subject_ids as an argument for filtering results, your requests might have the following formats:

Errors

Errors with a message will return with the follow response body structure:

{ "error": <string>, "code": <integer> }

We use standard HTTP response codes to indicate the status of the response. Codes in the 200s indicate success, 400s usually indicate a client configuration problem (that's you), while 500s indicate that something bad is happening on the server (that's us).

The codes are presented in the header of the response; some error responses will also contain a body with the message specified below:

Code Meaning Message
200 Success n/a
401 Unauthorized “Unauthorized. Nice try.”
403 Forbidden
404 Not Found
422 Unprocessable Entity Description of how the request was malformed.
429 Too Many Requests
500 Internal Server Error n/a
503 Service Unavailable n/a

Rate Limit

We enforce the following rate limits to ensure decent response times for everyone using the API:

Throttle Value
Requests per minute 60

An HTTP status code of 429 (Forbidden) and a body with the message Rate Limit Exceeded is returned if the limits are exceeded (shocking, we know).

Revisions (aka Versioning)

To define the revision, use this code:

curl "https://api.wanikani.com/v2/<api_endpoint_here>" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = '<api_endpoint_here>';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Any time we make ‘breaking changes’ to the API, we release a new, timestamped revision of the API. Non-breaking changes don't trigger a new revision, and those changes are available in all versions of the API.

Revisions are designated by timestamps in the format YYYYMMDD. We expect the revision to be included in all API requests to the server in a header that looks like the following: Wanikani-Revision: 20170710.

See the list of revisions and changelogs for more details.

Best Practices

We're always working to make the API as performant as possible, but there are a few things you can do to optimize your use of the data we deliver and speed things up when you need to make new requests: cache data locally whenever possible, make conditional requests to minimize network load, and make use of the updated_after filter on a lot of the endpoints.

When you're building applications or services that other people will use, there's also some work to be done to respect the access to content granted by a subscription to WaniKani (per our terms and generally being a good citizen).

Caching

Most of the data on WaniKani doesn't change that often, so long-lived caches or more permanent stores that are periodically updated can eliminate a lot of time-consuming requests and help with offline functionality, if that's something you're after.

Here are a few recommendations that might influence what you cache and how long you keep it around:

Do take note any of the above recommendations may become outdated, but we will try out best to communicate these changes.

Caching is always tricky business. When do you expire it? How do you refresh it? Who's in charge of it?

We've done a couple things to try and help with a couple of the problems around caching. The first is to support conditional requests, which lets us quickly tell you that a record hasn't changed since you got it last. The second is to give you tools to get only the updated or new records after any point in time, letting you easily refresh your local data caches and stores without having to parse all the records.

Conditional Requests

We accept the If-None-Match and If-Modified-Since headers for every endpoint. If the response body hasn't changed since the last request, then a HTTP status code 304 (Not Modified) and an empty response body is returned. The advantage to using these headers is a faster response time since we don't have to generate a full response; we assume you still have the unmodified data cached.

Each response includes the ETag and Last-Modified headers that are used to populate If-None-Match and If-Modified-Since, respectively. These values can be used in future requests at the matching endpoint.

If both If-None-Match and If-Modified-Since are passed in, then If-None-Match takes precedence.

If-Modified-Since

To define If-Modified-Since, use this code:

curl "<api_endpoint_here>"
  -H "Authorization: Bearer <api_token_here>"
  -H "Wanikani-Revision: 20170710"
  -H "If-Modified-Since: <last_modified_date_here>"
var requestHeaders = new Headers();
requestHeaders.append('Authorization', 'Bearer <api_token_here>');
requestHeaders.append('Wanikani-Revision', '20170710');
requestHeaders.append('If-Modified-Since', '<last_modified_date_here>');
var requestInit = { method: 'GET', headers: requestHeaders };
var endpoint = new Request('<api_endpoint_here>', requestInit);

fetch(endpoint)
  .then(function(response) { return response.json(); })
  .then(function(responseBody) { console.log(responseBody); });

Make sure to replace <last_modified_date_here> with the Last-Modified value extracted from a previous response header or any datetime.

The If-Modified-Since request header takes in a Last-Modified value from the last request — or any datetime — in the following format:

If-Modified-Since: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT

Where:

Example: If-Modified-Since: Fri, 11 Nov 2011 11:11:11 GMT

The generally-excellent MDN web docs have more information on the If-Modified-Since header.

If-None-Match

To define If-None-Match, use this code:

curl "<api_endpoint_here>"
  -H "Authorization: Bearer <api_token_here>"
  -H "Wanikani-Revision: 20170710"
  -H "If-None-Match: <etag_here>"
var requestHeaders = new Headers();
requestHeaders.append('Authorization', 'Bearer <api_token_here>');
requestHeaders.append('Wanikani-Revision', '20170710');
requestHeaders.append('If-None-Match', '<etag_here>');
var requestInit = { method: 'GET', headers: requestHeaders };
var endpoint = new Request('<api_endpoint_here>', requestInit);

fetch(endpoint)
  .then(function(response) { return response.json(); })
  .then(function(responseBody) { console.log(responseBody); });

Make sure to replace <etag_here> with the ETag value extracted from a previous response header.

The If-None-Match request header takes in an ETag value from the last request's response header:

If-None-Match: <etag_here>

The MDN web docs have more information on the If-None-Match header, too.

Leveraging the updated_after Filter

All of the collection endpoints support an updated_after filter. As you'd guess, that's going to only return records that have been updated after the timestamp you pass to us.

Example/Scenario/Not a Fable

How does that help with performance and caching? By only returning the records you need.

Let's say you're building a statistics site. You need to know about all the subjects plus get all of a user's assignments, review statistics, reviews, resets, and level progressions to figure out how they've done in the past and do some guesswork on how they might do in the future.

Focusing in on the assignments, let's say you decide to re-calculate a user's progress every time they log in to use your site. Without the updated_after filter, you'd have to grab all their assignments, since there'd be no way to tell which ones had changed until after you retrieved them all. For high level users, that could be 18 sequential requests! Once you've made them sit through that progress bar, you'd need to parse all the results and compare to them what you've stored locally.

With the updated_after filter, though, you can ask for only the records that have changed since the last time that user logged in, getting a smaller, faster response full of records you know you have to update or add internally. Even high activity users are only going to touch a small portion of their assignments at a time. We can generate that list of records far more rapidly, it'll be a smaller payload, and you probably won't need to page through results to get everything that you need.

Respecting Subscription Restrictions

WaniKani has paid subscriptions. That may come as a surprise in 2019, but it's true. Those subscriptions grant access to all the content past level three and let people to do lessons and reviews for that content.

When the API is used for your own uses (populating spreadsheets, backing up progress, etc.), those access restrictions don't have that much of an impact. Most of the data delivered by the API belongs to you: assignments, study materials, review statistics, and those bits about how you progress through WaniKani. The only data that isn't yours is the content in subjects. All those mnemonics, hints, and relationships have been painstakingly crafted by the WaniKani staff to make learning kanji faster and better. That content is covered by pertinent copyright laws — which also means that fair use allows you to use it to learn on your own.

Once you start building tools that can be used by other people, things change, though. First, you can't use the content to build anything that's for profit. Second, you need to respect the limitations put in place by the subscriptions. Both of those requirements are per our terms. So, how do you do meet those requirements?

The user endpoint has a subscription attribute. That should have everything you need.

Your application can use max_level_granted as a first, easy line of defense. That restricts content access based on their subscription, and is most of what you need to do. The active, type, and period_ends_at fields are all their to let you build more robust solutions. Those help you figure out when your application needs to check up on subscription status (if ever) or do things like expire access if the user hasn't connected in a while.

Additional Information

Spaced Repetition System

There are 10 stages in our spaced-repetition system. We start at 0, which indicates that the subject hasn't been learned through lessons yet. When an assignment for a subject has obtained stage 5 once, the assignment.passed_at is touched, where it contributes towards level progress and can unlock additional assignments. Getting an assignment to stage 9 removes the timestamp on assignment.available_at, which removes the associated subject from the user's review queue — we think it's been firmly burned into memory at that point.

We use the SRS stages to calculate the time until the next review (the 'space' in the 'spaced-repetition').

The accelerated interval is used for the first two levels of assignments.

Stage Name Interval (hours) Accelerated Interval (hours)
0 Initiate 0 0
1 Apprentice I 4 2
2 Apprentice II 8 4
3 Apprentice III 23 8
4 Apprentice IV 47 23
5 Guru I 167 167
6 Guru II 335 335
7 Master 719 719
8 Enlightened 2,879 2,879
9 Burned n/a n/a

For additional information regarding SRS stages please check out the article on WaniKani Knowledge.

User Resets

Users have the option to reset their account to a target level at or below their current level.

Resets will show up in a variety of places. Explicit records will show up under resets. They'll get a fresh level progression for the target level of the reset, and the level progression for the level they abandoned gets an abandoned_at timestamp. Finally, the assignments and review_statistics for the affected levels will get set back to their default state, waiting to be unlocked or started, depending on the levels.

Resources

Assignments

Assignments contain information about a user's progress on a particular subject, including their current state and timestamps for various progress milestones. Assignments are created when a user has passed all the components of the given subject and the assignment is at or below their current level for the first time.

Assignment Data Structure

Example Structure

{
  "id": 80463006,
  "object": "assignment",
  "url": "https://api.wanikani.com/v2/assignments/80463006",
  "data_updated_at": "2017-10-30T01:51:10.438432Z",
  "data": {
    "created_at": "2017-09-05T23:38:10.695133Z",
    "subject_id": 8761,
    "subject_type": "radical",
    "srs_stage": 8,
    "srs_stage_name": "Enlightened",
    "unlocked_at": "2017-09-05T23:38:10.695133Z",
    "started_at": "2017-09-05T23:41:28.980679Z",
    "passed_at": "2017-09-07T17:14:14.491889Z",
    "burned_at": null,
    "available_at": "2018-02-27T00:00:00.000000Z",
    "resurrected_at": null,
    "passed": true,
    "resurrected": false
  }
}
Attribute Data Type Description
available_at null or Date Timestamp when the related subject will be available in the user's review queue.
burned_at null or Date Timestamp when the user reaches SRS stage 9 the first time.
created_at Date Timestamp when the assignment was created.
hidden Boolean Indicates if the associated subject has been hidden, preventing it from appearing in lessons or reviews.
passed_at null or Date Timestamp when the user reaches SRS stage 5 for the first time.
passed Boolean The boolean equivalent of passed_at
resurrected_at null or Date Timestamp when the subject is resurrected and placed back in the user's review queue.
resurrected Boolean A convenience field indicating that the subject has been burned, resurrected, and is still in the user's review queue.
srs_stage_name String The stage name associated with the srs_stage.
srs_stage Integer The current SRS stage interval, from 0 to 9.
started_at null or Date Timestamp when the user completes the lesson for the related subject.
subject_id Integer Unique identifier of the associated subject.
subject_type String The type of the associated subject, one of: kanji, radical, or vocabulary.
unlocked_at null or Date

The timestamp when the related subject has its prerequisites satisfied and is made available in lessons.

Prerequisites are:

  • The subject components have reached SRS stage 5 once (they have been “passed”).
  • The user's level is equal to or greater than the level of the assignment’s subject.

Get All Assignments

Example Request

curl "https://api.wanikani.com/v2/assignments" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'assignments';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "collection",
  "url": "https://api.wanikani.com/v2/assignments",
  "pages": {
    "per_page": 500,
    "next_url": "https://api.wanikani.com/v2/assignments?page_after_id=80469434",
    "previous_url": null
  },
  "total_count": 1600,
  "data_updated_at": "2017-11-29T19:37:03.571377Z",
  "data": [
    {
      "id": 80463006,
      "object": "assignment",
      "url": "https://api.wanikani.com/v2/assignments/80463006",
      "data_updated_at": "2017-10-30T01:51:10.438432Z",
      "data": {
        "created_at": "2017-09-05T23:38:10.695133Z",
        "subject_id": 8761,
        "subject_type": "radical",
        "srs_stage": 8,
        "srs_stage_name": "Enlightened",
        "unlocked_at": "2017-09-05T23:38:10.695133Z",
        "started_at": "2017-09-05T23:41:28.980679Z",
        "passed_at": "2017-09-07T17:14:14.491889Z",
        "burned_at": null,
        "available_at": "2018-02-27T00:00:00.000000Z",
        "resurrected_at": null,
        "passed": true,
        "resurrected": false
      }
    }
  ]
}

Returns a collection of all assignments, ordered by ascending created_at, 500 at a time.

HTTP Request

GET https://api.wanikani.com/v2/assignments

Query Parameters

The collection of assignments will be filtered on the parameters provided.

Name Data Type Description
available_after Date Only assignments available at or after this time are returned.
available_before Date Only assignments available at or before this time are returned.
burned Boolean When set to true, returns assignments that have a value in data.burned_at. Returns assignments with a null data.burned_at if false.
hidden Boolean Return assignments with a matching value in the hidden attribute
ids Array of integers Only assignments where data.id matches one of the array values are returned.
immediately_available_for_lessons (not required) Returns assignments which are immediately available for lessons
immediately_available_for_review (not required) Returns assignments which are immediately available for review
in_review (not required) Returns assignments which are in the review state
levels Array of integers Only assignments where the associated subject level matches one of the array values are returned. Valid values range from 1 to 60.
passed Boolean Returns assignments where data.passed equals passed.
resurrected Boolean Returns assignments where data.resurrected equals resurrected.
srs_stages Array of integers Only assignments where data.srs_stage matches one of the array values are returned. Valid values range from 0 to 9
started Boolean When set to true, returns assignments that have a value in data.started_at. Returns assignments with a null data.started_at if false.
subject_ids Array of integers Only assignments where data.subject_id matches one of the array values are returned.
subject_types Array of strings Only assignments where data.subject_type matches one of the array values are returned. Valid values are: radical, kanji, or vocabulary.
unlocked Boolean When set to true, returns assignments that have a value in data.unlocked_at. Returns assignments with a null data.unlocked_at if false.
updated_after Date Only assignments updated after this time are returned.

Query Parameter Examples

Assignments Available for Review in Two Hours

If the date time now is November 11, 2017 8:42:00 AM UTC:

https://api.wanikani.com/v2/assignments?available_after=2017-11-11T10:42:00Z

Level 8 and 42 Kanji Assignments Which Have Been Burned

https://api.wanikani.com/v2/assignments?levels=8,42&subject_types=kanji&burned=true

Assignments Updated After One Hour Ago and at SRS Stage Master I

If the date time now is November 11, 2017 8:42:00 AM UTC:

https://api.wanikani.com/v2/assignments?updated_after=2017-11-11T7:42:00Z&srs_stages=7

Get a Specific Assignment

Example Request

curl "https://api.wanikani.com/v2/assignments/80463006" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'assignments/80463006';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "id": 80463006,
  "object": "assignment",
  "url": "https://api.wanikani.com/v2/assignments/80463006",
  "data_updated_at": "2017-11-29T19:37:03.571377Z",
  "data": {
    "created_at": "2017-09-05T23:38:10.695133Z",
    "subject_id": 8761,
    "subject_type": "radical",
    "level": 1,
    "srs_stage": 8,
    "srs_stage_name": "Enlightened",
    "unlocked_at": "2017-09-05T23:38:10.695133Z",
    "started_at": "2017-09-05T23:41:28.980679Z",
    "passed_at": "2017-09-07T17:14:14.491889Z",
    "burned_at": null,
    "available_at": "2018-02-27T00:00:00.000000Z",
    "passed": true,
    "resurrected_at": null,
    "resurrected": false
  }
}

Retrieves a specific assignment by its id.

HTTP Request

GET https://api.wanikani.com/v2/assignments/<id>

Parameters

Name Data Type Description
id Integer Unique identifier of the assignment.

Notes

The unlocked_at, started_at, passed_at, and burned_at timestamps are always in sequential order — assignments can't be started before they're unlocked, passed before they're started, etc.

Start an Assignment

Example Request

curl "https://api.wanikani.com/v2/assignments/80463006/start" \
  -X "PUT" \
  -H "Wanikani-Revision: 20170710" \
  -H "Content-Type: application/json; charset=utf-8" \
  -H "Authorization: Bearer <api_token_here>" \
  -d $'{
       "started_at": "2017-09-05T23:41:28.980679Z"
     }'
var apiToken = '<api_token_here>';
var apiEndpointPath = 'assignments/80463006/start';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'PUT',
    headers: requestHeaders,
    body: {
      "started_at": "2017-09-05T23:41:28.980679Z"
    }
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "id": 80463006,
  "object": "assignment",
  "url": "https://api.wanikani.com/v2/assignments/80463006",
  "data_updated_at": "2017-11-29T19:37:03.571377Z",
  "data": {
    "created_at": "2017-09-05T23:38:10.695133Z",
    "subject_id": 8761,
    "subject_type": "radical",
    "level": 1,
    "srs_stage": 1,
    "srs_stage_name": "Apprentice I",
    "unlocked_at": "2017-09-05T23:38:10.695133Z",
    "started_at": "2017-09-05T23:41:28.980679Z",
    "passed_at": null,
    "burned_at": null,
    "available_at": "2018-02-27T00:00:00.000000Z",
    "passed": false,
    "resurrected_at": null,
    "resurrected": false
  }
}

Mark the assignment as started, moving the assignment from the lessons queue to the review queue. Returns the updated assignment.

HTTP Request

PUT https://api.wanikani.com/v2/assignments/<id>/start

Allowed Parameters

Name Data Type Required?
started_at Date false

Notes:

Expected Starting State

The assignment must be in the following valid state:

Attribute State
level Must be less than or equal to the lowest value of User's level and max_level_granted_by_subscription
srs_stage Must be equal to 0
started_at Must be equal to null
unlocked_at Must not be null

Updated Attributes

Attribute New Value
available_at ISO8601 String timestamp
srs_stage_name Apprentice I
srs_stage 1
started_at ISO8601 String timestamp

Level Progressions

Level progressions contain information about a user's progress through the WaniKani levels.

A level progression is created when a user has met the prerequisites for leveling up, which are:

Level Progression Data Structure

Example Structure

{
  "id": 49392,
  "object": "level_progression",
  "url": "https://www.wanikani.com/api/v2/level_progressions/49392",
  "data_updated_at": "2017-03-30T11:31:20.438432Z",
  "data": {
    "created_at": "2017-03-30T08:21:51.439918Z",
    "level": 42,
    "unlocked_at": "2017-03-30T08:21:51.439918Z",
    "started_at": "2017-03-30T11:31:20.438432Z",
    "passed_at": null,
    "completed_at": null,
    "abandoned_at": null
  }
}
Attribute Possible Values Description
abandoned_at null or Date Timestamp when the user abandons the level. This is primary used when the user initiates a reset.
completed_at null or Date Timestamp when the user burns 100% of the assignments belonging to the associated subject's level.
created_at Date Timestamp when the level progression is created
level Integer The level of the progression, with possible values from 1 to 60.
passed_at null or Date Timestamp when the user passes at least 90% of the assignments with a type of kanji belonging to the associated subject's level.
started_at null or Date Timestamp when the user starts their first lesson of a subject belonging to the level.
unlocked_at null or Date Timestamp when the user can access lessons and reviews for the level.

Get All Level Progressions

Example Request

curl "https://api.wanikani.com/v2/level_progressions" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'level_progressions';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "collection",
  "url": "https://www.wanikani.com/api/v2/level_progressions",
  "pages": {
    "per_page": 500,
    "next_url": null,
    "previous_url": null
  },
  "total_count": 42,
  "data_updated_at": "2017-09-21T11:45:01.691388Z",
  "data": [
    {
      "id": 49392,
      "object": "level_progression",
      "url": "https://www.wanikani.com/api/v2/level_progressions/49392",
      "data_updated_at": "2017-03-30T11:31:20.438432Z",
      "data": {
        "created_at": "2017-03-30T08:21:51.439918Z",
        "level": 42,
        "unlocked_at": "2017-03-30T08:21:51.439918Z",
        "started_at": "2017-03-30T11:31:20.438432Z",
        "passed_at": null,
        "completed_at": null,
        "abandoned_at": null
      }
    }
  ]
}

Returns a collection of all level progressions, ordered by ascending created_at, 500 at a time.

HTTP Request

GET https://api.wanikani.com/v2/level_progressions

Query Parameters

The collection of assignments will be filtered on the parameters provided.

Name Permitted values Description
ids Array of integers Only level progressions where data.id matches one of the array values are returned.
updated_after Date Only level_progressions updated after this time are returned.

Get a Specific Level Progression

Example Request

curl "https://api.wanikani.com/v2/level_progressions/49392" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'level_progressions/49392';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "id": 49392,
  "object": "level_progression",
  "url": "https://api.wanikani.com/v2/level_progressions/49392",
  "data_updated_at": "2017-03-30T11:31:20.438432Z",
  "data": {
    "created_at": "2017-03-30T08:21:51.439918Z",
    "level": 42,
    "unlocked_at": "2017-03-30T08:21:51.439918Z",
    "started_at": "2017-03-30T11:31:20.438432Z",
    "passed_at": null,
    "completed_at": null,
    "abandoned_at": null
  }
}

Retrieves a specific level progression by its id.

HTTP Request

GET https://api.wanikani.com/v2/level_progressions/<id>

Parameters

Name Data Type Description
id Integer Unique identifier of the level progression.

Notes

The unlocked_at, started_at, passed_at, and completed_at timestamps are always in sequential order — level progressions can't be started before they're unlocked, passed before they're started, etc.

Resets

Users can reset their progress back to any level at or below their current level. When they reset to a particular level, all of the assignments and review_statistics at that level or higher are set back to their default state.

Resets contain information about when those resets happen, the starting level, and the target level.

Reset Data Structure

Example Structure

{
  "id": 234,
  "object": "reset",
  "url": "https://api.wanikani.com/v2/resets/80463006",
  "data_updated_at": "2017-12-20T00:24:47.048380Z",
  "data": {
    "created_at": "2017-12-20T00:03:56.642838Z",
    "original_level": 42,
    "target_level": 8,
    "confirmed_at": "2017-12-19T23:31:18.077268Z"
  }
}

Attribute Data Type Description
confirmed_at null or Date Timestamp when the user confirmed the reset.
created_at Date Timestamp when the reset was created.
original_level Integer The user's level before the reset, from 1 to 60
target_level Integer The user's level after the reset, from 1 to 60. It must be less than or equal to original_level.

Get All Resets

Example Request

curl "https://api.wanikani.com/v2/resets" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'resets';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "collection",
  "url": "https://api.wanikani.com/v2/resets",
  "pages": {
    "per_page": 500,
    "next_url": null,
    "previous_url": null
  },
  "total_count": 2,
  "data_updated_at": "2017-11-29T19:37:03.571377Z",
  "data": [
    {
      "id": 234,
      "object": "reset",
      "url": "https://api.wanikani.com/v2/resets/80463006",
      "data_updated_at": "2017-12-20T00:24:47.048380Z",
      "data": {
        "created_at": "2017-12-20T00:03:56.642838Z",
        "original_level": 42,
        "target_level": 8,
        "confirmed_at": "2017-12-19T23:31:18.077268Z"
      }
    }
  ]
}

Returns a collection of all resets, ordered by ascending created_at, 500 at a time.

HTTP Request

GET https://api.wanikani.com/v2/resets

Query Parameters

The collection of resets will be filtered on the parameters provided.

Name Permitted values Description
ids Array of integers Only resets where data.id matches one of the array values are returned.
updated_after Date Only resets updated after this time are returned.

Get a Specific Reset

Example Request

curl "https://api.wanikani.com/v2/resets/234" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'resets/234';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "id": 234,
  "object": "reset",
  "url": "https://api.wanikani.com/v2/resets/234",
  "data_updated_at": "2017-03-30T11:31:20.438432Z",
  "data": {
    "created_at": "2017-12-20T00:03:56.642838Z",
    "original_level": 42,
    "target_level": 8,
    "confirmed_at": "2017-12-19T23:31:18.077268Z"
  }
}

Retrieves a specific reset by its id.

HTTP Request

GET https://api.wanikani.com/v2/resets/<id>

Parameters

Name Data Type Description
id Integer Unique identifier of the reset.

Reviews

Reviews log all the correct and incorrect answers provided through the 'Reviews' section of WaniKani. Review records are created when a user answers all the parts of a subject correctly once; some subjects have both meaning or reading parts, and some only have one or the other. Note that reviews are not created for the quizzes in lessons.

Review Data Structure

Example Structure

{
  "id": 534342,
  "object": "review",
  "url": "https://api.wanikani.com/v2/reviews/534342",
  "data_updated_at": "2017-12-20T01:00:59.255427Z",
  "data": {
    "created_at": "2017-12-20T01:00:59.255427Z",
    "assignment_id": 32132,
    "subject_id": 8,
    "starting_srs_stage": 4,
    "starting_srs_stage_name": "Apprentice IV",
    "ending_srs_stage": 2,
    "ending_srs_stage_name": "Apprentice II",
    "incorrect_meaning_answers": 1,
    "incorrect_reading_answers": 0
  }
}
Attribute Date Type Description
assignment_id Integer Unique identifier of the associated assignment.
created_at Date Timestamp when the review was created.
ending_srs_stage_name String The stage name associated with the ending_srs_stage.
ending_srs_stage Integer The SRS stage interval calculated from the number of correct and incorrect answers, with valid values ranging from 1 to 9
incorrect_meaning_answers Integer The number of times the user has answered the meaning incorrectly.
incorrect_reading_answers Integer The number of times the user has answered the reading incorrectly.
starting_srs_stage_name String The stage name associated with the starting_srs_stage.
starting_srs_stage Integer The starting SRS stage interval, with valid values ranging from 1 to 8
subject_id Integer Unique identifier of the associated subject.

Notes

A subject (radical, kanji, and vocabulary) may not require a meaning or reading. Therefore attributes incorrect_meaning_answers and incorrect_reading_answers will return a value of 0 for subjects which do not have the requirement.

Subject type Answer types allowed
kanji Meaning, Reading
radical Meaning
vocabulary Meaning, Reading

Get All Reviews

Example Request

curl "https://api.wanikani.com/v2/reviews" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'reviews';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "collection",
  "url": "https://api.wanikani.com/v2/reviews",
  "pages": {
    "per_page": 1000,
    "next_url": "https://api.wanikani.com/v2/reviews?page_after_id=534345",
    "previous_url": null
  },
  "total_count": 19201,
  "data_updated_at": "2017-12-20T01:10:17.578705Z",
  "data": [
    {
      "id": 534342,
      "object": "review",
      "url": "https://api.wanikani.com/v2/reviews/534342",
      "data_updated_at": "2017-12-20T01:00:59.255427Z",
      "data": {
        "created_at": "2017-12-20T01:00:59.255427Z",
        "assignment_id": 32132,
        "subject_id": 8,
        "starting_srs_stage": 4,
        "starting_srs_stage_name": "Apprentice IV",
        "ending_srs_stage": 2,
        "ending_srs_stage_name": "Apprentice II",
        "incorrect_meaning_answers": 1,
        "incorrect_reading_answers": 0
      }
    }
  ]
}

Returns a collection of all reviews, ordered by ascending created_at, 1000 at a time.

HTTP Request

GET https://api.wanikani.com/v2/reviews

Query Parameters

The collection of reviews will be filtered on the parameters provided.

Name Data Type Description
assignment_ids Array of integers Only reviews where data.assignment_id matches one of the array values are returned.
ids Array of integers Only reviews where data.id matches one of the array values are returned.
subject_ids Array of integers Only reviews where data.subject_id matches one of the array values are returned.
updated_after Date Only reviews updated after this time are returned.

Examples

Reviews Belonging to Kanji 大 Reviewed After Yesterday

Assumptions:

https://api.wanikani.com/v2/reviews?subject_ids=42&updated_after=2017-10-11T10:42:00Z

Get a Specific Review

Example Request

curl "https://api.wanikani.com/v2/reviews/534342" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'reviews/534342';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "id": 534342,
  "object": "review",
  "url": "https://api.wanikani.com/v2/reviews/80463006",
  "data_updated_at": "2017-12-20T01:00:59.255427Z",
  "data": {
    "created_at": "2017-12-20T01:00:59.255427Z",
    "assignment_id": 32132,
    "subject_id": 8,
    "starting_srs_stage": 4,
    "starting_srs_stage_name": "Apprentice IV",
    "incorrect_meaning_answers": 1,
    "incorrect_reading_answers": 0
  }
}

Retrieves a specific review by its id.

HTTP Request

GET https://api.wanikani.com/v2/reviews/<id>

Parameters

Name Data Type Description
id Integer Unique identifier of the review.

Create a Review

Example Request

curl "https://api.wanikani.com/v2/reviews" \
  -X "POST" \
  -H "Wanikani-Revision: 20170710" \
  -H "Content-Type: application/json; charset=utf-8" \
  -H "Authorization: Bearer <api_token_here>" \
  -d $'{
       "review": {
         "assignment_id": 1422,
         "incorrect_meaning_answers": 1,
         "incorrect_reading_answers": 2,
         "created_at": "2017-09-30T01:42:13.453291Z"
       }
     }'
var apiToken = '<api_token_here>';
var apiEndpointPath = 'reviews';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'POST',
    headers: requestHeaders,
    body: {
      "review": {
        "assignment_id": 1422,
        "incorrect_meaning_answers": 1,
        "incorrect_reading_answers": 2,
        "created_at": "2017-09-30T01:42:13.453291Z"
      }
    }
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "id": 72,
  "object": "review",
  "url": "https://api.wanikani.com/v2/reviews/72",
  "data_updated_at": "2018-05-13T03:34:54.000000Z",
  "data": {
    "created_at": "2018-05-13T03:34:54.000000Z",
    "assignment_id": 1422,
    "subject_id": 997,
    "starting_srs_stage": 1,
    "starting_srs_stage_name": "Apprentice I",
    "ending_srs_stage": 1,
    "ending_srs_stage_name": "Apprentice I",
    "incorrect_meaning_answers": 1,
    "incorrect_reading_answers": 2
  },
  "resources_updated": {
    "assignment": {
      "id": 1422,
      "object": "assignment",
      "url": "https://api.wanikani.com/v2/assignments/1422",
      "data_updated_at": "2018-05-14T03:35:34.180006Z",
      "data": {
        "created_at": "2018-01-24T21:32:38.967244Z",
        "subject_id": 997,
        "subject_type": "vocabulary",
        "level": 2,
        "srs_stage": 1,
        "srs_stage_name": "Apprentice I",
        "unlocked_at": "2018-01-24T21:32:39.888359Z",
        "started_at": "2018-01-24T21:52:47.926376Z",
        "passed_at": null,
        "burned_at": null,
        "available_at": "2018-05-14T07:00:00.000000Z",
        "resurrected_at": null,
        "passed": false,
        "resurrected": false,
        "hidden": false
      }
    },
    "review_statistic": {
      "id": 342,
      "object": "review_statistic",
      "url": "https://api.wanikani.com/v2/review_statistics/342",
      "data_updated_at": "2018-05-14T03:35:34.223515Z",
      "data": {
        "created_at": "2018-01-24T21:35:55.127513Z",
        "subject_id": 997,
        "subject_type": "vocabulary",
        "meaning_correct": 1,
        "meaning_incorrect": 1,
        "meaning_max_streak": 1,
        "meaning_current_streak": 1,
        "reading_correct": 1,
        "reading_incorrect": 2,
        "reading_max_streak": 1,
        "reading_current_streak": 1,
        "percentage_correct": 67,
        "hidden": false
      }
    }
  }
}

Creates a review for a specific assignment_id. Using the related subject_id is also a valid alternative to using assignment_id.

Some criteria must be met in order for a review to be created: available_at must be not null and in the past.

When a review is registered, the associated assignment and review_statistic are both updated. These are returned in the response body under resources_updated.

HTTP Request

POST https://api.wanikani.com/v2/reviews/

Allowed Parameters

Name Data Type Required? Description
assignment_id Integer true Unique identifier of the assignment. This or subject_id must be set.
subject_id Integer true Unique identifier of the subject. This or assignment_id must be set.
incorrect_meaning_answers Integer true Must be zero or a positive number. This is the number of times the meaning was answered incorrectly.
incorrect_reading_answers Integer true Must be zero or a positive number. This is the number of times the reading was answered incorrectly. Note that subjects with a type or radical do not quiz on readings. Thus, set this value to 0.
created_at Date false Timestamp when the review was completed. Defaults to the time of the request if omitted from the request body. Must be in the past, but after assignment.available_at.

Review Statistics

Review statistics summarize the activity recorded in reviews. They contain sum the number of correct and incorrect answers for both meaning and reading. They track current and maximum streaks of correct answers. They store the overall percentage of correct answers versus total answers.

A review statistic is created when the user has done their first review on the related subject.

Review Statistic Data Structure

Example Structure

{
  "id": 80461982,
  "object": "review_statistic",
  "url": "https://api.wanikani.com/v2/review_statistics/80461982",
  "data_updated_at": "2018-04-03T11:50:31.558505Z",
  "data": {
    "created_at": "2017-09-05T23:38:10.964821Z",
    "subject_id": 8761,
    "subject_type": "radical",
    "meaning_correct": 8,
    "meaning_incorrect": 0,
    "meaning_max_streak": 8,
    "meaning_current_streak": 8,
    "reading_correct": 0,
    "reading_incorrect": 0,
    "reading_max_streak": 0,
    "reading_current_streak": 0,
    "percentage_correct": 100,
    "hidden": false
  }
}
Attribute Data Type Description
created_at Date Timestamp when the review statistic was created.
hidden Boolean Indicates if the associated subject has been hidden, preventing it from appearing in lessons or reviews.
meaning_correct Integer Total number of correct answers submitted for the meaning of the associated subject.
meaning_current_streak Integer The current, uninterrupted series of correct answers given for the meaning of the associated subject.
meaning_incorrect Integer Total number of incorrect answers submitted for the meaning of the associated subject.
meaning_max_streak Integer The longest, uninterrupted series of correct answers ever given for the meaning of the associated subject.
percentage_correct Integer The overall correct answer rate by the user for the subject, including both meaning and reading.
reading_correct Integer Total number of correct answers submitted for the reading of the associated subject.
reading_current_streak Integer The current, uninterrupted series of correct answers given for the reading of the associated subject.
reading_incorrect Integer Total number of incorrect answers submitted for the reading of the associated subject.
reading_max_streak Integer The longest, uninterrupted series of correct answers ever given for the reading of the associated subject.
subject_id Integer Unique identifier of the associated subject.
subject_type String The type of the associated subject, one of: kanji, radical, or vocabulary.

Notes

Get All Review Statistics

Example Request

curl "https://api.wanikani.com/v2/review_statistics" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'review_statistics';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "collection",
  "url": "https://api.wanikani.com/v2/review_statistics",
  "pages": {
    "per_page": 500,
    "next_url": "https://api.wanikani.com/v2/review_statistics?page_after_id=80461982",
    "previous_url": null
  },
  "total_count": 980,
  "data_updated_at": "2018-04-06T14:43:14.337681Z",
  "data": [
    {
      "id": 80461982,
      "object": "review_statistic",
      "url": "https://api.wanikani.com/v2/review_statistics/80461982",
      "data_updated_at": "2018-04-03T11:50:31.558505Z",
      "data": {
        "created_at": "2017-09-05T23:38:10.964821Z",
        "subject_id": 8761,
        "subject_type": "radical",
        "meaning_correct": 8,
        "meaning_incorrect": 0,
        "meaning_max_streak": 8,
        "meaning_current_streak": 8,
        "reading_correct": 0,
        "reading_incorrect": 0,
        "reading_max_streak": 0,
        "reading_current_streak": 0,
        "percentage_correct": 100,
        "hidden": false
      }
    }
  ]
}

Returns a collection of all review statistics, ordered by ascending created_at, 500 at a time.

HTTP Request

GET https://api.wanikani.com/v2/review_statistics

Query Parameters

The collection of review statistics will be filtered on the parameters provided.

Name Data Type Description
hidden Boolean Return review statistics with a matching value in the hidden attribute
ids Array of integers Only review statistics where data.id matches one of the array values are returned.
percentages_greater_than Integer Return review statistics where the percentage_correct is greater than the value.
percentages_less_than Integer Return review statistics where the percentage_correct is less than the value.
subject_ids Array of integers Only review statistics where data.subject_id matches one of the array values are returned.
subject_types Array of strings Only review statistics where data.subject_type matches one of the array values are returned. Valid values are: radical, kanji, or vocabulary.
updated_after Date Only review statistics updated after this time are returned.

Get a Specific Review Statistic

Example Request

curl "https://api.wanikani.com/v2/review_statistics/80461982" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'review_statistics/80461982';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "id": 80461982,
  "object": "review_statistic",
  "url": "https://api.wanikani.com/v2/review_statistics/80461982",
  "data_updated_at": "2018-04-03T11:50:31.558505Z",
  "data": {
    "created_at": "2017-09-05T23:38:10.964821Z",
    "subject_id": 8761,
    "subject_type": "radical",
    "meaning_correct": 8,
    "meaning_incorrect": 0,
    "meaning_max_streak": 8,
    "meaning_current_streak": 8,
    "reading_correct": 0,
    "reading_incorrect": 0,
    "reading_max_streak": 0,
    "reading_current_streak": 0,
    "percentage_correct": 100,
    "hidden": false
  }
}

Retrieves a specific review statistic by its id.

HTTP Request

GET https://api.wanikani.com/v2/review_statistics/<id>

Parameters

Name Data Type Description
id Integer Unique identifier of the review_statistic.

SRS Stages

This report summarizes the space repetition intervals. These intervals are used to calculate the assignment.available_at.

SRS Stages Data Structure

Example Structure

{
  "object": "report",
  "url": "https://api.wanikani.com/v2/srs_stages",
  "data_updated_at": "2018-04-19T21:53:03.000000Z",
  "data": [
    {
      "srs_stage": 1,
      "srs_stage_name": "Apprentice I",
      "interval": 14400,
      "accelerated_interval": 7200
    }
  ]
}
Attribute Data Type Description
accelerated_interval Integer The duration of the stage in seconds for levels which have accelerated space repetition.
interval Integer The duration of the stage in seconds.
srs_stage Integer The stage identifier.
srs_stage_name String The name of the stage.

Get the SRS Stages

Example Request

curl "https://api.wanikani.com/v2/srs_stages" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'srs_stages';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "report",
  "url": "https://api.wanikani.com/v2/srs_stages",
  "data_updated_at": "2018-04-19T21:53:03.000000Z",
  "data": [
    {
      "srs_stage": 0,
      "srs_stage_name": "Initiate",
      "interval": 0,
      "accelerated_interval": 0
    },
    {
      "srs_stage": 1,
      "srs_stage_name": "Apprentice I",
      "interval": 14400,
      "accelerated_interval": 7200
    },
    {
      "srs_stage": 2,
      "srs_stage_name": "Apprentice II",
      "interval": 28800,
      "accelerated_interval": 14400
    },
    {
      "srs_stage": 3,
      "srs_stage_name": "Apprentice III",
      "interval": 82800,
      "accelerated_interval": 28800
    },
    {
      "srs_stage": 4,
      "srs_stage_name": "Apprentice IV",
      "interval": 169200,
      "accelerated_interval": 82800
    },
    {
      "srs_stage": 5,
      "srs_stage_name": "Guru I",
      "interval": 601200,
      "accelerated_interval": 601200
    },
    {
      "srs_stage": 6,
      "srs_stage_name": "Guru II",
      "interval": 1206000,
      "accelerated_interval": 1206000
    },
    {
      "srs_stage": 7,
      "srs_stage_name": "Master",
      "interval": 2588400,
      "accelerated_interval": 2588400
    },
    {
      "srs_stage": 8,
      "srs_stage_name": "Enlightened",
      "interval": 10364400,
      "accelerated_interval": 10364400
    },
    {
      "srs_stage": 9,
      "srs_stage_name": "Burned",
      "interval": 0,
      "accelerated_interval": 0
    }
  ]
}

Returns a summary of srs stages.

HTTP Request

GET https://api.wanikani.com/v2/srs_stages

Study Materials

Study materials store user-specific notes and synonyms for a given subject. The records are created as soon as the user enters any study information.

Study Material Data Structure

Example Structure

{
  "id": 65231,
  "object": "study_material",
  "url": "https://api.wanikani.com/v2/study_materials/65231",
  "data_updated_at": "2017-09-30T01:42:13.453291Z",
  "data": {
    "created_at": "2017-09-30T01:42:13.453291Z",
    "subject_id": 241,
    "subject_type": "radical",
    "meaning_note": "I like turtles",
    "reading_note": "I like たrtles",
    "meaning_synonyms": ["burn", "sizzle"]
  }
}
Attribute Data Type Description
created_at Date Timestamp when the study material was created.
hidden Boolean Indicates if the associated subject has been hidden, preventing it from appearing in lessons or reviews.
meaning_note null or String Free form note related to the meaning(s) of the associated subject.
meaning_synonyms Array Synonyms for the meaning of the subject. These are used as additional correct answers during reviews.
reading_note null or String Free form note related to the reading(s) of the associated subject.
subject_id Integer Unique identifier of the associated subject.
subject_type String The type of the associated subject, one of: kanji, radical, or vocabulary.

Get All Study Materials

Example Request

curl "https://api.wanikani.com/v2/study_materials" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'study_materials';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "collection",
  "url": "https://api.wanikani.com/v2/study_materials",
  "pages": {
    "per_page": 500,
    "next_url": "https://api.wanikani.com/v2/study_materials?page_after_id=52342",
    "previous_url": null
  },
  "total_count": 88,
  "data_updated_at": "2017-12-21T22:42:11.468155Z",
  "data": [
    {
      "id": 65231,
      "object": "study_material",
      "url": "https://api.wanikani.com/v2/study_materials/65231",
      "data_updated_at": "2017-09-30T01:42:13.453291Z",
      "data": {
        "created_at": "2017-09-30T01:42:13.453291Z",
        "subject_id": 241,
        "subject_type": "radical",
        "meaning_note": "I like turtles",
        "reading_note": "I like durtles",
        "meaning_synonyms": ["burn", "sizzle"]
      }
    }
  ]
}

Returns a collection of all study material, ordered by ascending created_at, 500 at a time.

HTTP Request

GET https://api.wanikani.com/v2/study_materials

Query Parameters

The collection of study material records will be filtered on the parameters provided.

Name Data Type Description
hidden Boolean Return study materials with a matching value in the hidden attribute
ids Array of integers Only study material records where data.id matches one of the array values are returned.
subject_ids Array of integers Only study material records where data.subject_id matches one of the array values are returned.
subject_types Array of strings Only study material records where data.subject_type matches one of the array values are returned. Valid values are: radical, kanji, or vocabulary.
updated_after Date Only study material records updated after this time are returned.

Examples

Study Materials Updated Since Yesterday

Assumptions:

https://api.wanikani.com/v2/study_materials?updated_after=2017-10-11T10:42:00Z

Get a Specific Study Material

Example Request

curl "https://api.wanikani.com/v2/study_materials/65231" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'study_materials/65231';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
 "id": 65231,
 "object": "study_material",
 "url": "https://api.wanikani.com/v2/study_materials/65231",
 "data_updated_at": "2017-09-30T01:42:13.453291Z",
 "data": {
   "created_at": "2017-09-30T01:42:13.453291Z",
   "subject_id": 241,
   "subject_type": "radical",
   "meaning_note": "I like turtles",
   "reading_note": "I like durtles",
   "meaning_synonyms": ["burn", "sizzle"]
 }
}

Retrieves a specific study material by its id.

HTTP Request

GET https://api.wanikani.com/v2/study_materials/<id>

Parameters

Name Data Type Description
id Integer Unique identifier of the study material.

Create a Study Material

Example Request

curl "https://api.wanikani.com/v2/study_materials" \
  -X "POST" \
  -H "Wanikani-Revision: 20170710" \
  -H "Content-Type: application/json; charset=utf-8" \
  -H "Authorization: Bearer <api_token_here>" \
  -d $'{
       "study_material": {
         "subject_id": 2,
         "meaning_note": "The two grounds is too much",
         "reading_note": "This is tsu much",
         "meaning_synonyms": [
           "double"
         ]
       }
     }'
var apiToken = '<api_token_here>';
var apiEndpointPath = 'study_materials';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'POST',
    headers: requestHeaders,
    body: {
      "study_material": {
        "subject_id": 2,
        "meaning_note": "The two grounds is too much",
        "reading_note": "This is tsu much",
        "meaning_synonyms": [
          "double"
        ]
      }
    }
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
 "id": 234,
 "object": "study_material",
 "url": "https://api.wanikani.com/v2/study_materials/234",
 "data_updated_at": "2017-09-30T01:42:13.453291Z",
 "data": {
   "created_at": "2017-09-30T01:42:13.453291Z",
   "subject_id": 2,
   "subject_type": "kanji",
   "meaning_note": "The two grounds is too much",
   "reading_note": "This is tsu much",
   "meaning_synonyms": ["double"]
 }
}

Creates a study material for a specific subject_id.

The owner of the api key can only create one study_material per subject_id.

HTTP Request

POST https://api.wanikani.com/v2/study_materials/

Parameters

Name Data Type Required? Description
subject_id Integer true Unique identifier of the subject.
meaning_note String false Meaning notes specific for the subject.
reading_note String false Reading notes specific for the subject.
meaning_synonyms Array of Strings false Meaning synonyms for the subject.

Update a Study Material

Example Request

curl "https://api.wanikani.com/v2/study_materials/234" \
  -X "PUT" \
  -H "Wanikani-Revision: 20170710" \
  -H "Content-Type: application/json; charset=utf-8" \
  -H "Authorization: Bearer <api_token_here>" \
  -d $'{
       "study_material": {
         "meaning_note": "The two grounds are on top of each other",
         "reading_note": "This is too tsu much",
         "meaning_synonyms": [
           "double",
           "twice"
         ]
       }
     }'
var apiToken = '<api_token_here>';
var apiEndpointPath = 'study_materials/234';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'PUT',
    headers: requestHeaders,
    body: {
      "study_material": {
        "meaning_note": "The two grounds are on top of each other",
        "reading_note": "This is too tsu much",
        "meaning_synonyms": [
          "double",
          "twice"
        ]
      }
    }
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
 "id": 234,
 "object": "study_material",
 "url": "https://api.wanikani.com/v2/study_materials/234",
 "data_updated_at": "2017-10-15T06:23:43.345321Z",
 "data": {
   "created_at": "2017-09-30T01:42:13.453291Z",
   "subject_id": 2,
   "subject_type": "kanji",
   "meaning_note": "The two grounds are on top of each other",
   "reading_note": "This is too tsu much",
   "meaning_synonyms": ["double", "twice"]
 }
}

Updates a study material for a specific id.

HTTP Request

PUT https://api.wanikani.com/v2/study_materials/234

Parameters

Name Data Type Required? Description
meaning_note String false Meaning notes specific for the subject.
reading_note String false Reading notes specific for the subject.
meaning_synonyms Array of Strings false Meaning synonyms for the subject.

Subjects

Subjects are the radicals, kanji, and vocabulary that are learned through lessons and reviews. They contain basic dictionary information, such as meanings and/or readings, and information about their relationship to other items with WaniKani, like their level.

Subject Data Structure

The exact structure of a subject depends on the subject type. The available subject types are radical, kanji, and vocabulary. Note that any attributes called out for the specific subject type behaves differently than the common attribute of the same name.

Common Attributes

Attribute Data Type Description
auxiliary_meanings Array of objects Collection of auxiliary meanings. See table below for the object structure.
characters String The UTF-8 characters for the subject, including kanji and hiragana.
created_at Date Timestamp when the subject was created.
document_url String A URL pointing to the page on wanikani.com that provides detailed information about this subject.
hidden_at Date Timestamp when the subject was hidden, indicating associated assignments will no longer appear in lessons or reviews and that the subject page is no longer visible on wanikani.com.
lesson_position Integer The position that the subject appears in lessons. Note that the value is scoped to the level of the subject, so there are duplicate values across levels.
level Integer The level of the subject, from 1 to 60.
meaning_mnemonic String The subject's meaning mnemonic.
meanings Array of objects The subject meanings. See table below for the object structure.
slug String The string that is used when generating the document URL for the subject. Radicals use their meaning, downcased. Kanji and vocabulary use their characters.

Meaning Object Attributes

Attribute Data Type Description
meaning String A singular subject meaning.
primary Boolean Indicates priority in the WaniKani system.
accepted_answer Boolean Indicates if the meaning is used to evaluate user input for correctness.

Auxiliary Meaning Object Attributes

Attribute Data Type Description
meaning String A singular subject meaning.
type String Either whitelist or blacklist. When evaluating user input, whitelisted meanings are used to match for correctness. Blacklisted meanings are used to match for incorrectness.

Markup highlighting

One or many of these attributes can be present in radical, kanji, and vocabulary:

The strings can include a WaniKani specific markup syntax. The following is a list of markup used:


Radical Attributes

Example Structure

{
  "id": 1,
  "object": "radical",
  "url": "https://api.wanikani.com/v2/subjects/1",
  "data_updated_at": "2018-03-29T23:13:14.064836Z",
  "data": {
    "amalgamation_subject_ids": [
      5,
      4,
      98
    ],
    "auxiliary_meanings": [
      {
        "meaning": "grund",
        "type": "blacklist"
      }
    ],
    "characters": "一",
    "character_images": [
      {
        "url": "https://cdn.wanikani.com/images/legacy/576-subject-1-without-css-original.svg?1520987227",
        "metadata": {
          "inline_styles": false
        },
        "content_type": "image/svg+xml"
      }
    ],
    "created_at": "2012-02-27T18:08:16.000000Z",
    "document_url": "https://www.wanikani.com/radicals/ground",
    "hidden_at": null,
    "lesson_position": 1
    "level": 1,
    "meanings": [
      {
        "meaning": "Ground",
        "primary": true,
        "accepted_answer": true
      }
    ],
    "meaning_mnemonic": "This radical consists of a single, horizontal stroke. What's the biggest, single, horizontal stroke? That's the ground. Look at the <radical>ground</radical>, look at this radical, now look at the ground again. Kind of the same, right?",
    "slug": "ground",
  }
}
Attribute Data Type Description
amalgamation_subject_ids Array of integers An array of numeric identifiers for the kanji that have the radical as a component.
characters String or null Unlike kanji and vocabulary, radicals can have a null value for characters. Not all radicals have a UTF entry, so the radical must be visually represented with an image instead.
character_images Array of objects A collection of images of the radical. See table below for the object structure.

Character Image Object Attributes

Attribute Data Type Description
url String The location of the image.
content_type String The content type of the image. Currently the API delivers image/png and image/svg+xml.
metadata Object Details about the image. Each content_type returns a uniquely structured object.

Kanji Attributes

Example Structure

{
  "id": 440,
  "object": "kanji",
  "url": "https://api.wanikani.com/v2/subjects/440",
  "data_updated_at": "2018-03-29T23:14:30.805034Z",
  "data": {
    "amalgamation_subject_ids": [
      56,
      88,
      91
    ],
    "auxiliary_meanings": [
      {
        "meaning": "one",
        "type": "blacklist"
      },
      {
        "meaning": "flat",
        "type": "whitelist"
      }
    ],
    "characters": "一",
    "component_subject_ids": [
      1
    ],
    "created_at": "2012-02-27T19:55:19.000000Z",
    "document_url": "https://www.wanikani.com/kanji/%E4%B8%80",
    "hidden_at": null,
    "lesson_position": 2
    "level": 1,
    "meanings": [
      {
        "meaning": "One",
        "primary": true,
        "accepted_answer": true
      }
    ],
    "meaning_hint": "To remember the meaning of <kanji>One</kanji>, imagine yourself there at the scene of the crime. You grab <kanji>One</kanji> in your arms, trying to prop it up, trying to hear its last words. Instead, it just splatters some blood on your face. "Who did this to you?" you ask. The number One points weakly, and you see number Two running off into an alleyway. He's always been jealous of number One and knows he can be number one now that he's taken the real number one out.",
    "meaning_mnemonic": "Lying on the <radical>ground</radical> is something that looks just like the ground, the number <kanji>One</kanji>. Why is this One lying down? It's been shot by the number two. It's lying there, bleeding out and dying. The number One doesn't have long to live.",
    "readings": [
      {
        "type": "onyomi",
        "primary": true,
        "accepted_answer": true,
        "reading": "いち"
      },
      {
        "type": "kunyomi",
        "primary": false,
        "accepted_answer": false,
        "reading": "ひと"
      },
      {
        "type": "nanori",
        "primary": false,
        "accepted_answer": false,
        "reading": "かず"
      }
    ],
    "reading_mnemonic": "As you're sitting there next to <kanji>One</kanji>, holding him up, you start feeling a weird sensation all over your skin. From the wound comes a fine powder (obviously coming from the special bullet used to kill One) that causes the person it touches to get extremely <reading>itchy</reading> (いち)",
    "reading_hint": "Make sure you feel the ridiculously <reading>itchy</reading> sensation covering your body. It climbs from your hands, where you're holding the number <kanji>One</kanji> up, and then goes through your arms, crawls up your neck, goes down your body, and then covers everything. It becomes uncontrollable, and you're scratching everywhere, writhing on the ground. It's so itchy that it's the most painful thing you've ever experienced (you should imagine this vividly, so you remember the reading of this kanji).",
    "slug": "一",
    "visually_similar_subject_ids": [],
  }
}
Attribute Data Type Description
amalgamation_subject_ids Array of integers An array of numeric identifiers for the vocabulary that have the kanji as a component.
component_subject_ids Array of integers An array of numeric identifiers for the radicals that make up this kanji. Note that these are the subjects that must be have passed assignments in order to unlock this subject's assignment.
readings Array of objects Selected readings for the kanji. See table below for the object structure.
visually_similar_subject_ids Array of integers An array of numeric identifiers for kanji which are visually similar to the kanji in question.

Reading Object Attributes

Attribute Data Type Description
reading String A singular subject reading.
primary Boolean Indicates priority in the WaniKani system.
accepted_answer Boolean Indicates if the reading is used to evaluate user input for correctness.
type String The kanji reading's classfication: kunyomi, nanori, or onyomi.

Vocabulary Attributes

Example Structure

{
  "id": 2467,
  "object": "vocabulary",
  "url": "https://api.wanikani.com/v2/subjects/2467",
  "data_updated_at": "2018-12-12T23:09:52.234049Z",
  "data": {
    "auxiliary_meanings": [
      {
        "type": "whitelist",
        "meaning": "1"
      }
    ],
    "characters": "一",
    "component_subject_ids": [
      440
    ],
    "context_sentences": [
      {
        "en": "Let’s meet up once.",
        "ja": "一ど、あいましょう。"
      },
      {
        "en": "First place was an American.",
        "ja": "一いはアメリカ人でした。"
      },
      {
        "en": "I’m the weakest man in the world.",
        "ja": "ぼくはせかいで一ばんよわい。"
      }
    ],
    "created_at": "2012-02-28T08:04:47.000000Z",
    "document_url": "https://www.wanikani.com/vocabulary/%E4%B8%80",
    "hidden_at": null,
    "lesson_position": 44,
    "level": 1,
    "meanings": [
      {
        "meaning": "One",
        "primary": true,
        "accepted_answer": true
      }
    ],
    "meaning_mnemonic": "As is the case with most vocab words that consist of a single kanji, this vocab word has the same meaning as the kanji it parallels, which is \u003cvocabulary\u003eone\u003c/vocabulary\u003e.",
    "parts_of_speech": [
      "numeral"
    ],
    "pronunciation_audios": [
      {
        "url": "https://cdn.wanikani.com/audios/3020-subject-2467.mp3?1547862356",
        "metadata": {
          "gender": "male",
          "source_id": 2711,
          "pronunciation": "いち",
          "voice_actor_id": 2,
          "voice_actor_name": "Kenichi",
          "voice_description": "Tokyo accent"
        },
        "content_type": "audio/mpeg"
      },
      {
        "url": "https://cdn.wanikani.com/audios/3018-subject-2467.ogg?1547862356",
        "metadata": {
          "gender": "male",
          "source_id": 2711,
          "pronunciation": "いち",
          "voice_actor_id": 2,
          "voice_actor_name": "Kenichi",
          "voice_description": "Tokyo accent"
        },
        "content_type": "audio/ogg"
      }
    ],
    "readings": [
      {
        "primary": true,
        "reading": "いち",
        "accepted_answer": true
      }
    ],
    "reading_mnemonic": "When a vocab word is all alone and has no okurigana (hiragana attached to kanji) connected to it, it usually uses the kun'yomi reading. Numbers are an exception, however. When a number is all alone, with no kanji or okurigana, it is going to be the on'yomi reading, which you learned with the kanji.  Just remember this exception for alone numbers and you'll be able to read future number-related vocab to come.",
    "slug": "一",
  }
}
Attribute Data Type Description
component_subject_ids Array of integers An array of numeric identifiers for the kanji that make up this vocabulary. Note that these are the subjects that must be have passed assignments in order to unlock this subject's assignment.
context_sentences Array of objects A collection of context sentences. See table below for the object structure.
meaning_mnemonic String The subject's meaning mnemonic.
parts_of_speech Array of strings Parts of speech.
pronunciation_audios Array of objects A collection of pronunciation audio. See table below for the object structure.
readings Array of objects Selected readings for the vocabulary. See table below for the object structure.
reading_mnemonic String The subject's reading mnemonic.

Reading Object Attributes

Attribute Data Type Description
accepted_answer Boolean Indicates if the reading is used to evaluate user input for correctness.
primary Boolean Indicates priority in the WaniKani system.
reading String A singular subject reading.

Context Sentence Object Attributes

Attribute Data Type Description
en String English translation of the sentence
ja String Japanese context sentence

Pronunciation Audio Object Attributes

Attribute Data Type Description
url String The location of the audio.
content_type String The content type of the audio. Currently the API delivers audio/mpeg and audio/ogg.
metadata Object Details about the pronunciation audio. See table below for details.
Pronunciation Audio Metadata Object Attributes
Attribute Data Type Description
gender String The gender of the voice actor.
source_id Integer A unique ID shared between same source pronunciation audio.
pronunciation String Vocabulary being pronounced in kana.
voice_actor_id Integer A unique ID belonging to the voice actor.
voice_actor_name String Humanized name of the voice actor.
voice_description String Description of the voice.

Get All Subjects

Example Request

curl "https://api.wanikani.com/v2/subjects" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'subjects';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "collection",
  "url": "https://api.wanikani.com/v2/subjects?types=kanji",
  "pages": {
    "per_page": 1000,
    "next_url": "https://api.wanikani.com/v2/subjects?page_after_id=1439\u0026types=kanji",
    "previous_url": null
  },
  "total_count": 2027,
  "data_updated_at": "2018-04-09T18:08:59.946969Z",
  "data": [
    {
      "id": 440,
      "object": "kanji",
      "url": "https://api.wanikani.com/v2/subjects/440",
      "data_updated_at": "2018-03-29T23:14:30.805034Z",
      "data": {
        "created_at": "2012-02-27T19:55:19.000000Z",
        "level": 1,
        "slug": "一",
        "hidden_at": null,
        "document_url": "https://www.wanikani.com/kanji/%E4%B8%80",
        "characters": "一",
        "meanings": [
          {
            "meaning": "One",
            "primary": true,
            "accepted_answer": true
          }
        ],
        "readings": [
          {
            "type": "onyomi",
            "primary": true,
            "accepted_answer": true,
            "reading": "いち"
          },
          {
            "type": "kunyomi",
            "primary": false,
            "accepted_answer": false,
            "reading": "ひと"
          },
          {
            "type": "nanori",
            "primary": false,
            "accepted_answer": false,
            "reading": "かず"
          }
        ],
        "component_subject_ids": [
          1
        ],
        "amalgamation_subject_ids": [
          56,
          88,
          91
        ],
        "visually_similar_subject_ids": [],
        "meaning_mnemonic": "Lying on the <radical>ground</radical> is something that looks just like the ground, the number <kanji>One</kanji>. Why is this One lying down? It's been shot by the number two. It's lying there, bleeding out and dying. The number One doesn't have long to live.",
        "meaning_hint": "To remember the meaning of <kanji>One</kanji>, imagine yourself there at the scene of the crime. You grab <kanji>One</kanji> in your arms, trying to prop it up, trying to hear its last words. Instead, it just splatters some blood on your face. "Who did this to you?" you ask. The number One points weakly, and you see number Two running off into an alleyway. He's always been jealous of number One and knows he can be number one now that he's taken the real number one out.",
        "reading_mnemonic": "As you're sitting there next to <kanji>One</kanji>, holding him up, you start feeling a weird sensation all over your skin. From the wound comes a fine powder (obviously coming from the special bullet used to kill One) that causes the person it touches to get extremely <reading>itchy</reading> (いち)",
        "reading_hint": "Make sure you feel the ridiculously <reading>itchy</reading> sensation covering your body. It climbs from your hands, where you're holding the number <kanji>One</kanji> up, and then goes through your arms, crawls up your neck, goes down your body, and then covers everything. It becomes uncontrollable, and you're scratching everywhere, writhing on the ground. It's so itchy that it's the most painful thing you've ever experienced (you should imagine this vividly, so you remember the reading of this kanji).",
        "lesson_position": 2
      }
    }
  ]
}

Returns a collection of all subjects, ordered by ascending created_at, 1000 at a time.

HTTP Request

GET https://api.wanikani.com/v2/subjects

Query Parameters

The collection of subjects will be filtered on the parameters provided.

Name Data Type Description
ids Array of integers Only subjects where data.id matches one of the array values are returned.
types Array of strings Return subjects of the specified types.
slugs Array of strings Return subjects of the specified slug.
levels Array of integers Return subjects at the specified levels.
hidden Boolean Return subjects which are or are not hidden from the user-facing application.
updated_after Date Only subjects updated after this time are returned.

Get a Specific Subject

Retrieves a specific subject by its id. The structure of the response depends on the subject type. See the section on subject data structure for details.

HTTP Request

GET https://api.wanikani.com/v2/subjects/<id>

Parameters

Name Data Type Description
id Integer Unique identifier of the subject.

Summary

The summary report contains currently available lessons and reviews and the reviews that will become available in the next 24 hours, grouped by the hour.

Summary Data Structure

Example Structure

{
  "object": "report",
  "url": "https://api.wanikani.com/v2/summary",
  "data_updated_at": "2018-04-11T21:00:00.000000Z",
  "data": {
    "lessons": [
      {
        "available_at": "2018-04-11T21:00:00.000000Z",
        "subject_ids": [
          25,
          26
        ]
      }
    ],
    "next_reviews_at:" "2018-04-11T21:00:00.000000Z",
    "reviews": [
      {
        "available_at": "2018-04-11T21:00:00.000000Z",
        "subject_ids": [
          21,
          23,
          24
        ]
      },
      {
        "available_at": "2018-04-11T22:00:00.000000Z",
        "subject_ids": []
      },
      ...
    ]
  }
}
Attribute Data Type Description
lessons Array of objects Details about subjects available for lessons. See table below for object structure.
next_reviews_at null or Date Earliest date when the reviews are available. Is null when the user has no reviews scheduled.
reviews Array of objects Details about subjects available for reviews now and in the next 24 hours by the hour (total of 25 objects). See table below for object structure.

Lesson Object Attributes

Attribute Data Type Description
available_at Date When the paired subject_ids are available for lessons. Always beginning of the current hour when the API endpoint is accessed.
subject_ids Array of integers Collection of unique identifiers for subjects.

Review Object Attributes

Attribute Data Type Description
available_at Date When the paired subject_ids are available for reviews. All timestamps are the top of an hour.
subject_ids Array of integers Collection of unique identifiers for subjects.

Get a Summary

Example Request

curl "https://api.wanikani.com/v2/summary" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'summary';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "report",
  "url": "https://api.wanikani.com/v2/summary",
  "data_updated_at": "2018-04-11T21:00:00.000000Z",
  "data": {
    "lessons": [
      {
        "available_at": "2018-04-11T21:00:00.000000Z",
        "subject_ids": [
          25,
          26
        ]
      }
    ],
    "next_reviews_at": "2018-04-11T21:00:00.000000Z",
    "reviews": [
      {
        "available_at": "2018-04-11T21:00:00.000000Z",
        "subject_ids": [
          21,
          23,
          24
        ]
      },
      {
        "available_at": "2018-04-11T22:00:00.000000Z",
        "subject_ids": []
      },
      ...
    ]
  }
}

Retrieves a summary report.

HTTP Request

GET https://api.wanikani.com/v2/summary

User

The user summary returns basic information for the user making the API request, identified by their API key.

User Data Structure

Example Structure

{
  "object": "user",
  "url": "https://api.wanikani.com/v2/user",
  "data_updated_at": "2018-04-06T14:26:53.022245Z",
  "data": {
    "id": "5a6a5234-a392-4a87-8f3f-33342afe8a42",
    "username": "example_user",
    "level": 5,
    "max_level_granted_by_subscription": 60,
    "profile_url": "https://www.wanikani.com/users/example_user",
    "started_at": "2012-05-11T00:52:18.958466Z",
    "subscribed": true,
    "current_vacation_started_at": null,
    "subscription": {
      "active": true,
      "type": "recurring",
      "max_level_granted": 60,
      "period_ends_at": "2018-12-11T13:32:19.485748Z"
    },
    "preferences": {
      "lessons_autoplay_audio": false,
      "lessons_batch_size": 10,
      "lessons_presentation_order": "ascending_level_then_subject",
      "reviews_autoplay_audio": false,
      "reviews_display_srs_indicator": true
    }
  }
}
Attribute Data Type Description
current_vacation_started_at null or Date If the user is on vacation, this will be the timestamp of when that vacation started. If the user is not on vacation, this is null.
level Integer The current level of the user. This ignores subscription status.
max_level_granted_by_subscription Integer NOTE: This will be dropped. Please use subscription instead. The maximum level of content accessible to the user for lessons, reviews, and content review. For unsubscribed/free users, the maximum level is 3. For subscribed users, this is 60. Any application that uses data from the WaniKani API must respect these access limits.
preferences Object User settings specific to the WaniKani application. See table below for the object structure.
profile_url String The URL to the user's public facing profile page.
started_at Date The signup date for the user.
subscribed Boolean NOTE: This will be dropped. Please use subscription instead. Whether or not the user currently has a paid subscription.
subscription Object Details about the user's subscription state. See table below for the object structure.
username String The user's username.

Preferences Object Attributes

Attribute Data Type Description
lessons_autoplay_audio Boolean Automatically play pronunciation audio for vocabulary during lessons.
lessons_batch_size Integer Number of subjects introduced to the user during lessons before quizzing.
lessons_presentation_order String The order in which lessons are presented. The options are ascending_level_then_subject, shuffled, and ascending_level_then_shuffled. The default (and best experience) is ascending_level_then_subject.
reviews_autoplay_audio Boolean Automatically play pronunciation audio for vocabulary during reviews.
reviews_display_srs_indicator Boolean Toggle for display SRS change indicator after a subject has been completely answered during review.

Subscription Object Attributes

Attribute Data Type Description
active Boolean Whether or not the user currently has a paid subscription.
max_level_granted Integer The maximum level of content accessible to the user for lessons, reviews, and content review. For unsubscribed/free users, the maximum level is 3. For subscribed users, this is 60. Any application that uses data from the WaniKani API must respect these access limits.
period_ends_at null or Date The date when the user's subscription period ends. If the user has subscription type lifetime or free then the value is null.
type String The type of subscription the user has. Options are following: free, recurring, and lifetime.

Get User Information

Example Request

curl "https://api.wanikani.com/v2/user" \
  -H "Wanikani-Revision: 20170710" \
  -H "Authorization: Bearer <api_token_here>"
var apiToken = '<api_token_here>';
var apiEndpointPath = 'user';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'GET',
    headers: requestHeaders
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "user",
  "url": "https://api.wanikani.com/v2/user",
  "data_updated_at": "2018-04-06T14:26:53.022245Z",
  "data": {
    "id": "5a6a5234-a392-4a87-8f3f-33342afe8a42",
    "username": "example_user",
    "level": 5,
    "max_level_granted_by_subscription": 60,
    "profile_url": "https://www.wanikani.com/users/example_user",
    "started_at": "2012-05-11T00:52:18.958466Z",
    "subscribed": true,
    "current_vacation_started_at": null,
    "subscription": {
      "active": true,
      "type": "recurring",
      "max_level_granted": 60,
      "period_ends_at": "2018-12-11T13:32:19.485748Z"
    },
    "preferences": {
      "lessons_autoplay_audio": false,
      "lessons_batch_size": 5,
      "lessons_presentation_order": "ascending_level_then_subject",
      "reviews_autoplay_audio": false,
      "reviews_display_srs_indicator": true
    }
  }
}

Returns a summary of user information.

HTTP Request

GET https://api.wanikani.com/v2/user

Update User Information

Example Request

curl "https://api.wanikani.com/v2/user" \
  -X "PUT" \
  -H "Wanikani-Revision: 20170710" \
  -H "Content-Type: application/json; charset=utf-8" \
  -H "Authorization: Bearer <api_token_here>" \
  -d $'{
       "user": {
         "preferences": {
           "lessons_autoplay_audio": true,
           "lessons_batch_size": 3,
           "lessons_presentation_order": "shuffled",
           "reviews_autoplay_audio": true,
           "reviews_display_srs_indicator": false
         }
       }
     }'
var apiToken = '<api_token_here>';
var apiEndpointPath = 'user';
var requestHeaders =
  new Headers({
    'Wanikani-Revision': '20170710',
    Authorization: 'Bearer ' + apiToken,
  });
var apiEndpoint =
  new Request('https://api.wanikani.com/v2/' + apiEndpointPath, {
    method: 'PUT',
    headers: requestHeaders,
    body: {
      "user": {
        "preferences": {
          "lessons_autoplay_audio": true,
          "lessons_batch_size": 3,
          "lessons_presentation_order": "shuffled",
          "reviews_autoplay_audio": true,
          "reviews_display_srs_indicator": false
        }
      }
    }
  });

fetch(apiEndpoint)
  .then(response => response.json())
  .then(responseBody => console.log(responseBody));

Example Response

{
  "object": "user",
  "url": "https://api.wanikani.com/v2/user",
  "data_updated_at": "2018-04-06T14:26:53.022245Z",
  "data": {
    "id": "5a6a5234-a392-4a87-8f3f-33342afe8a42",
    "username": "example_user",
    "level": 5,
    "max_level_granted_by_subscription": 60,
    "profile_url": "https://www.wanikani.com/users/example_user",
    "started_at": "2012-05-11T00:52:18.958466Z",
    "subscribed": true,
    "current_vacation_started_at": null,
    "subscription": {
      "active": true,
      "type": "recurring",
      "max_level_granted": 60,
      "period_ends_at": "2018-12-11T13:32:19.485748Z"
    },
    "preferences": {
      "lessons_autoplay_audio": true,
      "lessons_batch_size": 3,
      "lessons_presentation_order": "shuffled",
      "reviews_autoplay_audio": true,
      "reviews_display_srs_indicator": false
    }
  }
}

Returns an updated summary of user information.

HTTP Request

PUT https://api.wanikani.com/v2/user

Allowed Parameters

Only the values under preferences are allowed to be updated.

Name Data Type Required?
lessons_autoplay_audio Boolean false
lessons_batch_size Integer false
lessons_presentation_order String false
reviews_autoplay_audio Boolean false
reviews_display_srs_indicator Boolean false
shell javascript