How the (real) Duolingo API works: Endpoints

The Duolingo API is not officially documented, but can be found by sniffing the traffic from their mobile apps. The API is used for user information, Skills and their Lessons, etc.

The base URL of the API is https://www.duolingo.com/api/1.

GET /version_info

No authentication required

Response:

{
    "dict_base_url": "http://d2.duolingo.com/",
    "feature_flags": {
        "disable_discussions": false,
        "duolingo_for_schools": true,
        "use_newrelic_on_ios": true
    },
    "js_version": "//d7mj4aqfscim2.cloudfront.net/proxy/js2/2c5d8cfb60c72069af01-vendor.js-//d7mj4aqfscim2.cloudfront.net/proxy/js2/2c5d8cfb60c72069af01-duolingo.js",
    "logged_out_ab_options": {
        "course_button_experiment2": true,
        "course_title_experiment": true,
        "dummy_loggedout_ab_experiment": true,
        "login_modal_experiment": false,
        "signup_modal_buttons_experiment": true,
        "web_loggedout_no_background_image_experiment": true,
        "web_register_language_select_experiment": "scaled",
        "web_schools_splash_experiment": false
    },
    "offline": {
        "enabled": true,
        "max_lessons": 5
    },
    "speech_host": "speech.duolingo.com",
    "supported_directions": {
        "en": [
            "de",
            "es",
            "fr",
            "it",
            "pt"
        ],
        "es": [
            "en"
        ],
        "fr": [
            "en"
        ],
        "it": [
            "en"
        ],
        "pt": [
            "en"
        ]
    },
    "tts_base_url": "https://d7mj4aqfscim2.cloudfront.net/",
    "tts_cdn_url": "http://static.duolingo.com/",
    "tts_voice_configuration": {
        "multi_voices": "{\"dn\": [\"dn\"], \"fr\": [\"fr\", \"fr/mathieu\"], \"en\": [\"en/salli\"], \"pt\": [\"pt\"], \"nb\": [\"nb/liv\"], \"de\": [\"de\"], \"tr\": [\"tr/filiz\"], \"it\": [\"it/carla\"], \"da\": [\"da\"], \"sv\": [\"sv/astrid\"], \"es\": [\"es\"]}",
        "path": "tts/{voice}/{type}/{id}",
        "voices": "{\"nb\": \"nb/liv\", \"en\": \"en/salli\", \"tr\": \"tr/filiz\", \"it\": \"it/carla\", \"sv\": \"sv/astrid\"}"
    }
}

Things of note:

  • tts_cdn_url and tts_voice_configuration: These give the paths used for

    getting the audio files for various exercises. More on these later.

  • dict_base_url: This is the base URL for the multi-language dictionary.

GET /users/show?id={user_id} or /users/show?username={username}

With the users API, it’s important to know Duolingo’s concept of the current language. Instead of always returning all data about a language, Duolingo only returns the data on the language the user is currently learning, be it German, French, etc. This state is kept across web, mobile, etc. To get information on a user’s progress in another language, it’s necessary to change language TO that language first.

Content varies with authentication

Unauthenticated

{
    "admin": false,
    "avatar": "https://duolingo-images.s3.amazonaws.com/avatars/1/AX2PP_c3ls",
    "bio": "",
    "blockers": [],
    "blocking": [],
    "browser_language": "en",
    "calendar": [],
    "certificates": [],
    "change-design": false,
    "cohort": null,
    "created": "\n\n\n\n\n\n\n\n\n3 years ago\n",
    "daily_goal": null,
    "dashboard_redesign": true,
    "deactivated": false,
    "delete-permissions": false,
    "events": [],
    "facebook_id": null,
    "followers": [],
    "following": [],
    "freeze-permissions": false,
    "fullname": "",
    "gplus_id": null,
    "has_google_now": false,
    "has_observer": false,
    "id": 1,
    "inventory": {
        "timed_practice": "grandfathered"
    },
    "is_blocked_by": false,
    "is_blocking": false,
    "is_follower_by": false,
    "is_following": false,
    "is_self_observer": false,
    "language_data": {
        "es": {
            "all_time_rank": [
                "1"
            ],
            "bonus_rows": [
                4
            ],
            "bonus_skills": [
                {
                    "achievements": [],
                    "beginner": false,
                    "bonus": true,
                    "category": "bonus",
                    "changed": false,
                    "comment_data": {},
                    "coords_x": 2,
                    "coords_y": 1000,
                    "dependencies": [],
                    "dependencies_name": [],
                    "description": "",
                    "disabled": false,
                    "explanation": null,
                    "has_explanation": "",
                    "icon_color": "purple",
                    "id": "b1be4ade8dfba595f69342e4e11891f9",
                    "index": "64",
                    "known_lexemes": [],
                    "language": "es",
                    "language_string": "Spanish",
                    "learned": false,
                    "learning_threshold": 0,
                    "learning_threshold_percentage": 0,
                    "left_lessons": 0,
                    "lesson": false,
                    "lesson_number": 1,
                    "locked": true,
                    "mastered": false,
                    "missing_lessons": 3,
                    "more_lessons": 0,
                    "name": "FLIRTING",
                    "new_index": 64,
                    "num_lessons": 3,
                    "num_lexemes": 17,
                    "num_missing": 17,
                    "num_translation_nodes": 0,
                    "path": [],
                    "practice_recommended": false,
                    "progress_percent": 0.0,
                    "short": "Flirting",
                    "strength": 0.0,
                    "test": false,
                    "test_count": 3,
                    "title": "Flirting",
                    "url_title": "Flirting",
                    "words": [
                        "quieres",
                        "eres",
                        "en",
                        "por",
                        "n\u00famero",
                        "cielo",
                        "gustas",
                        "ojos",
                        "una",
                        "hola"
                    ]
                },
                {
                    "achievements": [],
                    "beginner": false,
                    "bonus": true,
                    "category": "bonus",
                    "changed": false,
                    "comment_data": {},
                    "coords_x": 3,
                    "coords_y": 1000,
                    "dependencies": [],
                    "dependencies_name": [],
                    "description": "",
                    "disabled": false,
                    "explanation": null,
                    "has_explanation": "",
                    "icon_color": "purple",
                    "id": "6da3ebe37baff2a6efc1404235923ebd",
                    "index": "63",
                    "known_lexemes": [],
                    "language": "es",
                    "language_string": "Spanish",
                    "learned": false,
                    "learning_threshold": 0,
                    "learning_threshold_percentage": 0,
                    "left_lessons": 0,
                    "lesson": false,
                    "lesson_number": 1,
                    "locked": true,
                    "mastered": false,
                    "missing_lessons": 2,
                    "more_lessons": 0,
                    "name": "IDIOMS",
                    "new_index": 63,
                    "num_lessons": 2,
                    "num_lexemes": 15,
                    "num_missing": 15,
                    "num_translation_nodes": 0,
                    "path": [],
                    "practice_recommended": false,
                    "progress_percent": 0.0,
                    "short": "Idioms",
                    "strength": 0.0,
                    "test": false,
                    "test_count": 3,
                    "title": "Idioms and Proverbs",
                    "url_title": "Idioms-and-Proverbs",
                    "words": [
                        "quien",
                        "con",
                        "m\u00e1s",
                        "todo",
                        "coraz\u00f3n",
                        "se",
                        "el",
                        "de",
                        "cuenta",
                        "mal"
                    ]
                }
            ],
            "calendar": [],
            "direction_status": "released",
            "first_time": true,
            "fluency_score": 0.0,
            "immersion_enabled": true,
            "language": "es",
            "language_strength": 0,
            "language_string": "Spanish",
            "level": 1,
            "level_left": 60,
            "level_percent": 0,
            "level_points": 60,
            "level_progress": 0,
            "level_tests": [],
            "max_depth_learned": 0,
            "max_level": false,
            "max_tree_level": 1,
            "next_lesson": {
                "lesson_number": 1,
                "skill_title": "Basics 1",
                "skill_url": "Basics-1"
            },
            "next_level": 2,
            "no_dep": true,
            "num_skills_learned": 1,
            "placement_test": {
                "attempts": 1
            },
            "points": 0,
            "points_rank": 1,
            "points_ranking_data": [
                {
                    "avatar": "https://duolingo-images.s3.amazonaws.com/avatars/1/AX2PP_c3ls",
                    "fullname": "",
                    "id": 1,
                    "language": "es",
                    "language_string": "Spanish",
                    "points_data": {
                        "languages": [],
                        "total": 0
                    },
                    "rank": 1,
                    "self": true,
                    "username": "admin"
                }
            ],
            "points_ranking_data_dict": {
                "1": {
                    "avatar": "https://duolingo-images.s3.amazonaws.com/avatars/1/AX2PP_c3ls",
                    "fullname": "",
                    "id": 1,
                    "language": "es",
                    "language_string": "Spanish",
                    "points_data": {
                        "languages": [],
                        "total": 0
                    },
                    "self": true,
                    "username": "admin"
                }
            },
            "skills": [
                {
                    "achievements": [],
                    "beginner": false,
                    "bonus": false,
                    "category": "",
                    "changed": false,
                    "comment_data": {},
                    "coords_x": 2,
                    "coords_y": 10,
                    "dependencies": [
                        "Dates and Time"
                    ],
                    "dependencies_name": [
                        "DATES-AND-TIME"
                    ],
                    "description": "",
                    "disabled": false,
                    "explanation": null,
                    "has_explanation": null,
                    "icon_color": "blue",
                    "id": "9ad994514334443ac12f950280fac0dc",
                    "index": "45",
                    "known_lexemes": [],
                    "language": "es",
                    "language_string": "Spanish",
                    "learned": false,
                    "learning_threshold": 0,
                    "learning_threshold_percentage": 0,
                    "left_lessons": 0,
                    "lesson": false,
                    "lesson_number": 1,
                    "locked": true,
                    "mastered": false,
                    "missing_lessons": 1,
                    "more_lessons": 0,
                    "name": "SIZES",
                    "new_index": 39,
                    "num_lessons": 1,
                    "num_lexemes": 9,
                    "num_missing": 9,
                    "num_translation_nodes": 0,
                    "path": [],
                    "practice_recommended": false,
                    "progress_percent": 0,
                    "short": "Sizes",
                    "strength": 0,
                    "test": true,
                    "test_count": 3,
                    "title": "Sizes",
                    "url_title": "Sizes",
                    "words": [
                        "grande",
                        "peque\u00f1a",
                        "largo",
                        "altos",
                        "cortos",
                        "enormes",
                        "tama\u00f1o",
                        "gran",
                        "bajo"
                    ]
                },
                ...
            ]
            "streak": 0,
            "tc_estimate": null,
            "testcenter_estimate": null
        }
    },
    "languages": [
        {
            "current_learning": false,
            "language": "dn",
            "language_string": "Dutch",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "eo",
            "language_string": "Esperanto",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "uk",
            "language_string": "Ukrainian",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "pt",
            "language_string": "Portuguese",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "nb",
            "language_string": "Norwegian (Bokm\u00e5l)",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "de",
            "language_string": "German",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "tr",
            "language_string": "Turkish",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "fr",
            "language_string": "French",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "da",
            "language_string": "Danish",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "ga",
            "language_string": "Irish",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "it",
            "language_string": "Italian",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": false,
            "language": "sv",
            "language_string": "Swedish",
            "learning": false,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        },
        {
            "current_learning": true,
            "language": "es",
            "language_string": "Spanish",
            "learning": true,
            "level": 1,
            "points": 0,
            "sentences_translated": 0,
            "streak": 0,
            "to_next_level": 60
        }
    ],
    "learning_language": "es",
    "learning_language_string": "Spanish",
    "location": "",
    "notif_event_ids": [
        "ev_2567641930",
        "ev_2551857838",
        "ev_2547818680",
        "ev_2541303828",
        "ev_2355629187"
    ],
    "num_followers": 63,
    "num_following": 0,
    "num_observees": 0,
    "rupees": 0,
    "show_dashboard_ad": true,
    "sina_weibo_id": null,
    "site_streak": 0,
    "streak_extended_today": false,
    "trial_account": false,
    "twitter_id": null,
    "ui_language": "en",
    "upload-self-service": false,
    "username": "admin"
}

Authenticated

When an authenticated user requests their profile, they get a lot more information.

{
    "ab_options": {
        "android_11_google_now_experiment": true,
        ...
    },
    "admin": false,
    "auto_facebook_post": false,
    "autoplay": true,
    "avatar": "https://s3.amazonaws.com/duolingo-images/avatar/default_2",
    "bio": "",
    "blockers": [],
    "blocking": [],
    "browser_language": "en",
    "calendar": [
        {
            "datetime": 1435894795000.0,
            "improvement": 10
        },
        ...
    ],
    "certificates": [
        {
            "datetime": "\n\n\n\n\n\n\n\n1 month ago\n\n",
            "id": "abcde",
            "language": "de",
            "language_string": "German",
            "score": 2.09
        }
    ],
    "change-design": false,
    "cohort": null,
    "created": "\n\n\n\n\n\n\n\n\n3 years ago\n",
    "created_dt": 1338352674000.0,
    "creation_date": "2012-05-30T04:37:54",
    "current_time": 1436510650294.148,
    "daily_goal": 30,
    "dashboard_redesign": true,
    "deactivated": false,
    "delete-permissions": false,
    "email": "[email protected]",
    "events": [],
    "facebook_id": "123456789",
    "filter_stream": false,
    "followers": [],
    "following": [],
    "freeze-permissions": false,
    "fullname": null,
    "gplus_id": null,
    "has_google_now": false,
    "has_observer": false,
    "id": 1234,
    "insite_immersion_lingots": true,
    "insite_sentence_edited": true,
    "inventory": {
        "flirting_de": "2015-04-18 02:48:18",
        "formal_outfit": "2015-05-21 11:19:08",
        "idioms_de": "2015-02-16 02:18:53",
        "streak_freeze": "2015-05-14 05:53:16",
        "timed_practice": "grandfathered"
    },
    "invites": {
        "extra_invites": 0,
        "invited": [],
        "invites_left": 3
    },
    "is_following": false,
    "is_self_observer": false,
    "language_data": {
        "de": {
            "all_time_rank": [
                "1234",
                "9999999",
                "1111111"
            ],
            "bonus_rows": [
                4
            ],
            "bonus_skills": [
                {
                    "achievements": [],
                    "beginner": false,
                    "bonus": true,
                    "category": "bonus",
                    "changed": false,
                    "comment_data": {},
                    "coords_x": 1,
                    "coords_y": 1000,
                    "dependencies": [],
                    "dependencies_name": [],
                    "description": "",
                    "disabled": false,
                    "explanation": null,
                    "has_explanation": "",
                    "icon_color": "purple",
                    "id": "47cc154e7d091c46aefb18dbf583588d",
                    "index": "63",
                    "known_lexemes": [
                        "0e31a5f2b119b3f4b7b6eac64cc8e98c",
                        "4ae59c85701323605ad9c5e8d35a81cf",
                        "4d19a63831881edce7a42efbbe9b0cbc",
                        "54ca03339b893eb13bd2c0e699270ea3",
                        "625507b03d9d3d674f0aafe9a9b83c6d",
                        "793979dd80dd32ccba22a4ccf09d6dc6",
                        "8217bc2911be463e40f8277fbaad38e1",
                        "a69bac60383f632f46c89abb28c1be6b",
                        "b1758fb28f93586d6f2373c24cc2850e",
                        "c6bae3eda56c6c57292868a950657a0a",
                        "d26d14bf5202ced0f7ccf510c1e9379a",
                        "e5d5b55f107acc1e69eaf98cba857a1a",
                        "eb975e9337b1c55de88aa89d508746d2",
                        "fdaac4e11cfd5ba2e2d4ac5088434a5a",
                        "fdd9e771d1ed33fde73aeeabf8e587ab"
                    ],
                    "language": "de",
                    "language_string": "German",
                    "learned": true,
                    "learned_ts": 1424424687,
                    "learning_threshold": 0,
                    "learning_threshold_percentage": 0,
                    "left_lessons": 0,
                    "lesson": false,
                    "lesson_number": 1,
                    "locked": false,
                    "mastered": true,
                    "missing_lessons": 0,
                    "more_lessons": 0,
                    "name": "IDIOMS",
                    "new_index": 63,
                    "num_lessons": 2,
                    "num_lexemes": 15,
                    "num_missing": 0,
                    "num_translation_nodes": 0,
                    "path": [],
                    "practice_recommended": false,
                    "progress_percent": 100.0,
                    "short": "Idioms",
                    "strength": 1,
                    "test": false,
                    "test_count": 3,
                    "title": "Idioms and Proverbs",
                    "url_title": "Idioms-and-Proverbs",
                    "words": [
                        "Meister",
                        "wir",
                        "du",
                        "nicht",
                        "in",
                        "alles",
                        "sagt",
                        "das",
                        "es",
                        "ich"
                    ]
                },
                {
                    "achievements": [],
                    "beginner": false,
                    "bonus": true,
                    "category": "bonus",
                    "changed": false,
                    "comment_data": {},
                    "coords_x": 2,
                    "coords_y": 1000,
                    "dependencies": [],
                    "dependencies_name": [],
                    "description": "",
                    "disabled": false,
                    "explanation": null,
                    "has_explanation": "",
                    "icon_color": "purple",
                    "id": "12bf924c1fae71c723e86dd20b377928",
                    "index": "64",
                    "known_lexemes": [
                        "0021362e7e6c2ca9660d9c6ce58a3fea",
                        "0795b250299434fc8335f3f18f4a22ab",
                        "07b77395a5523aaa6424b797a8052bc8",
                        "08d5aedbf7533146786bca797c68789d",
                        "3879a2c7c57d026ce0d63028f4a7ac97",
                        "48fceec852338522f29d2c401224005e",
                        "5523a9bfb978db8f5cd0f5fda429c494",
                        "61d42d5a55018d2e1e1585cc57324702",
                        "624ed6195d86d1450165295ab875e171",
                        "671aff64046a3598f82f6cc7a1d2fbc2",
                        "9cb6715e32862480033e330c5b4971cb",
                        "a497fedbde428c113aadbe6ab4b2cc27",
                        "acd4b1188d2ecae1f735ef56308ade2f",
                        "bad3ea3a35e041def877b10ce1e249b1",
                        "ea3155c1930625d2ac0a7f1f7a941cdd"
                    ],
                    "language": "de",
                    "language_string": "German",
                    "learned": true,
                    "learned_ts": 1429326405,
                    "learning_threshold": 0,
                    "learning_threshold_percentage": 0,
                    "left_lessons": 0,
                    "lesson": false,
                    "lesson_number": 1,
                    "locked": false,
                    "mastered": true,
                    "missing_lessons": 0,
                    "more_lessons": 0,
                    "name": "FLIRTING",
                    "new_index": 64,
                    "num_lessons": 2,
                    "num_lexemes": 15,
                    "num_missing": 0,
                    "num_translation_nodes": 0,
                    "path": [],
                    "practice_recommended": false,
                    "progress_percent": 100.0,
                    "short": "Flirting",
                    "strength": 1,
                    "test": false,
                    "test_count": 3,
                    "title": "Flirting",
                    "url_title": "Flirting",
                    "words": [
                        "deine",
                        "darf",
                        "m\u00f6chte",
                        "dich",
                        "wir",
                        "nicht",
                        "n\u00e4chste",
                        "s\u00fc\u00df",
                        "bist",
                        "will"
                    ]
                }
            ],
            "calendar": [
                {
                    "datetime": 1435894795000.0,
                    "improvement": 10
                },
                {
                    "datetime": 1435894995000.0,
                    "improvement": 10
                },
                ...
            ],
            "direction_status": "released",
            "first_time": false,
            "fluency_score": 0.4546002196,
            "immersion_enabled": true,
            "language": "de",
            "language_strength": 0.96,
            "language_string": "German",
            "level": 14,
            "level_left": 66,
            "level_percent": 95,
            "level_points": 1500,
            "level_progress": 1434,
            "level_tests": [
                {
                    "attempts": 3,
                    "index": 0,
                    "level": 6
                },
                {
                    "attempts": 3,
                    "index": 1,
                    "level": 11
                },
                {
                    "attempts": 3,
                    "index": 2,
                    "level": 22
                },
                {
                    "attempts": 3,
                    "index": 3,
                    "level": 28
                }
            ],
            "max_depth_learned": 29,
            "max_level": false,
            "max_tree_level": 30,
            "next_lesson": {
                "lesson_number": 1,
                "skill_title": "Abstract Objects 1",
                "skill_url": "Abstract-Objects-1"
            },
            "next_level": 15,
            "no_dep": true,
            "notifications": {
                "chrome_app_ad": false,
                "duolingo_for_schools": false,
                "lesson_strength_bar": false
            },
            "notify_practice": false,
            "notify_time": 1020,
            "num_global_practice": 1,
            "num_skills_learned": 57,
            "placement_test": {
                "attempts": 1
            },
            "points": 7434,
            "points_rank": 1,
            "points_ranking_data": [
                {
                    "avatar": "https://s3.amazonaws.com/duolingo-images/avatar/default_2",
                    "fullname": null,
                    "id": 1234,
                    "language": "de",
                    "language_string": "German",
                    "points_data": {
                        "languages": [],
                        "total": 9651
                    },
                    "rank": 1,
                    "self": true,
                    "username": "me"
                },
                {
                    "avatar": "https://s3.amazonaws.com/duolingo-images/avatar/default_2",
                    "fullname": "My Friend",
                    "id": 9999999,
                    "language": "de",
                    "language_string": "German",
                    "points_data": {
                        "languages": [],
                        "total": 3000
                    },
                    "rank": 2,
                    "self": false,
                    "username": "friend"
                },
                ...
            },
            "push_practice": true,
            "show_practice": true,
            "skills": [
                ...
            ],
            "streak": 58,
            "tc_estimate": null,
            "testcenter_estimate": null,
            "tracking_properties": {
                "direction": "de<-en",
                "learning_language": "de",
                "max_tree_level": 30,
                "took_placementtest": false,
                "ui_language": "en"
            }
        }
    },
    "languages": [
        ...
    ],
    "learning_language": "de",
    "learning_language_string": "German",
    "location": null,
    "microphone": false,
    "notif_event_ids": [],
    "notify_activity_comment": true,
    "notify_activity_reply": true,
    "notify_announcement": true,
    "notify_comment": true,
    "notify_edit_suggested": true,
    "notify_follow": true,
    "notify_pass": true,
    "notify_stream_post": true,
    "num_followers": 5,
    "num_following": 8,
    "num_observees": 0,
    "push_activity_comment": true,
    "push_activity_reply": true,
    "push_announcement": true,
    "push_comment": true,
    "push_edit_suggested": true,
    "push_follow": false,
    "push_passed": false,
    "push_stream_post": true,
    "rupees": 349,
    "show_dashboard_ad": true,
    "sina_weibo_id": null,
    "site_streak": 142,
    "sound_effects": true,
    "speaker": true,
    "streak_extended_today": true,
    "timezone": "America/Los_Angeles",
    "timezone_offset": "-0700",
    "tracking_properties": {
        "creation_date_new": "2012-05-30T04:37:54",
        "has_google_now": false,
        "has_observer": false,
        "is_self_observer": false,
        "lingots": 349,
        "num_observees": 0,
        "trial_account": false,
        "user_id": 1234,
        "username": "me"
    },
    "trial_account": false,
    "twitter_id": null,
    "ui_language": "en",
    "upload-self-service": false,
    "username": "me",
    "week_old_account": true
}

GET /store/get_items

Requires authentication.

This endpoint just returns a list of all items available in the store. It’s not entirely clear to yet exactly how the app tracks which items have been bought, equipped, are available on that platform, etc.

Interestingly, their human-backed certification is included in this API response.

{
    "bonus_skills": [
        {
            "description": "Learn some German idioms and proverbs.",
            "icon_index": 63,
            "name": "idioms",
            "price": 30,
            "skill_id": "47cc154e7d091c46aefb18dbf583588d",
            "title": "Idioms and Proverbs"
        },
        {
            "description": "Do you believe in love at first sight? Learn to flirt in German.",
            "icon_index": 64,
            "name": "flirting",
            "price": 30,
            "skill_id": "12bf924c1fae71c723e86dd20b377928",
            "title": "Flirting"
        }
    ],
    "misc_items": [
        {
            "name": "certification_human",
            "price": 100
        },
        {
            "description": "Streak Freeze allows your streak to remain in place for one full day of inactivity.",
            "name": "streak_freeze",
            "price": 10,
            "title": "Streak Freeze"
        },
        {
            "name": "certification",
            "price": 25
        },
        {
            "description": "Attempt to double your five lingot wager by maintaining a seven day streak.",
            "name": "rupee_wager",
            "price": 5,
            "title": "Double or Nothing"
        },
        {
            "name": "timed_practice",
            "price": 10
        },
        {
            "description": "Allows you to regain one heart lost during a lesson.",
            "name": "heart_refill",
            "price": 4,
            "title": "Heart Refill"
        }
    ],
    "outfits": [
        {
            "description": "Learn in style. Duo has always been a sharp guy, now he'll look sharp too.",
            "name": "formal_outfit",
            "price": 20,
            "title": "Formal Attire"
        },
        {
            "description": "Learn in luxury. Duo will love the feel of 24 carat gold silk on his feathers.",
            "name": "luxury_outfit",
            "price": 30,
            "title": "Champagne Tracksuit"
        }
    ]
}

POST /me/switch_language

This endpoint is used to switch languages (imagine that!). To switch, it requires a form-encoded parameter learning_language, which should be the language you want to learn, like de.

It can also take a parameter from_language, which should be the two letter language you want to learn from, like en.

POST /me/switch_language
learning_language: fr

Its response body is equivalent to the language_data/language part of the /users/show endpoint shown above.

``GET /dictionary/hints/{target}/{source}?tokens=[“word1”,”word2”,...]

Oddly, this endpoint operates on a different base URL. The base URL can be gotten through /version_info. It takes the query string as shown above, and returns a result like this:

{
    bonjour: [
        "hello",
        "good morning",
        "good afternoon",
        "good day"
    ],
    monde: [
        "world",
        "people",
        "anyone",
        "crowd",
        "set",
        "society"
    ]
}

skills

activity stream