# REST API Documentation

**URL:** <https://discuss.openedx.org/t/rest-api-documentation/3001>\
**Category:** Build-Test-Release\
**Tags:** api\
**Created:** [August 18, 2020, 6:00pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001 "2020-08-18T18:00:06Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![jramnai](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/jramnai/32/87_2.png) [@jramnai](https://discuss.openedx.org/u/jramnai)\
**Post date:** [August 18, 2020, 6:00pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/1 "2020-08-18T18:00:06Z")

</div>

I am creating this topic so that we can have good documentation for all REST API endpoints which are currently available in the open edX platform.

> **Where can I find the REST API endpoint for user creation?**

I have seen this question very often on the discussion forum and on the slack channels. And yes, we have an [endpoint](https://github.com/edx/edx-platform/blob/open-release/juniper.master/openedx/core/djangoapps/user_authn/urls_common.py#L27#L28) for this.

Normally when anyone lookup for the API for open edX they (or me) end up with this link: [https://courses.edx.org/api-docs/](https://courses.edx.org/api-docs/). This link has APIs listed but some of the endpoints are missing (for example `user_api/v1/account/registration/`).

The foundation for the API documentation was laid by @nedbat

1. [REST API docs tooling pull request](https://discuss.openedx.org/t/rest-api-docs-tooling-pull-request/92)
2. [Improved API documentation](https://discuss.openedx.org/t/improved-api-documentation/318)

I have gone through [this PR](https://github.com/edx/edx-platform/pull/21207) which was merged previously but in `open-release/juniper.master` some of the changes made with this PR are removed (Don’t know why!).

In the last, I would say that it will be nice if we can have all the REST API endpoints under one roof (centralized).

I think we can start like this:

- Create new doc which will have endpoint, method, description (if we have), codebase location
- By codebase location, developers or maintainers will be able to get the required body parameters
- Then gradually we can add the body parameters and can go on if everything goes well

People, please suggest if you have any good ideas about this.

cc: @regis

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [August 18, 2020, 6:30pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/2 "2020-08-18T18:30:30Z")

</div>

Thanks for bringing this up. I would love to see more movement on this. I’m personally disappointed that I couldn’t make more progress.

> [@jramnai](#):
>
> Create new doc which will have endpoint, method, description (if we have), codebase location

What do you mean by “create new doc”? I’m strongly in favor of putting the words near the code, and using tooling to collect them and publish them. Are you thinking of something different than that?

---

<div class="post-metadata">

**Author:** ![regis](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/regis/32/2640_2.png) [@regis](https://discuss.openedx.org/u/regis)\
**Post date:** [August 19, 2020, 9:59am UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/3 "2020-08-19T09:59:33Z")

</div>

Thanks for the detailed info @jramnai!

(For background information: @jramnai came to the meetup of the BTR working group and mentioned this issue. I suggested that I could help fix it himself and get the fix merged upstream.)

What you need to do is to generate a new `docs/swagger.yaml` file that contains the documentation for the endpoints that you are interested in. To generate this file, run:

```
make swagger

```

Or equivalently:

```
DJANGO_SETTINGS_MODULE=docs.docs_settings python manage.py lms generate_swagger --generator-class=edx_api_doc_tools.ApiSchemaGenerator -o docs/swagger.yaml

```

Once this file has been generated, it will be converted to human-readable documentation by the following command, which is part of `make api-docs-sphinx`:

```
python docs/sw2sphinxopenapi.py docs/swagger.yaml docs/api/gen

```

So, basically, you need to figure out WHY the `/user_api/v1/account/registration` endpoint is not included in swagger.yaml, while the `/api/user/v1/me` is, for instance.

This class is documented in swagger.yaml: [https://github.com/edx/edx-platform/blob/2c33fc249de02f0c02da94e67b9a64c0f81c0468/openedx/core/djangoapps/user\_api/accounts/views.py#L124](https://github.com/edx/edx-platform/blob/2c33fc249de02f0c02da94e67b9a64c0f81c0468/openedx/core/djangoapps/user_api/accounts/views.py#L124)  
While this one isn’t: [https://github.com/edx/edx-platform/blob/2c33fc249de02f0c02da94e67b9a64c0f81c0468/openedx/core/djangoapps/user\_authn/views/register.py#L448](https://github.com/edx/edx-platform/blob/2c33fc249de02f0c02da94e67b9a64c0f81c0468/openedx/core/djangoapps/user_authn/views/register.py#L448)

To figure out the underlying issue, we need to look at the code of the `ApiSchemaGenerator` in edx\_api\_doc\_tools.conf\_utils: [https://github.com/edx/api-doc-tools/blob/589bb566b098a81b9ad8ff4797ff3b42ad77ccb4/edx\_api\_doc\_tools/conf\_utils.py#L152](https://github.com/edx/api-doc-tools/blob/589bb566b098a81b9ad8ff4797ff3b42ad77ccb4/edx_api_doc_tools/conf_utils.py#L152)

It appears that this generator returns only endpoints which start with “/api”. By setting a breakpoint in the `get_endpoints` method (with `import pdb; pdb.set_trace()`) we can observe that “/user\_api/v1/account/registration/” is in `endpoints`, but not in `subpoints`.

Do you start to see the underlying issue @jramnai? Do you understand how to resolve it?

---

<div class="post-metadata">

**Author:** ![jramnai](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/jramnai/32/87_2.png) [@jramnai](https://discuss.openedx.org/u/jramnai)\
**Post date:** [August 19, 2020, 1:22pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/4 "2020-08-19T13:22:40Z")

</div>

> [@nedbat](#):
>
> What do you mean by “create new doc”? I’m strongly in favor of putting the words near the code, and using tooling to collect them and publish them. Are you thinking of something different than that?

No, I am not thinking other than that but by “create new doc” my meaning was to include the remaining endpoints and generate the new doc.

> [@regis](#):
>
> Do you start to see the underlying issue @jramnai? Do you understand how to resolve it?

Yes, we need to change the `get_endpoints` method in such a way that it should return all the API endpoints not only which starts with “/api/” (correct me if I am wrong here)

I will try to come up with a solution.

Thanks for the help @regis.

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [August 19, 2020, 5:42pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/5 "2020-08-19T17:42:57Z")

</div>

The goal was to only document `/api/`, and for other endpoints that should be documented, add an “alias” in `/api/` so that they would be available in a unified namespace.

---

<div class="post-metadata">

**Author:** ![regis](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/regis/32/2640_2.png) [@regis](https://discuss.openedx.org/u/regis)\
**Post date:** [August 20, 2020, 6:29pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/6 "2020-08-20T18:29:01Z")

</div>

> [@nedbat](#):
>
> The goal was to only document `/api/` , and for other endpoints that should be documented, add an “alias” in `/api/` so that they would be available in a unified namespace.

Does that mean that we should create an alias in urls.py to document the user API?

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [August 20, 2020, 7:20pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/7 "2020-08-20T19:20:30Z")

</div>

That would be the way to do it, yes.

---

<div class="post-metadata">

**Author:** ![regis](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/regis/32/2640_2.png) [@regis](https://discuss.openedx.org/u/regis)\
**Post date:** [August 21, 2020, 8:15am UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/8 "2020-08-21T08:15:57Z")

</div>

@jramnai Do you see how you can implement this?

---

<div class="post-metadata">

**Author:** ![jramnai](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/jramnai/32/87_2.png) [@jramnai](https://discuss.openedx.org/u/jramnai)\
**Post date:** [August 21, 2020, 4:19pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/9 "2020-08-21T16:19:50Z")

</div>

```
url(r'^user_api/v1/account/registration/$', register.RegistrationView.as_view(),
    name="user_api_registration"),
url(r'^api/user_api/v1/account/registration/$', register.RegistrationView.as_view(),
    name="api_registration"), #alias

```

@regis, do you mean above by “create an alias in [urls.py](https://github.com/edx/edx-platform/blob/open-release/juniper.master/openedx/core/djangoapps/user_authn/urls_common.py#L27#L28)”?

---

<div class="post-metadata">

**Author:** ![regis](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/regis/32/2640_2.png) [@regis](https://discuss.openedx.org/u/regis)\
**Post date:** [August 21, 2020, 5:11pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/10 "2020-08-21T17:11:39Z")

</div>

Yes, something along those lines. I would also change the name of the deprecated url to something like “user\_api\_registration\_legacy”.  
You should do the same for the “user\_api/v1/account/login\_session/” url.  
Please test those changes and see if they work (i.e: modify the swagger.yaml file). If yes, then you should be ready to open a PR.

---

<div class="post-metadata">

**Author:** ![jramnai](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/jramnai/32/87_2.png) [@jramnai](https://discuss.openedx.org/u/jramnai)\
**Post date:** [August 22, 2020, 12:16pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/11 "2020-08-22T12:16:02Z")

</div>

Yes @regis, I am testing the changes. But I think we should not change its name as it is being used in many test cases and [here](https://github.com/edx/edx-platform/blob/open-release/juniper.master/openedx/core/djangoapps/user_authn/views/registration_form.py#L376), too.

> [@regis](#):
>
> It appears that this generator returns only endpoints which start with “/api”. By setting a breakpoint in the `get_endpoints` method (with `import pdb; pdb.set_trace()` ) we can observe that “/user\_api/v1/account/registration/” is in `endpoints` , but not in `subpoints` .

I tried this with debugger and `get_endpoints` method is **not returning 24 API endpoints**'cause they do not start with `/api/`. By adding alias we will have `registration` and `login_session` API endpoints in the API documentation but what about the rest of endpoints?

API endpoints which do not start with `/api/`:

```auto
'/api-admin/api/v1/api_access_request/',
'/courses/{course_id}/teams/',
'/courses/{course_id}/xblock/{usage_id}/view/{view_name}',
'/courses/yt_video_metadata',
'/create_account',
'/csrf/api/v1/token',
'/notifier_api/v1/users/',
'/notifier_api/v1/users/{id}/',
'/oauth2/login/',
'/support/enrollment/{username_or_email}',
'/support/manage_user/{username_or_email}',
'/verify_student/status/',
'/user_api/v1/account/login_session/',
'/user_api/v1/account/password_reset/',
'/user_api/v1/account/registration/',
'/user_api/v1/forum_roles/{name}/users/',
'/user_api/v1/preferences/time_zones/',
'/user_api/v1/preferences/email_opt_in/',
'/user_api/v1/users/',
'/user_api/v1/users/{id}/',
'/user_api/v1/user_prefs/{id}/',
'/user_api/v1/user_prefs/',
'/zendesk_proxy/v0',
'/zendesk_proxy/v1',

```

If we do not have any strong reason to keep startswith `/api/` condition in `get_endpoints` method then we should remove it and then it will return all the endpoints. But this will affect the unified namespace.

@nedbat & @regis, let me know your thoughts on above.

---

<div class="post-metadata">

**Author:** ![nedbat](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/nedbat/32/3317_2.png) [@nedbat](https://discuss.openedx.org/u/nedbat)\
**Post date:** [August 25, 2020, 4:43pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/12 "2020-08-25T16:43:44Z")

</div>

We want the REST API to become more uniform and disciplined. Insisting on the `/api/` namespace is one way to do that. The [REST API Conventions](https://openedx.atlassian.net/wiki/spaces/AC/pages/18350757/edX+REST+API+Conventions) clearly indicate using the `/api/` namespace.

---

<div class="post-metadata">

**Author:** ![regis](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/regis/32/2640_2.png) [@regis](https://discuss.openedx.org/u/regis)\
**Post date:** [August 29, 2020, 1:37pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/13 "2020-08-29T13:37:07Z")

</div>

> [@jramnai](#):
>
> Yes @regis, I am testing the changes. But I think we should not change its name as it is being used in many test cases and [here](https://github.com/edx/edx-platform/blob/open-release/juniper.master/openedx/core/djangoapps/user_authn/views/registration_form.py#L376), too.

I understand. My point was that the new url should have the “user\_api\_registration” while the older url should be renamed to “user\_api\_registration\_legacy”. That way, all calls to `reverse("user_api_registration")` will point to the new url – which is good.

> [@jramnai](#):
>
> If we do not have any strong reason to keep startswith `/api/` condition in `get_endpoints` method then we should remove it and then it will return all the endpoints. But this will affect the unified namespace.

As Ned explained, we do want all API urls to start with /api. If you are interested in documenting some of these endpoints, then you can apply the same procedure for those endpoints. All those changes can go in a single pull request.

@jramnai: Does that answer your questions? Do you have what it takes to proceed with opening a PR?

---

<div class="post-metadata">

**Author:** ![regis](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/regis/32/2640_2.png) [@regis](https://discuss.openedx.org/u/regis)\
**Post date:** [September 16, 2020, 3:14pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/14 "2020-09-16T15:14:16Z")

</div>

@jramnai Did you create a PR? Do you need help?

---

<div class="post-metadata">

**Author:** ![jramnai](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/jramnai/32/87_2.png) [@jramnai](https://discuss.openedx.org/u/jramnai)\
**Post date:** [September 16, 2020, 3:28pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/15 "2020-09-16T15:28:45Z")

</div>

No, @regis. But I will open one by this weekend, was extremely busy this days.

I will let you know if I need any help.

Thanks.

---

<div class="post-metadata">

**Author:** ![jramnai](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/jramnai/32/87_2.png) [@jramnai](https://discuss.openedx.org/u/jramnai)\
**Post date:** [September 18, 2020, 4:02pm UTC](https://discuss.openedx.org/t/rest-api-documentation/3001/16 "2020-09-18T16:02:30Z")

</div>

Hi @regis,

I have opened the [PR](https://github.com/edx/edx-platform/pull/25020) and added you as reviewer.

Let me know if I have missed anything or done anything wrong.
