# Duolingo Profile & Streak API
> Live public profile and language-learning stats from Duolingo, the world's largest language-learning platform — no key, nothing stored. This is the gamified-learning social view: a learner's XP, daily streak, courses and progress, distinct from every other social platform in the catalogue. The user endpoint returns a profile summary — display name, bio, location, join date, total XP, the current daily streak, the language being learned and the from-language, the current course, Super/Plus status and a course count. The courses endpoint returns the per-language breakdown: every course the learner studies with its title, learning and from languages, XP earned and crown count. The streak endpoint returns the streak detail — the current streak length and, when the learner makes it public, the streak start date and longest streak. Lookup is by username; the official mascot account "duo" is always available. Build streak widgets, learning-accountability bots, language-club leaderboards and profile cards on top of real Duolingo data. Private or non-existent usernames return a clean 404.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/duolingo-api/..."
```

## Pricing
- **Free** (Free) — 18,000 calls/Mo, 3 req/s
- **Starter** ($7/Mo) — 260,000 calls/Mo, 10 req/s
- **Pro** ($19/Mo) — 1,050,000 calls/Mo, 25 req/s
- **Scale** ($42/Mo) — 3,800,000 calls/Mo, 55 req/s

## Endpoints

### User

#### `GET /v1/user` — Profile summary — XP, streak, languages

**Parameters:**
- `username` (query, required, string) — Duolingo username Example: `duo`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/duolingo-api/v1/user?username=duo"
```

**Response:**
```json
{
    "data": {
        "bio": null,
        "name": "Vincent",
        "joined": "2011-12-09T23:17:32.000Z",
        "source": "Duolingo",
        "streak": 0,
        "country": null,
        "has_plus": true,
        "location": "Vancouver",
        "total_xp": 5889,
        "username": "duo",
        "has_picture": true,
        "course_count": 4,
        "from_language": "en",
        "current_course": "Japanese",
        "learning_language": "ja",
        "has_recent_activity": false
    },
    "meta": {
        "timestamp": "2026-06-12T01:42:39.948Z",
        "request_id": "d7c2616f-a888-479c-9129-201af131a2b3"
    },
    "status": "ok",
    "message": "User retrieved successfully",
    "success": true
}
```

### Courses

#### `GET /v1/courses` — Per-language course breakdown

**Parameters:**
- `username` (query, required, string) — Duolingo username Example: `duo`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/duolingo-api/v1/courses?username=duo"
```

**Response:**
```json
{
    "data": {
        "source": "Duolingo",
        "courses": [
            {
                "id": "DUOLINGO_FR_EN",
                "xp": 2463,
                "title": "French",
                "crowns": 9999,
                "is_current": false,
                "from_language": "en",
                "learning_language": "fr"
            },
            {
                "id": "DUOLINGO_JA_EN",
                "xp": 2340,
                "title": "Japanese",
                "crowns": 9999,
                "is_current": true,
                "from_language": "en",
                "learning_language": "ja"
            },
            {
                "id": "DUOLINGO_ES_EN",
                "xp": 916,
                "title": "Spanish",
                "crowns": 9999,
                "is_current": false,
                "from_language": "en",
                "learning_language": "es"
            },
            {
                "id": "DUOLINGO_DA_EN",
                "xp": 170,
                "title": "Danish",
                "crowns": 9999,
                "is_current": false,
                "from_language": "en",
                "learning_language": "da"
            }
        ],
        "total_xp": 5889,
        "username": "duo",
        "course_count": 4
    },
    "meta": {
        "timestamp": "2026-06-12T01:42:40.397Z",
        "request_id": "1f4694ed-165c-4c07-b083-fcaa9d359f5a"
    },
    "status": "ok",
    "message": "Courses retrieved successfully",
    "succ
…(truncated, see openapi.json for full schema)
```

### Streak

#### `GET /v1/streak` — Streak detail — length, longest

**Parameters:**
- `username` (query, required, string) — Duolingo username Example: `duo`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/duolingo-api/v1/streak?username=duo"
```

**Response:**
```json
{
    "data": {
        "source": "Duolingo",
        "streak": 0,
        "username": "duo",
        "current_streak_end": null,
        "longest_streak_end": null,
        "current_streak_start": null,
        "current_streak_length": 0,
        "longest_streak_length": null
    },
    "meta": {
        "timestamp": "2026-06-12T01:42:41.195Z",
        "request_id": "c994aaab-1dc3-4299-8195-6c6766c7add4"
    },
    "status": "ok",
    "message": "Streak retrieved successfully",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Service metadata

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/duolingo-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "note": "username is a Duolingo handle (try username=duo, the official mascot account). Private or non-existent usernames return 404. Some fields (longest streak, streak dates) are only present when the learner makes them public.",
        "source": "Duolingo public profile API (duolingo.com/2017-06-30/users, live)",
        "service": "duolingo-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/user": "Profile summary — XP, streak, languages, current course (username=duo).",
            "GET /v1/streak": "Streak detail — current length, start date, longest streak (username=duo).",
            "GET /v1/courses": "Per-language course breakdown with XP and crowns (username=duo)."
        },
        "description": "Live public profile and language-learning stats from Duolingo, the world's largest language-learning platform. The gamified-learning social view — a learner's XP, streak, courses and progress. user = profile summary (name, bio, location, join date, total XP, current daily streak, learning/from language, current course, Super/Plus status, course count); courses = the per-language breakdown (each course with title, languages, XP and crowns); streak = streak detail (current length and, when public, start date and longest streak). Live, no key, nothing stored. Lookup is by username.",
        "upstream_status": "ok"
    },
    "meta": {
        "timestamp": "2026-06-12T01:42:42.259Z",
        "requ
…(truncated, see openapi.json for full schema)
```

### Learners

#### `GET /v1/avatar` — A learner's avatar image URLs at several sizes

**Parameters:**
- `username` (query, required, string) — Duolingo username Example: `duo`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/duolingo-api/v1/avatar?username=duo"
```

**Response:**
```json
{
    "data": {
        "name": "Vincent",
        "sizes": {
            "large": "https://simg-ssl.duolingo.com/ssr-avatars/952/SSR-MFPmYmU4iE/large",
            "small": "https://simg-ssl.duolingo.com/ssr-avatars/952/SSR-MFPmYmU4iE/small",
            "xlarge": "https://simg-ssl.duolingo.com/ssr-avatars/952/SSR-MFPmYmU4iE/xlarge"
        },
        "source": "Duolingo",
        "username": "duo",
        "image_url": "https://simg-ssl.duolingo.com/ssr-avatars/952/SSR-MFPmYmU4iE/large"
    },
    "meta": {
        "timestamp": "2026-06-13T13:55:15.455Z",
        "request_id": "06944220-9055-4cd2-a844-e1440780ad91"
    },
    "status": "ok",
    "message": "Avatar retrieved successfully",
    "success": true
}
```


---
Marketplace page: https://www.oanor.com/api/duolingo-api
OpenAPI spec: https://www.oanor.com/api/duolingo-api/openapi.json
