Self-hosted service
alfaarghya/alfa-leetcode-api avatar
alfaarghya/alfa-leetcode-api

alfa-leetcode-api puts documented REST endpoints in front of LeetCode GraphQL

It's a custom leetcode api. This API provides endpoints to retrieve details about a user's profile, badges, solved questions, contest details, contest history, submissions, calendar and and also daily questions, selected problem, list of problems.

836 stars332 forksTypeScriptMIT

At a glance

What is it?
alfa-leetcode-api is an Express and TypeScript service that wraps the undocumented leetcode.com GraphQL interface in JSON REST endpoints for profiles, submissions, contests and problem lists. It ships as a Docker image, a hosted instance and an MCP server, and it depends on an upstream interface nobody promises to keep.
Who is it for?
alfa-leetcode-api is worth adopting for a portfolio, a bot, a study dashboard or an agent integration that needs LeetCode profile and submission data without writing GraphQL queries, provided you are comfortable with a third party dependency on an interface LeetCode does not document.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 85 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap this fills is documentation, not capability

LeetCode has a GraphQL interface at leetcode.com/graphql, and the project description explains the motivation plainly: the author could not find proper documentation for it, and after reading various articles about the LeetCode public API still could not find the comprehensive documentation he was looking for. alfa-leetcode-api is the result of that search.

So the value proposition is not a new data source. It is a described HTTP surface on top of an existing one, aimed at developers who want plain JSON over REST rather than a GraphQL client and a query they have to reverse engineer. The endpoints cover a user's profile, full profile, badges, solved count, contest participation, contest history, submissions, accepted submissions, submission calendar, skill stats, language stats and question progress, plus problem oriented routes for the daily question, a selected problem and a list of problems.

That makes it a natural fit for small tools. A profile card, a streak tracker, a bot that reports your weekly progress, or a coding agent that wants to look up a problem by slug. The repository also ships an MCP server directory and an MCP.md file, so the same data can be exposed to a model client rather than only to HTTP callers.

What it is not is an official LeetCode product, and the README does not present it as one.

Route shape: username parameters, limit and year query strings

The endpoint table in the README is the specification, and it is worth reading closely because the conventions are consistent. User-scoped routes take the username as a path segment.

bash
/:username
/:username/profile
/:username/badges
/:username/solved
/:username/contest
/:username/contest/history
/:username/submission
/:username/acSubmission
/:username/calendar
/:username/skill
/:username/language
/:username/progress

Three of those accept a query parameter. Submissions come in a default and a limited form, where the limited form takes the number of records you want.

bash
/:username/submission?limit=number
/:username/acSubmission?limit=7
/:username/calendar?year=2025

The problem routes are separate from the user routes and follow their own pattern. There is a daily route, a raw variant of it, a selected problem route taking a titleSlug, a raw variant of that, and a list of problems route.

bash
/daily
/daily/raw
/select?titleSlug=selected-question
/select/raw?titleSlug=selected-question

The raw variants are a small but telling design decision. The normal routes return the shaped, display ready payload, and the raw routes hand back the upstream response without the reshaping, so a caller who needs a field the wrapper does not map can still get to it. The README also notes that the selected problem route expects the slug selected-question, which reads like a placeholder value that the upstream daily selection fills in.

Express with a caching layer, a rate limiter and a Swagger spec

The package.json shows a TypeScript Express service. The dependency list gives the shape of the runtime: express for routing, cors for cross origin headers, express-rate-limit for throttling, apicache for response caching, axios for outbound HTTP, zod for validation, swagger-ui-express for serving the API documentation and the Model Context Protocol SDK for the MCP server. The repository also has a swagger.yaml file at the top level, which is the OpenAPI description of the service.

The scripts show the standard shape of a TypeScript Node service, compiled with tsc to dist and run from dist/index.js in production.

json
    "build": "tsc",
    "dev": "nodemon --exec ts-node src/index.ts",
    "start": "node dist/index.js",
    "test": "vitest run",
    "lint": "biome check . ",
    "mcp": "ts-node mcp/index.ts"

The lint and format tooling is Biome, with a biome.json in the root and husky plus lint-staged wired up for pre-commit hooks. The test setup is Vitest with supertest and msw in the dev dependencies, and there is a vitest.config.ts at the root alongside a tests directory.

This is a well equipped service for its size. The rate limiter and the cache are the two pieces that matter most operationally, since every request fans out to LeetCode and a shared public instance would otherwise be an easy way to get blocked.

Three ways to run it, from hosted URL to MCP server

The README publishes a hosted API URL, a Docker image, and the npm scripts cover local development.

bash
https://alfa-leetcode-api.onrender.com/

The image is on Docker Hub and is run with a single port mapping.

bash
docker run -p 3000:3000 alfaarghya/alfa-leetcode-api:2.0.4

For local work the Dockerfile has four stages. The base is node:24-alpine with a working directory of /app and the package manifests copied in. Development installs everything and runs the dev script. Build installs with ci and compiles. Production installs with ci, omits dev dependencies and scripts, copies the compiled dist from the build stage plus swagger.yaml, and starts the compiled entry point. The dev and prod stages expose port 3000.

bash
FROM node:24-alpine AS prod
RUN npm ci --omit=dev --ignore-scripts
COPY --from=build /app/dist ./dist
COPY swagger.yaml ./
EXPOSE 3000
CMD ["node", "dist/index.js"]

The compose file mounts the working tree into the container for hot reload with polling enabled through two environment variables, so the dev loop does not require a rebuild.

yaml
    environment:
      - CHOKIDAR_USEPOLLING=true
      - WATCHPACK_POLLING=true
    volumes:
      - .:/app
      - /app/node_modules

The MCP entry point is separate and can be run with npm run mcp, with npm run mcp:dist for the compiled version and npm run mcp:inspect to open the inspector.

The dependency on an undocumented upstream is the real limitation

Every endpoint here is a translation of a call into leetcode.com/graphql. That is the project's value and also its constraint. The upstream interface is not publicly documented, which was the original complaint, and an undocumented interface can change shape without notice. A wrapper can absorb a schema change only if someone notices and updates it, and the repository's own release history shows how that cadence works in practice.

The releases are tightly clustered. v2.0.2, v2.0.3 and v2.0.4 all shipped on 2026-04-16, minutes apart, and the last push to the repository was on 2026-08-02. The project is not archived, and the recent dates are a fair signal that it is being worked on, but the gap between the last release and the last push is the number to keep in mind, and the clustered patch releases look like a response to an upstream change rather than a steady release train.

A second limit is the shared instance. The public URL is a single shared deployment, and the service has a rate limiter built in. Depending on someone else's hosted instance for anything user facing means depending on their quota and their uptime.

And there is the licence inconsistency worth resolving early. The repository shows an MIT badge, there is a LICENSE file at the top level, and the repository is described as MIT licensed, but the package.json license field reads ISC.

How it compares to writing GraphQL queries yourself

The alternative is not another REST wrapper, it is the direct route: send a GraphQL query to leetcode.com/graphql yourself and parse the result. That approach gives you complete control over the fields you request and no third party in the path, but you have to learn the schema, handle authentication and session behaviour yourself, and keep the query in step with an interface that is not documented.

The wrapper inverts that trade. You get JSON over HTTP with named routes, a Swagger spec, caching, throttling and a set of endpoints that already answer the common questions. What you give up is control over the exact upstream fields, and any need for a field the wrapper does not expose, though the raw routes exist precisely for that case.

A third option is to skip LeetCode data entirely if the goal is a practice dashboard, since the submission calendar and problem list data can be produced locally by a service you control. But if you specifically want the LeetCode profile of a real account, this API is the shortcut.

For agent workloads the MCP server is the differentiator rather than the REST layer, since a model client can query profiles and problems through a tool interface instead of an HTTP call.

Editorial conclusion

alfa-leetcode-api is worth adopting for a portfolio, a bot, a study dashboard or an agent integration that needs LeetCode profile and submission data without writing GraphQL queries, provided you are comfortable with a third party dependency on an interface LeetCode does not document. It is the wrong choice for a production service that needs a stable contract, rate limit headroom or a support commitment, because the API is a wrapper over leetcode.com/graphql and and nothing in the repository promises that upstream will stay stable. Before adopting, read swagger.yaml for the endpoint list, run the Docker image on port 3000 to confirm the shape of the responses you need, and settle the licence question yourself: the repository carries an MIT badge and a LICENSE file while the package.json license field reads ISC.

Frequently asked questions

How do I run alfa-leetcode-api locally?

The Dockerfile exposes port 3000 and the image can be started with docker run -p 3000:3000 alfaarghya/alfa-leetcode-api:2.0.4. For local development the package scripts offer npm run dev with nodemon and ts-node, and npm run build followed by npm start to run the compiled output.

Which endpoints does alfa-leetcode-api expose?

User routes take a username path segment and cover profile, full profile, badges, solved, contest, contest history, submission, accepted submission, calendar, skill, language and progress. Problem routes cover /daily, /daily/raw, /select with a titleSlug query, a raw variant of select, and a list of problems route.

What licence is alfa-leetcode-api released under?

The repository carries an MIT badge and a LICENSE file at the root, and the repository is described as MIT licensed, but the license field in package.json reads ISC. Check both files before redistributing the code.

Does alfa-leetcode-api support MCP?

Yes. The repository has an mcp directory and an MCP.md file, and the package scripts include mcp, mcp:dist and mcp:inspect, with the Model Context Protocol SDK listed as a dependency.

Is alfa-leetcode-api safe to depend on in production?

It wraps the undocumented leetcode.com/graphql interface, so its behaviour depends on an upstream that carries no compatibility promise. The service itself has caching through apicache and throttling through express-rate-limit, and the shared hosted instance at https://alfa-leetcode-api.onrender.com/ adds another dependency on a third party deployment.

Official sources

  1. alfaarghya/alfa-leetcode-api on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/alfaarghya-alfa-leetcode-api.svg)](https://hysenlabs.com/projects/alfaarghya-alfa-leetcode-api)

Was this useful?