V1.0 Stable

API Reference

Build powerful integrations with Jiroshi's professional LMS engine. Our REST API is designed for reliability, speed, and seamless multi-tenant operations.

Introduction

The Jiroshi REST API provides programmatic access to all core platform resources, including instructors, students, courses, enrollments, and related operational data. It is intended for building custom integrations, instructor-facing tools, internal services, and automated workflows on top of the Jiroshi platform.

The API follows standard REST conventions, uses JSON for all request and response payloads, and is versioned to ensure backward compatibility as the platform evolves. Authentication, authorization, and rate limiting are enforced consistently across all endpoints.

This documentation describes the available endpoints, request/response formats, authentication mechanisms, error handling conventions, and operational constraints. All the API endpoints are subject to change as this is a MVP Version of the API and new platform capabilities will be introduced.

Active Base URL for Jiroshi V1

bash
https://api.jiroshi.com/api/v1/public

Base URL

All API requests should be made to https://api.jiroshi.com/api/v1/public

Note: Future versions will be exposed under separate versioned paths (for example,/api/v2/public).


API Keys

Jiroshi uses API keys to authenticate and authorize access to its REST API. API keys are scoped to your account and must be included with every request to protected endpoints.

You can create and manage API keys from the Jiroshi Dashboard. Each key pair consists of a Public Key (pk) and a Secret Key (sk), each intended for different security contexts.

Creating an API Key

To generate a new API key, navigate to the Manage API Keys section from the dashboard sidebar. On the Manage API Keys page:

  • Enter a meaningful name for the API key to identify its purpose.
  • Select an expiration period. Available options include 1 week, 1 month, 1 year, or never.
  • Generate the API key.

Important

The Public Key and Secret Key are displayed only onceat the time of creation. Make sure to copy and store them securely. Lost keys cannot be recovered and must be regenerated.

Public vs Secret Keys

Jiroshi distinguishes between public and secret API keys to enforce proper security boundaries:

  • Public Key (pk) - Safe to use in client-side applications such as web or mobile frontends. Required for all public-facing API calls.

    Sample Public Key (pk)

    bash
    pk:12a3b456-1ab2-3c45-4d67-21f72ad886f3:RK07B89pGD4J3-VypELpwDX4z1ZX0yF1R_0au6EZibU=
  • Secret Key (sk) - Must never be exposed on the frontend. Intended strictly for secure server-to-server operations, such as payment processing or privileged administrative actions.

    Sample Secret Key (sk)

    bash
    sk:12a3b456-1ab2-3c45-4d67-21f72ad886f3:RK07B89pGD4J3-VypELpwDX4z1ZX0yF1R_0au6EZibU=

Security Warning

Do not store or transmit secret keys in frontend code, public repositories, or client-side environments. Compromised secret keys can lead to irreversible account-level damage.

Current Usage

At present, all documented API endpoints require only the use of the Public Key (pk). While Secret Keys are not actively used in the current API surface, they are reserved for upcoming features and enhanced security-sensitive workflows.

Each API endpoint in this documentation is explicitly tagged to indicate whether it requires a pk or sk, allowing you to clearly distinguish frontend-safe and server-only operations.

Key Rotation Policy

Jiroshi does not enforce a key rotation policy. However, it is recommended to rotate your API keys periodically to enhance security.

Key Revocation Behavior

API keys are revokable. When a key is revoked, it is no longer valid and cannot be used to access the API. This ensures that compromised keys are quickly rendered ineffective.

API keys can be revoked from the Jiroshi Dashboard by simply deleting a particular key. It also gets revoked on expiration.

API Abuse policy

If API abuse is suspected, Jiroshi reserves the right to revoke API keys and take other measures to prevent abuse.


API Key Usage

All authenticated requests to the Jiroshi API must include a valid API key in the request headers. The API uses this key to identify the requesting account and to enforce access control rules.

API keys are passed using the x-api-keyheader. Requests missing this header or providing an invalid key will be rejected.

API Key Header

bash
x-api-key: <YOUR_API_KEY>

Key Validation Rules

The Jiroshi API performs strict validation on every API key provided with a request. A request will fail if any of the following conditions apply:

  • The API key is missing from the request headers.
  • The API key is malformed, invalid, or does not exist.
  • The API key has expired.
  • The API key type does not match the endpoint requirements (for example, using a Secret Key where a Public Key is expected, or vice versa).

API Key Errors

All errors related to API key authentication and validation use the standardized error codeAPI_KEY_ERR.

The HTTP status code and error message will vary depending on the failure scenario (for example, missing credentials, expired keys, or invalid key usage). Detailed information about response formats, error structures, and status codes is covered in a later section of this documentation.

Sample Error Response

json
{
  "status": false,
  "results": false,
  "message": "API key missing",
  "data": null,
  "error_code": "INVALID_TOKEN_ERR"
}

Retry Behavior & Best Practices

Requests that fail due to API key errors should not be retried automatically. These errors indicate a client-side configuration issue that must be resolved before the request can succeed.

  • Ensure the x-api-key header is present.
  • Verify that the correct API key type (pk or sk) is being used.
  • Confirm that the API key has not expired or been revoked.
  • Rotate the API key immediately if compromise is suspected.

Retrying the same request with an invalid API key will always result in failure.

Rate Limiting & API Keys

API requests are rate-limited on a per-API-key basis to protect the platform and ensure fair usage across accounts.

  • Requests exceeding the allowed rate are rejected with an appropriate HTTP status code.
  • Exceeding a rate limit does not revoke or invalidate the API key.
  • Clients should implement exponential backoff before retrying requests.
  • Rate limits may vary based on API key type, endpoint category, and account configuration.

Response Format

All Jiroshi API responses follow a consistent, envelope-based JSON structure. This applies to both successful and failed requests, allowing clients to reliably parse and handle responses across all endpoints.

Standard Response Structure

json
{
  "status": true,
  "results": true,
  "message": "Success",
  "data": {
    "id": "c1a2b3d4-e89b-12d3-a456-426614174000",
    "name": "Introduction to Backend Development",
    "is_active": true,
    "created_at": "2025-01-12T10:42:31Z"
  },
  "error_code": null
}
  • status - Indicates whether the request was successfully processed (true) or failed (false).
  • results - Indicates whether thedata field is non-null.
  • message - A human-readable success or error message.
  • data - The response payload containing resource data.
  • error_code - A machine-readable error identifier, ornull for successful responses.

Paginated Response Structure

Endpoints that return collections use a paginated response format. Pagination metadata is included alongside the result set.

Paginated Response Structure

json
{
  "status": true,
  "results": true,
  "message": "Successfully Fetched",
  "data": {
    "results": [
      {
        "uuid": "a12f3c9b-4e91-44de-bf6a-9f1a2a6d90ab",
        "title": "Advanced Django Course",
        "description": "",
        "thumbnail": "<thumbnail_url>",
        "duration": "39600.9667",
        "created_at": "2025-10-02T14:20:11.544767Z",
        "is_enrolled": false
      },
      {
        "uuid": "a12f3c9b-4e91-44de-bf6a-9f1a2a6d90ab",
        "title": "Learn Python",
        "description": "",
        "thumbnail": "<thumbnail_url>",
        "duration": "15876.9667",
        "created_at": "2025-10-02T14:20:11.544767Z",
        "is_enrolled": false
      },
      {
        "uuid": "a12f3c9b-4e91-44de-bf6a-9f1a2a6d90ab",
        "title": "Learn JavaScript",
        "description": "",
        "thumbnail": "<thumbnail_url>",
        "duration": "15876.9667",
        "created_at": "2025-10-02T14:20:11.544767Z",
        "is_enrolled": false
      }
    ],
    "pagination": {
      "count": 3,
      "total_pages": 1,
      "current_page": 1,
      "next": null,
      "previous": null
    }
  },
  "error_code": null
}
  • results - A list of resource objects for the current page.
  • pagination - Metadata used to navigate large result sets.

Error Response Structure

Error responses use the same envelope structure, withstatus andresults set tofalse,data set tonullor maybe some structured error, and a non-nullerror_code.

Sample Error Response

json
{
  "status": false,
  "results": false,
  "message": "API key missing",
  "data": null,
  "error_code": "INVALID_TOKEN_ERR"
}

Error Codes

Jiroshi APIs use standardized error codes to help clients reliably identify and handle different failure scenarios. Error codes are string literals that remain consistent across API versions and environments, even if the human-readable error message changes.

Whenever an error occurs, the response includes a non-nullerror_code field along with an appropriate HTTP status code and message.

Data & Validation Errors

  • INTEGRITY_ERR - Database integrity constraint violations, such as foreign key or uniqueness mismatches.

    INTEGRITY_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "Database integrity error !",
      "data": null,
      "error_code": "INTEGRITY_ERR"
    }
  • VALIDATION_ERR - Invalid input data or failed validation rules based on the request payload.

    VALIDATION_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "API key missing",
      "data": null,
      "error_code": "VALIDATION_ERR"
    }

Authentication & Authorization Errors

  • API_KEY_ERR - Issues related to API key authentication, including missing, invalid, malformed, or expired API keys.

    API_KEY_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "API key missing",
      "data": null,
      "error_code": "API_KEY_ERR"
    }
  • INVALID_TOKEN_ERR - Student authentication failures due to missing, invalid, malformed, or expired access or refresh tokens.

    INVALID_TOKEN_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "Student not authenticated",
      "data": null,
      "error_code": "INVALID_TOKEN_ERR"
    }
  • ACCESS_DENIED_ERR - Unauthorized access attempts to resources that do not belong to the requesting tenant.

    ACCESS_DENIED_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "Access denied to this resource !",
      "data": null,
      "error_code": "ACCESS_DENIED_ERR"
    }

Resource State Errors

  • ALREADY_EXISTS_ERR - Attempt to create a resource that already exists.

    ALREADY_EXISTS_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "Record already exists !",
      "data": null,
      "error_code": "ALREADY_EXISTS_ERR"
    }
  • NOT_FOUND_ERR - Requested resource could not be found.

    NOT_FOUND_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "Record not found !",
      "data": null,
      "error_code": "NOT_FOUND_ERR"
    }

Server Errors

  • INTERNAL_ERR - An unhandled server-side exception. If this error is encountered, please report it with request details as soon as possible.

    INTERNAL_ERR

    json
    {
      "status": false,
      "results": false,
      "message": "Internal Server Error",
      "data": null,
      "error_code": "INTERNAL_ERR"
    }

Clients are strongly encouraged to rely onerror_code values and HTTP Response codes for programmatic error handling rather than parsing response messages, which are intended primarily for human readability.


Selections & Filters

Jiroshi APIs provide selection and filtering mechanisms to optimize data retrieval, reduce response payload size, and improve performance for data-intensive endpoints.

Selections

Selections allow clients to explicitly specify which fields should be returned in the response. This is particularly useful for list and retrieve APIs where returning the full object is unnecessary.

For example, when displaying a list of lessons where only the title and description are required, selections can be used to fetch only those fields.

Selections Query Parameter

bash
GET /courses/<course_id>/lessons/?selections=title,description
  • Only fields included in selectionsare returned in the response.
  • Selections are restricted to a predefined set of allowed fields per API.
  • Invalid or unsupported selection fields are silently ignored.
  • If no selections are provided, or all provided selections are invalid, the API returns all allowed fields by default.

Not all APIs support selections. Wherever supported, the list of allowed selectable fields is documented explicitly for that endpoint.

Filters (Listing APIs Only)

Listing APIs support a set of generic filters that allow clients to narrow down results based on search terms, ordering, and date ranges.

Search

To perform a generic search across all searchable fields, use thesearch query parameter.

Generic Search

bash
GET /courses/?search=backend

Field-specific searches can also be performed by using the field name directly as a query parameter.

Field-Specific Search

bash
GET /courses/?title=django

Searchable fields vary by API and are documented individually for each endpoint.

Ordering

All listing APIs apply a default ordering of-created_at(descending by creation time).

This behavior can be overridden using theordering query parameter.

Ordering Examples

bash
# Ascending order by duration
GET /courses/?ordering=duration

# Descending order by duration
GET /courses/?ordering=-duration

Date Range Filters

Date range filtering follows a consistent naming convention for all supported date fields.

  • <field>_after - Filters records after the specified date.
  • <field>_before - Filters records before the specified date.

Date Range Filter Example

bash
GET /courses/?created_at_after=2025-01-01T00:00:00Z&created_at_before=2025-01-31T23:59:59Z

Important: All date values must be provided in UTC format.


Get Instructor Profile

GET
public Key
GET
/instructor/profile/
Retrieves the profile details of the authenticated instructor. This endpoint returns basic account information along with the associated instructor profile metadata.
Selections: Not supported
Filters: Not supported

Response

json
{
  "status": true,
  "results": true,
  "message": "Instructor Profile Fetched !",
  "data": {
    "instructor": {
      "username": "demo.instructor",
      "email": "demo.instructor@mail.com",
      "country_code": "+91",
      "display_name": "Demo Instructor",
      "phone_number": "1234567890"
    },
    "profile": {
      "bio": "The bio for a test instructor.",
      "location": "Sector 1, State, Country",
      "profile_picture": "<profile_picture>"
    }
  },
  "error_code": null
}
Fields that can be null:
  • country_code
  • phone_number
  • bio
  • location
  • profile_picture

Get Instructor KPIs

GET
public Key
GET
/instructor/kpi/
Fetches key performance indicators (KPIs) for the authenticated instructor. This includes total counts and activity from the last 30 days for courses, signups, and enrollments.
Selections: Not supported
Filters: Not supported

Response

json
{
  "status": true,
  "results": true,
  "message": "KPIs Fetched !",
  "data": {
    "courses": {
      "total": 3,
      "in_last_thirty_days": 0
    },
    "signups": {
      "total": 4,
      "in_last_thirty_days": 4
    },
    "enrollments": {
      "total": 4,
      "in_last_thirty_days": 4
    }
  },
  "error_code": null
}
Notes:
  • total represents the all-time count for the metric.
  • in_last_thirty_days represents activity within the last 30 days, calculated using UTC timestamps.

Student Authentication (Introduction)

Jiroshi currently only supports standard JWT-based authentication mechanism for student authentication and session management. This flow is used for all student-facing actions such as sign-up, login, enrollment, and course access.

Upon successful authentication, a student is issued an access token and a refresh token. The access token is used to authenticate API requests, while the refresh token is used to obtain new access tokens when the current one expires.

All authentication APIs are accessed using the Public API Key (pk) of an instructor. When a student authenticates using an instructor’s public key, that student is permanently associated with the corresponding instructor tenant.

This tenant-based authentication model ensures strict isolation between instructors. Tokens issued under one instructor’s API key cannot be used to access resources belonging to another instructor.

Important

Student access and refresh tokens are always validated in the context of the instructor API key used during authentication. Cross-tenant token usage is not permitted.

Authentication Transport & Client Detection

Jiroshi adapts its authentication token handling based on the detected client environment to ensure maximum security while supporting multiple application types.

Browser-Based Clients

When a request is identified as originating from a browser environment, refresh tokens are issued and stored exclusively via HTTP-only cookies. These cookies are inaccessible to browser-side JavaScript and are automatically included in subsequent refresh requests by the browser.

In this mode, refresh tokens are never exposed in API responses or request payloads, significantly reducing the risk of token theft via XSS or client-side compromise.

Cross-Origin Requests

For the browser to include these secure cookies in cross-origin API requests, you must set credentials: 'include' (Fetch API) or withCredentials: true (Axios) in your request configuration.

Non-Browser Clients

For non-browser clients such as mobile applications, desktop clients, or backend services, refresh tokens are returned directly in the API response payload. Subsequent refresh requests must include the refresh token explicitly in the request body.

This mode is intended only for environments where secure storage of tokens is handled by the client platform itself.

Development Mode

During local development, strict cookie policies (SameSite, Secure) can sometimes hinder testing on localhost. You can switch to a developer-friendly mode by setting the following header:

Force Development Mode

bash
X-Client-Type: dev

Effect: In this mode, just like with non-browser clients, the refresh token is transported via the request and response payloads instead of cookies. This makes it easier to inspect and manage tokens manually during development.

Forcing API Mode

In certain edge cases-such as React Native or Electron-based applications-the client may be incorrectly detected as a browser. In such scenarios, token handling can be explicitly forced to API mode by setting the following request header:

Force API Client Mode

bash
X-Client-Type: non-browser

Restricted Usage

Forcing API mode bypasses browser-level protections and exposes refresh tokens directly to the client. This option should be used only when absolutely necessary and only in trusted environments. Misuse may lead to token leakage, unauthorized access, or account compromise.

Jiroshi reserves the right to introduce additional validation, restrictions, or rate limits on forced API mode usage to prevent abuse.


Student Signup

POST
public Key
POST
/students/signup/
Registers a new student under the authenticated instructor tenant. Upon successful signup, the student is authenticated immediately and issued access and refresh tokens based on the client environment.
The signup flow currently requires only an identifier and password. Additional student attributes may be introduced in future versions of the API.
Selections: Not supported
Filters: Not supported

Request Body

Signup Payload

json
{
  "identifier": "dummy@mail.com",
  "password": "12345678"
}
identifier is a flexible, tenant-defined unique identifier. It may represent an email address, mobile number, student ID, or any other identifier scheme required by the instructor.
Tip: You can use the Student Identifier Lookup endpoint to perform real-time, debounced availability checks for the identifier during the signup flow.

Server-Side Validation Rules

Server-side Validations

The server performs only minimal validation during signup:
  • The identifier must be unique within the instructor tenant.
  • identifier length must be between 1 and 255 characters.
  • password length must be between 8 and 72 characters.

All additional identifier validation (format, pattern, semantics) must be enforced on the client side.
Passwords are securely hashed and never stored or transmitted in plain text.

Response (Browser Environment)

Browser Response

json
{
  "access_token": "<access_token>"
}
In browser environments, the refresh token is issued via an HTTP-only cookie and is not accessible to client-side JavaScript.

Cross-Origin Requests

For the browser to include these secure cookies in cross-origin API requests, you must set credentials: 'include' (Fetch API) or withCredentials: true (Axios) in your request configuration.

Response (Non-Browser / Dev Mode / Forced API Mode)

API Client Response

json
{
  "access_token": "<access_token>",
  "refresh_token": "<refresh_token>"
}
For non-browser clients (mobile, desktop, server-side applications) or when API mode is explicitly forced, both access and refresh tokens are returned in the response payload.
The exact token transport behavior depends on client detection and headers, as described in the Authentication Transport and Client Detection section.

Student Login

POST
public Key
POST
/students/login/
Authenticates an existing student under the authenticated instructor tenant. Upon successful login, the student is issued new access and refresh tokens based on the client environment.
This endpoint mirrors the signup authentication flow and differs only in that it validates existing credentials instead of creating a new student record.
Selections: Not supported
Filters: Not supported

Request Body

Login Payload

json
{
  "identifier": "muteen@mail.com",
  "password": "12345678"
}
The identifier must match the value used during signup and must be unique within the instructor tenant.

Response (Browser Environment)

Browser Response

json
{
  "access_token": "<access_token>"
}
In browser environments, the refresh token is issued via an HTTP-only cookie and is not accessible to client-side JavaScript.

Cross-Origin Requests

For the browser to include these secure cookies in cross-origin API requests, you must set credentials: 'include' (Fetch API) or withCredentials: true (Axios) in your request configuration.

Response (Non-Browser / Dev Mode / Forced API Mode)

API Client Response

json
{
  "access_token": "<access_token>",
  "refresh_token": "<refresh_token>"
}
For non-browser clients or when API mode is explicitly forced, both access and refresh tokens are returned in the response payload.
Token transport behavior follows the same rules described in the Authentication section.

Student Refresh Access Token

POST
public Key
POST
/students/refresh-token/
Issues a new access token by validating a refresh token. On every successful refresh, a new refresh token is also issued and the previous refresh token is immediately invalidated.
This endpoint is used to maintain authenticated sessions without requiring the student to re-enter credentials.
Selections: Not supported
Filters: Not supported

Request Body (Browser Environment)

No request body is required when the client is detected as a browser. The refresh token is automatically extracted from an HTTP-only cookie.

Cross-Origin Requests

For the browser to include these secure cookies in cross-origin API requests, you must set credentials: 'include' (Fetch API) or withCredentials: true (Axios) in your request configuration.

Request Body (Non-Browser / Dev Mode / Forced API)

Refresh Token Payload

json
{
  "refresh_token": "<refresh_token>"
}
For non-browser clients, the refresh token must be explicitly provided in the request body.

Response (Browser Environment)

Browser Response

json
{
  "access_token": "<new_access_token>"
}
A new refresh token is issued via an HTTP-only cookie. The previous refresh token becomes invalid immediately after rotation.

Response (Non-Browser / Dev Mode / Forced API)

API Client Response

json
{
  "access_token": "<new_access_token>",
  "refresh_token": "<new_refresh_token>"
}
In API mode, both the new access token and rotated refresh token are returned in the response payload.

Token Lifetime & Rotation Rules

1. Token Lifetimes

  • Access tokens: 15 minutes
  • Refresh tokens: 7 days (sliding window)

2. Rotation Policy (Important)

Jiroshi implements strict Refresh Token Rotation. Every time a refresh token is used to get a new access token, a new refresh token is issued in the response.

  • You must replace the old refresh token with the new one immediately.
  • The old refresh token becomes instantly invalid.

Security: Reuse Detection

Attempting to reuse an old/invalidated refresh token is treated as a security breach (potential token theft).

If a reused token is detected, the system will:
  • Immediately revoke the entire family of tokens (including the valid one).
  • Force the user to sign in again.

Student Logout

POST
public Key
POST
/students/logout/
Logs out the authenticated student by invalidating the active refresh token associated with the current session. All clients should call this endpoint to ensure tokens are blacklisted on the server.
For browser-based clients, the refresh token is stored in an HTTP-only cookie and is cleared automatically upon a successful logout. For Non-Browser clients and Dev Mode, the refresh token must be passed explicitly in the request body.
Selections: Not supported
Filters: Not supported

Authentication Requirements

A valid student access token must be provided to call this endpoint. The access token is used to identify the session being terminated.

Request Body

For Browser clients, no request body is required as the refresh token is picked up from the HTTP-only cookie.
For Non-Browser clients, Forced API Mode and Dev Mode, the refresh token must be provided in the request body to be blacklisted:

Logout Request Body (Non-Browser / Dev / Forced API Mode)

json
{
  "refresh_token": "<token>"
}

Client-Specific Behavior

  • Browser Clients: Calling this endpoint invalidates the refresh token stored in the HTTP-only cookie. You must set credentials: 'include' (Fetch) or withCredentials: true (Axios) to ensure the cookie is sent. Clients should also manually flush the access token from local storage.
  • Non-Browser & Dev Mode: These clients must call this endpoint passing the `refresh_token` in the request body. This blacklists the token to reduce the blast radius in case of compromise. Clients should then flush both access and refresh tokens from local storage.

Response

Logout Response

json
{
  "status": true,
  "results": true,
  "message": "Logged out successfully",
  "data": null,
  "error_code": null
}

Get Student Profile

GET
public Key
GET
/students/profile/
Retrieves basic profile information for the authenticated student. This endpoint requires a valid student access token.
At present, the student profile contains minimal data. As the platform evolves, additional profile attributes will be added to this response without changing the endpoint contract.
Selections: Not supported
Filters: Not supported

Authentication Requirements

A valid student access token must be provided in the request headers. Requests with expired or invalid tokens will fail.

Response

Student Profile Response

json
{
  "status": true,
  "results": true,
  "message": "Student Profile Fetched !",
  "data": {
    "uuid": "<student_uuid>",
    "identifier": "<student_identifier>"
  },
  "error_code": null
}
Notes:
  • This endpoint can be used to verify whether a student is currently authenticated.
  • If the access token is expired or invalid, the request will fail, indicating that re-authentication or token refresh is required.
  • Additional student profile fields will be added in future versions without breaking existing clients.

Update Student Account Details

PUT
public Key
PUT
/students/account/update/
Updates account-level details for the authenticated student. This endpoint can be used to update the student identifier and/or password.
For security reasons, all update operations require verification using the student’s current password.
Selections: Not supported
Filters: Not supported

Authentication Requirements

A valid student access token must be provided with the request. Requests without a valid token will be rejected.
Tip: You can use the Student Identifier Lookup endpoint to perform real-time, debounced availability checks for the identifier during the identifier update flow.

Request Body

Update Account Payload

json
{
  "identifier": "dummy@mail.com",
  "password": "1234567890",
  "current_password": "12345678"
}

Rules

  • At least one of identifier or passwordmust be provided.
  • current_password is mandatory for all update requests and is used to verify the authenticity of the request.
  • Identifier uniqueness is enforced within the instructor tenant.
  • Password updates follow the same length constraints as signup and login flows.

Response

Update Response

json
{
  "status": true,
  "results": true,
  "message": "Student account details updated !",
  "data": null,
  "error_code": null
}
If the update is successful, the new account details take effect immediately. Invalid credentials or failed validations will result in an authentication or validation error.

Student Identifier Lookup

POST
public Key
POST
/students/lookup/
Checks whether a student identifier already exists under the authenticated instructor tenant.
This is a lightweight helper endpoint intended for client-side validation and debounced availability checks. It does not authenticate a student or expose any student-specific data.
Selections: Not supported
Filters: Not supported

Request Body

Lookup Payload

json
{
  "identifier": "muteen@mail.com"
}
The identifier value must follow the same rules as used during signup and login. The lookup is scoped strictly to the current instructor tenant.

Response

Lookup Response

json
{
  "status": true,
  "results": true,
  "message": "Status fetched",
  "data": {
    "student_exists": true
  },
  "error_code": null
}
Notes:
  • student_exists indicates whether the identifier is already registered under the current instructor tenant.
  • This endpoint is suitable for debounced checks during signup or account update flows.
  • The lookup does not reveal any additional information about the student.
Support for additional lookup attributes may be introduced in future versions of the API.

List Courses

GET
public Key
GET
/courses/
Retrieves a paginated list of available courses under the instructor tenant. This endpoint supports selections, searching, ordering, date range filtering, and pagination.

Authenticated Student Use-Case (Important)

If a valid student access token is provided (from authorization header), the response also indicates whether the student is enrolled in each course or not viais_enrolled field. But if the student access token is expired or invalid, it will throw authentication error.

Now, if the access token is not provided with the request, theis_enrolledfield will be set tofalse for every course in the list.

Supported selectable fields:

NameTypeDescription
uuidstringThe unique identifier of the course.
titlestringThe title of the course.
descriptionstringThe description of the course.
thumbnailstringThe thumbnail URL of the course. (Image File)
durationstring (Seconds)The duration of the course IN SECONDS.
created_atstring (UTC Date)The creation date (IN UTC DATETIME FORMAT) of the course.
Note: The is_enrolled field is always included in the response and cannot be excluded via selections. Check Response.

Selections Usage Example

Selections Usage Example

http
GET /courses/?selections=uuid,title

Search Filter Query Params:

NameTypeDescription
searchstringSearches for a match in course titles or descriptions.
titlestringSearch courses by title

Search Filter Usage Example

Usage Example

http
GET /courses/?search=python

Ordering Fields:

NameTypeDescription
created_atstringOrders the results by created_at.
durationstringOrders the results by duration.

Ordering Usage Example

Usage Example

http
GET /courses/?ordering=created_at

Ordering usage Tip

Although already mentioned in 'Selections & Filters' section, it is important to note that, if you want to order the results in descending order, prefix the field name with a minus sign (-).

For example, to order the results by created_at in descending order, useordering=-created_at .

Note:

The default ordering is -created_at.

Date Range Filters:

NameTypeDescription
created_at_afterstringFilters the results to include only courses created after the specified date (IN UTC DATETIME FORMAT).
created_at_beforestringFilters the results to include only courses created before the specified date (IN UTC DATETIME FORMAT).

Date Range Filter Usage Example

Date Range Filter Usage Example

http
GET /courses/?created_at_after=2023-01-01&created_at_before=2023-12-31

Pagination

Pagination is supported and defaults to cursor-based pagination. Page-based pagination can be enabled explicitly usingpagination=pagein query params.

Response

Course List Response

json
{
  "status": true,
  "results": true,
  "message": "Successfully Fetched",
  "data": {
    "results": [
      {
        "uuid": "11111111-aaaa-bbbb-cccc-000000000001",
        "title": "Introduction to Backend Systems",
        "description": "Learn the fundamentals of backend development.",
        "thumbnail": "<course_thumbnail>",
        "duration": "12500.50",
        "created_at": "2025-01-10T10:00:00Z",
        "is_enrolled": false
      },
      {
        "uuid": "22222222-aaaa-bbbb-cccc-000000000002",
        "title": "Advanced API Design",
        "description": "Deep dive into scalable API architectures.",
        "thumbnail": "<course_thumbnail>",
        "duration": "42500.75",
        "created_at": "2025-01-05T08:30:00Z",
        "is_enrolled": true
      }
    ],
    "pagination": {
      "next": null,
      "previous": null,
      "next_cursor": null,
      "previous_cursor": null
    }
  },
  "error_code": null
}

Get Course Details

GET
public Key
GET
/courses/{courseUUID}/
Retrieves detailed information about a specific course.

Path Parameters

NameTypeRequiredDescription
courseUUIDstringYesThe unique identifier of the course.

Authenticated Student Use-Case (Important)

If a valid student access token is provided (from authorization header), the response also indicates whether the student is enrolled in each course or not viais_enrolled field. But if the student access token is expired or invalid, it will throw authentication error.

Now, if the access token is not provided with the request, theis_enrolledfield will be set tofalse for every course in the list.

Supported selectable fields:

NameTypeDescription
uuidstringThe unique identifier of the course.
titlestringThe title of the course.
descriptionstringThe description of the course.
thumbnailstringThe thumbnail URL of the course. (Image File)
durationstring (Seconds)The duration of the course IN SECONDS.
created_atstring (UTC Date)The creation date (IN UTC DATETIME FORMAT) of the course.
Note: The is_enrolled field is always included in the response and cannot be excluded via selections. Check Response.

Selections Usage Example

Selections Usage Example

http
GET /courses/{courseUUID}/?selections=uuid,title

Response

Response

json
{
  "status": true,
  "results": true,
  "message": "Successfully fetched !",
  "data": {
    "uuid": "11111111-aaaa-2222-bbbb-333333333333",
    "title": "Demo Course",
    "description": "Dummy description",
    "thumbnail": "<thumbnail_url>",
    "duration": "15900.9667",
    "created_at": "2025-10-02T14:20:11.544767Z",
    "is_enrolled": false
  },
  "error_code": null
}

List Course Lessons

GET
public Key
GET
/courses/{courseUUID}/lessons/
Retrieves a paginated list of available lessons under the given course for the tenant. This endpoint supports selections, searching, ordering, date range filtering, and pagination.

Note:

Access Token is NOT required to access this endpoint.

Path Parameters

NameTypeRequiredDescription
courseUUIDstringYesThe unique identifier of the course.

Supported selectable fields:

NameTypeDescription
uuidstringThe unique identifier of the lesson.
titlestringThe title of the lesson.
descriptionstringThe description of the lesson.
durationstring (Seconds)The duration of the lesson IN SECONDS.
created_atstring (UTC Date)The creation date (IN UTC DATETIME FORMAT) of the lesson.

Selections Usage Example

Selections Usage Example

http
GET /courses/{courseUUID}/lessons/?selections=uuid,title

Search Filter Query Params:

NameTypeDescription
searchstringSearches for a match in lesson titles or descriptions.
titlestringSearch lessons by title

Search Filter Usage Example

Usage Example

http
GET /courses/{courseUUID}/lessons/?search=python

Ordering Fields:

NameTypeDescription
created_atstringOrders the results by created_at.
durationstringOrders the results by duration.

Ordering Usage Example

Usage Example

http
GET /courses/{courseUUID}/lessons/?ordering=created_at

Ordering usage Tip

Although already mentioned in 'Selections & Filters' section, it is important to note that, if you want to order the results in descending order, prefix the field name with a minus sign (-).

For example, to order the results by created_at in descending order, useordering=-created_at .

Note:

The default ordering is -created_at.

Date Range Filters:

NameTypeDescription
created_at_afterstringFilters the results to include only lessons created after the specified date (IN UTC DATETIME FORMAT).
created_at_beforestringFilters the results to include only lessons created before the specified date (IN UTC DATETIME FORMAT).

Date Range Filter Usage Example

Date Range Filter Usage Example

http
GET /courses/{courseUUID}/lessons/?created_at_after=2023-01-01&created_at_before=2023-12-31

Pagination

Pagination is supported and defaults to cursor-based pagination. Page-based pagination can be enabled explicitly usingpagination=pagein query params.

Response

Lesson List Response

json
{
  "status": true,
  "results": true,
  "message": "Successfully Fetched",
  "data": {
    "results": [
      {
        "uuid": "11111111-1111-1111-1111-111111111111",
        "title": "Lesson 1",
        "description": "Description 1",
        "duration": "860.9667",
        "created_at": "2025-10-24T06:01:10.463300Z"
      },
      {
        "uuid": "22222222-2222-2222-2222-222222222222",
        "title": "Lesson 2",
        "description": "Description 2",
        "duration": "860.9667",
        "created_at": "2025-10-24T06:10:09.708923Z"
      },
      {
        "uuid": "33333333-3333-3333-3333-333333333333",
        "title": "Lesson 3",
        "description": "Description 3",
        "duration": "650.0000",
        "created_at": "2025-10-28T06:12:18.083998Z"
      },
      {
        "uuid": "44444444-4444-4444-4444-444444444444",
        "title": "Lesson 4",
        "description": "Description 4",
        "duration": "860.9667",
        "created_at": "2025-10-28T18:49:19.128782Z"
      },
      {
        "uuid": "55555555-5555-5555-5555-555555555555",
        "title": "Lesson 5",
        "description": "Description 5",
        "duration": "860.9667",
        "created_at": "2025-10-30T18:17:24.966641Z"
      },
      {
        "uuid": "66666666-6666-6666-6666-666666666666",
        "title": "Lesson 6",
        "description": "Description 6",
        "duration": "920.6873",
        "created_at": "2025-10-31T19:10:51.296300Z"
      }
    ],
    "pagination": {
      "next": null,
      "previous": null,
      "next_cursor": null,
      "previous_cursor": null
    }
  },
  "error_code": null
}

Enroll Student to Course

POST
public Key
POST
/courses/enroll/
Enrolls the authenticated student into a specified course, making the course content accessible to the student.
The current enrollment flow is intentionally minimal and does not enforce advanced eligibility or payment checks. As the platform evolves and payment workflows are introduced, this endpoint will be extended with stricter validation and access controls.

We'll eventually make the use of secret key (sk) mandatory for this endpoint.

Selections: Not supported
Filters: Not supported

Authentication Requirements

  • A valid student access token is required to authenticate the student.
  • A valid instructor public API key (pk) must be provided with the request.

Request Body

Enrollment Payload

json
{
  "course_uuid": "aaaaaaaa-1111-bbbb-2222-cccccccccccc"
}
The course_uuid must reference an existing course under the instructor tenant.

Response

Enrollment Response

json
{
  "status": true,
  "results": true,
  "message": "Enrolled successfully !",
  "data": {
    "enrollment_id": "bbbbbbbb-bbbb-bbbb-cccc-dddddddddddd"
  },
  "error_code": null
}
Once enrolled, the student gains access to the course contents immediately.
Note:
  • Re-enrolling an already enrolled student may result in anALREADY_EXISTS_ERR.
  • Enrollment logic will be extended in future versions to support paid courses and additional validation rules.

Enrollment Error Response

json
{
  "status": false,
  "results": false,
  "message": "Student already enrolled !",
  "data": null,
  "error_code": "ALREADY_EXISTS_ERR"
}

Real-World Business Workflow (Recommended for Now)

Until built-in payments are available, tenants can choose to keep student signup and enrollment APIs private.

In this approach, the tenant first collects payment outside the platform and then creates the student account and enrolls the student manually using the API.

Students do not sign up or enroll on their own. Access is granted only after the tenant confirms payment.

Why this is useful

  • Ensures only paid students get access.
  • Gives full control to the tenant.
  • Works well for early launches and private batches.

Security note

Since public API keys can be misused, tenants should design access in a way where enrolling without payment does not expose valuable content.

Common ways to do this include using one common course, enrolling paid students into all courses, or keeping premium content behind additional checks.

This setup keeps the platform usable and safe until stronger payment checks are added.

Tenant himself/herself will be responsible for any payment security failures or any misconducts by students.

Get Lesson Details

GET
public Key
GET
/courses/{courseUUID}/lessons/{lessonUUID}/
Retrieves detailed information about a specific lesson.

Path Parameters

NameTypeRequiredDescription
courseUUIDstringYesThe unique identifier of the course.
lessonUUIDstringYesThe unique identifier of the lesson.
Note: Student access token is required to access this API. And student must be enrolled in the course to access this API.

Supported selectable fields:

NameTypeDescription
uuidstringThe unique identifier of the lesson.
titlestringThe title of the lesson.
descriptionstringThe description of the lesson.
durationstring (Seconds)The duration of the lesson IN SECONDS.
video_urlstringThe video URL of the lesson. (Video File)
created_atstring (UTC Date)The creation date (IN UTC DATETIME FORMAT) of the lesson.

Selections Usage Example

Selections Usage Example

http
GET /courses/{courseUUID}/lessons/{lessonUUID}/?selections=uuid,title

Response

Response

json
{
  "status": true,
  "results": true,
  "message": "Successfully fetched !",
  "data": {
    "uuid": "11111111-aaaa-2222-bbbb-333333333333",
    "title": "Demo Course",
    "description": "Dummy description",
    "duration": "15900.9667",
    "video_url": "<video_url>",
    "created_at": "2025-10-02T14:20:11.544767Z"
  },
  "error_code": null
}

Lesson Extra Resources

GET
public Key
GET
/courses/{courseUUID}/lessons/{lessonUUID}/resources/
Retrieves extra resources of a specific lesson like Files, Notes and Links.

Path Parameters

NameTypeRequiredDescription
courseUUIDstringYesThe unique identifier of the course.
lessonUUIDstringYesThe unique identifier of the lesson.
Note: Student access token is required to access this API. And student must be enrolled in the course to access this API.

Supported selectable resource fields:

NameTypeDescription
notesstringThe notes of the lesson.
related_linksstringThe related links of the lesson.

Supported selectable file fields:

NameTypeDescription
uuidstringThe unique identifier of the file.
titlestringThe title of the file.
file_sizestringThe file size (IN BYTES) of the file.
file_typestringThe file type of the file.
file_urlstringThe file URL of the file.
created_atstringThe creation date (IN UTC DATETIME FORMAT) of the file.

Selections Usage Example

Selections Usage Example

http
GET /courses/{courseUUID}/lessons/{lessonUUID}/resources/?selections=notes,related_links,title,file_size,file_url

Search Filter Query Params for File Resources:

NameTypeDescription
searchstringSearches for a match in lesson resource file titles or file_types.
titlestringSearch lesson resource files by title
file_typestringSearch lesson resource files by file_type

Search Filter Usage Example

Usage Example

http
GET /courses/{courseUUID}/lessons/{lessonUUID}/resources/?search=ebook

Ordering Fields for File Resources:

NameTypeDescription
created_atstringOrders file resources list by created_at.
file_sizestringOrders file resources list by file_size.

Ordering Usage Example

Usage Example

http
GET /courses/{courseUUID}/lessons/{lessonUUID}/resources/?ordering=created_at

Ordering usage Tip

Although already mentioned in 'Selections & Filters' section, it is important to note that, if you want to order the results in descending order, prefix the field name with a minus sign (-).

For example, to order the results by created_at in descending order, useordering=-created_at .

Note:

The default ordering is -created_at.

Date Range Filters:

NameTypeDescription
created_at_afterstringFilters the results to include only file resources created after the specified date (IN UTC DATETIME FORMAT).
created_at_beforestringFilters the results to include only file resources created before the specified date (IN UTC DATETIME FORMAT).

Date Range Filter Usage Example

Date Range Filter Usage Example

http
GET /courses/{courseUUID}/lessons/{lessonUUID}/resources/?created_at_after=2023-01-01&created_at_before=2023-12-31

Pagination

Pagination is applied to the list of file resources. Pagination is supported and defaults to cursor-based pagination. Page-based pagination can be enabled explicitly usingpagination=pagein query params.

Response

Response

json
{
  "status": true,
  "results": true,
  "message": "Successfully Fetched",
  "data": {
    "notes": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec metus nec ante feugiat finibus. Nullam nec metus nec ante feugiat finibus.",
    "related_links": [
      {
        "url": "https://chatgpt.com/",
        "title": "ChatGPT"
      }
    ],
    "results": [
      {
        "uuid": "11111111-aaaa-2222-bbbb-333333333333",
        "title": "Dummy ref material",
        "file_size": 8130,
        "file_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "file_url": "<file_url>",
        "created_at": "2025-10-31T19:11:27.180036Z"
      },
      {
        "uuid": "11111111-cccc-2222-dddd-333333333333",
        "title": "Dummy ref material 2",
        "file_size": 6130,
        "file_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "file_url": "<file_url>",
        "created_at": "2025-10-31T19:11:27.180036Z"
      }
    ],
    "pagination": {
      "next": null,
      "previous": null,
      "next_cursor": null,
      "previous_cursor": null
    }
  },
  "error_code": null
}

Student Enrolled Courses

GET
public Key
GET
/courses/enrolled/
Retrieves a paginated list of courses that the student is enrolled in. This endpoint supports selections, searching, ordering, date range filtering, and pagination.
Note: Student access token is required to access this API. And student must be enrolled in the course to access this API.

Supported selectable fields:

NameTypeDescription
uuidstringThe unique identifier of the course.
titlestringThe title of the course.
descriptionstringThe description of the course.
thumbnailstringThe thumbnail URL of the course. (Image File)
durationstring (Seconds)The duration of the course IN SECONDS.
course_created_atstring (UTC Date)The creation date (IN UTC DATETIME FORMAT) of the course.
enrolled_atstring (UTC Date)The date (IN UTC DATETIME FORMAT) when the student enrolled in the course.

Selections Usage Example

Selections Usage Example

http
GET /courses/enrolled/?selections=uuid,title

Search Filter Query Params:

NameTypeDescription
searchstringSearches for a match in course titles or descriptions.
titlestringSearch courses by title

Search Filter Usage Example

Usage Example

http
GET /courses/enrolled/?search=python

Ordering Fields:

NameTypeDescription
course_created_atstringOrders the results by course_created_at.
durationstringOrders the results by duration.
enrolled_atstringOrders the results by enrolled_at.

Ordering Usage Example

Usage Example

http
GET /courses/enrolled/?ordering=course_created_at

Ordering usage Tip

Although already mentioned in 'Selections & Filters' section, it is important to note that, if you want to order the results in descending order, prefix the field name with a minus sign (-).

For example, to order the results by created_at in descending order, useordering=-created_at .

Note:

The default ordering is -enrolled_at.

Date Range Filters:

NameTypeDescription
created_at_afterstringFilters the results to include only courses created after the specified date (IN UTC DATETIME FORMAT).
created_at_beforestringFilters the results to include only courses created before the specified date (IN UTC DATETIME FORMAT).
enrolled_at_afterstringFilters the results to include only courses enrolled after the specified date (IN UTC DATETIME FORMAT).
enrolled_at_beforestringFilters the results to include only courses enrolled before the specified date (IN UTC DATETIME FORMAT).

Date Range Filter Usage Example

Date Range Filter Usage Example

http
GET /courses/enrolled/?enrolled_at_after=2023-01-01&enrolled_at_before=2023-12-31

Pagination

Pagination is supported and defaults to cursor-based pagination. Page-based pagination can be enabled explicitly usingpagination=pagein query params.

Response

Course List Response

json
{
  "status": true,
  "results": true,
  "message": "Successfully Fetched",
  "data": {
    "results": [
      {
        "uuid": "11111111-aaaa-bbbb-cccc-000000000001",
        "title": "Introduction to Backend Systems",
        "description": "Learn the fundamentals of backend development.",
        "thumbnail": "<course_thumbnail>",
        "duration": "12500.50",
        "course_created_at": "2025-11-01T06:41:03.008653Z",
        "enrolled_at": "2025-12-19T05:55:56.087766Z"
      },
      {
        "uuid": "22222222-aaaa-bbbb-cccc-000000000002",
        "title": "Advanced API Design",
        "description": "Deep dive into scalable API architectures.",
        "thumbnail": "<course_thumbnail>",
        "duration": "42500.75",
        "course_created_at": "2025-01-05T08:30:00Z",
        "enrolled_at": "2025-12-20T05:55:56.087766Z"
      }
    ],
    "pagination": {
      "next": null,
      "previous": null,
      "next_cursor": null,
      "previous_cursor": null
    }
  },
  "error_code": null
}