Discover/Duolingo API
live

Duolingo APIduolingo.com

Browse Duolingo's complete language course catalog to discover available courses, see how many learners are enrolled in each, and identify the source and target language pairs offered. Find the perfect language learning path by viewing all courses in one place.

This API takes change requests — .
Endpoint health
monitored
list_courses
Checks pendingself-healing
Endpoints
1
Updated
4h ago
This call costs1 credit / call— charged only on success
Try it
ISO 639-1 language code for the source language (instruction language). Filters courses to only those taught from this language. Example: 'en' for English, 'es' for Spanish.
api.parse.bot/scraper/3ea1693d-acff-4d24-a6fb-2564d076ae55/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/3ea1693d-acff-4d24-a6fb-2564d076ae55/list_courses?from_language=en' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

Typed, relational, agent-ready

A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.

  • Fully typed · autocompletes
  • Objects link to objects
  • Typed errors & pagination

Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:

uv add parse-sdk
uv run parse init
uv run parse add --marketplace duolingo-com-api

uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.


"""Walkthrough: Duolingo SDK — bounded, re-runnable; every call capped."""
from parse_apis.duolingo_com_api import Duolingo, ParseError

client = Duolingo()

# List courses available for English speakers, capped at 3
for course in client.courses.list(from_language="en", limit=3):
    print(course.learning_language_name, course.num_learners)

# Get the first course from the full catalog
top = client.courses.list(limit=1).first()
if top:
    print(top.learning_language_name, "from", top.from_language_name, "-", top.num_learners, "learners")

# Typed error handling around a call
try:
    for course in client.courses.list(from_language="es", limit=2):
        print(course.learning_language_name, course.from_language_name, course.phase)
except ParseError as e:
    print(f"error: {e.code}")

print("exercised: courses.list")
All endpoints · 1 totalmissing one? ·

Returns all available Duolingo courses. Each course represents a learning path from one language to another. Results are returned in a single page. Optionally filter by the source language (the language instruction is given in) using from_language.

Input
ParamTypeDescription
from_languagestringISO 639-1 language code for the source language (instruction language). Filters courses to only those taught from this language. Example: 'en' for English, 'es' for Spanish.
Response
{
  "type": "object",
  "fields": {
    "total": "integer total number of courses returned",
    "courses": "array of course objects with learning/from language details and learner counts"
  },
  "sample": {
    "data": {
      "total": 40,
      "courses": [
        {
          "phase": 3,
          "num_learners": 41959815,
          "from_language": "en",
          "learning_language": "es",
          "from_language_name": "English",
          "learning_language_name": "Spanish"
        },
        {
          "phase": 3,
          "num_learners": 22816034,
          "from_language": "en",
          "learning_language": "fr",
          "from_language_name": "English",
          "learning_language_name": "French"
        }
      ]
    },
    "status": "success"
  }
}

About the Duolingo API

The Duolingo API on Parse exposes 1 endpoint for the publicly available data on duolingo.com. Calls return JSON over HTTPS and are billed per successful response.

Pin a release with the API-Snapshot-Version header so canonical updates don't silently change your contract.