Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Nandini-13/PsycheIT/llms.txt

Use this file to discover all available pages before exploring further.

PsycheIT is designed to be stigma-free — students never need to register with a real name, email, or phone number. The two authentication endpoints together implement a fully anonymous identity system: /signup mints a unique userId derived from the student’s college code and returns a random password, while /login verifies those credentials against a bcrypt-hashed store and issues a short-lived JWT that the frontend uses to maintain session state.

POST /signup

Generate a new anonymous credential pair for a student. The returned userId and password are the only credentials that will ever exist for this account — there is no recovery mechanism.

Endpoint

POST /signup

Request Body

collegeCode
string
required
A short string identifying the student’s institution (e.g., SRMIST, IIT, BITS, VIT). This value becomes the prefix of the generated userId and is the only piece of institutional information the API collects.

Response Fields

userId
string
An auto-generated identifier in the format {collegeCode}_{timestamp}, where timestamp is the Unix epoch in milliseconds at the moment of signup. Example: SRMIST_1712345678901. This value is unique per signup call.
password
string
A randomly generated 8-character alphanumeric password produced via Math.random().toString(36).slice(-8). This password is returned in plaintext only once — it is not stored in plaintext anywhere on the server. Save it immediately.

Example Request

curl -X POST http://localhost:5000/signup \
  -H "Content-Type: application/json" \
  -d '{"collegeCode": "BITS"}'

Example Response

{
  "userId": "BITS_1712345678901",
  "password": "x7m2nq4p"
}

Error Responses

StatusBodyCause
400{ "error": "College code required" }The collegeCode field is missing.
Credentials are displayed only once at signup. The server never stores the plaintext password — only a bcrypt hash written at first login. If a student loses their userId or password, there is no recovery path. A new account must be created with another /signup call.

POST /login

Verify a credential pair and receive a signed JWT session token. On the very first login for a given userId, the password is hashed and persisted to users.json. Subsequent logins validate the submitted plaintext password against the stored hash.

Endpoint

POST /login

Request Body

userId
string
required
The userId returned by /signup. Example: BITS_1712345678901.
password
string
required
The plaintext password returned by /signup. This is compared against the bcrypt hash stored in users.json for existing accounts.

Response Fields

token
string
A signed JWT token (algorithm: HS256). The payload contains { userId, iat, exp }. The token expires 1 hour after issuance. Store it in localStorage and include it in subsequent API or frontend route calls as needed.

Example Request

curl -X POST http://localhost:5000/login \
  -H "Content-Type: application/json" \
  -d '{"userId": "BITS_1712345678901", "password": "x7m2nq4p"}'

Example Response

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJCSVRTXzE3MTIzNDU2Nzg5MDEiLCJpYXQiOjE3MTIzNDU2NzksImV4cCI6MTcxMjM0OTI3OX0.example"
}

First vs. Subsequent Logins

ScenarioBehaviour
First loginNo record exists in users.json for this userId. The server bcrypt-hashes the submitted password (cost factor 10), saves the new user record, and returns a JWT.
Subsequent loginsThe stored bcrypt hash is loaded and bcrypt.compareSync(password, hash) is called. A valid password returns a fresh JWT; an invalid password returns 401.

Error Responses

StatusBodyCause
400{ "error": "User ID and Password required" }One or both of userId / password fields are missing.
401{ "error": "Invalid password" }The password does not match the stored bcrypt hash for an existing user.

Decoding the JWT

The JWT payload contains { userId, iat, exp }. The PsycheIT frontend decodes it client-side — without a library — using:
const payload = JSON.parse(atob(token.split('.')[1]));
console.log(payload.userId); // "BITS_1712345678901"
iat is the issued-at Unix timestamp and exp is the expiry timestamp (issued-at + 3600 seconds). The token is not verified on the server side in the current implementation — validation is the responsibility of the client.

Build docs developers (and LLMs) love