{"info":{"_postman_id":"6456ed48-a00e-4afe-b291-5f582f432ba6","name":"SarahahApp API","description":"<html><head></head><body><h1 id=\"sarahahapp-api-documentation\">SarahahApp API Documentation</h1>\n<p>SarahahApp is an anonymous messaging platform built with <strong>Node.js</strong>, <strong>Express</strong>, <strong>MongoDB</strong>, and <strong>Redis</strong>.</p>\n<p>Users can create accounts, share their profile links, and receive anonymous messages — similar to the original Sarahah concept.</p>\n<hr>\n<h2 id=\"base-url\">Base URL</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>https://sarahah-app-back-end.vercel.app\n\n</code></pre><hr>\n<h2 id=\"authentication\">Authentication</h2>\n<p>This API uses <strong>JWT Tokens</strong>. After signing in, copy the <code>token</code> from the response and set it in the <code>token</code> header for all protected routes.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Header: token\nValue: &lt;your_jwt_token&gt;\n\n</code></pre><p>For refresh token, send the refresh token in:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Header: refreshtoken\nValue: &lt;your_refresh_token&gt;\n\n</code></pre><blockquote>\n<p><strong>Note:</strong> Each endpoint lists its exact requirements (header/body/query) in the description section. All token and ID values shown in requests are <strong>examples only</strong> — replace them with your actual values. </p>\n</blockquote>\n<hr>\n<h2 id=\"rate-limiting\">Rate Limiting</h2>\n<p>The API is rate-limited to <strong>50 requests per 15 minutes</strong> per IP address.</p>\n<hr>\n<h2 id=\"response-format\">Response Format</h2>\n<p>All responses follow this structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"message\": \"done!\",\n  \"data\": { ... }\n}\n\n</code></pre>\n<h2 id=\"error-format\">Error Format</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"message\": \"Error description\"\n}\n\n</code></pre>\n<h2 id=\"validation-error-format\">Validation Error Format</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"success\": false,\n  \"message\": \"Validation Error\",\n  \"errors\": [\"field error messages\"]\n}\n\n</code></pre>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[{"content":"SarahahApp API Documentation","slug":"sarahahapp-api-documentation"}],"owner":"49715513","collectionId":"6456ed48-a00e-4afe-b291-5f582f432ba6","publishedId":"2sBXiqFpZ5","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"publishDate":"2026-04-06T17:27:15.000Z"},"item":[{"name":"Auth","item":[{"name":"Sign Up","id":"f3a4ac91-b9cc-4cbe-8cd9-592ac6f5dddc","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[{"key":"userName","value":"Diaa Eldeen","description":"<p>Required. 3-30 chars. Letters, numbers, spaces, - and _ only.</p>\n","type":"text"},{"key":"email","value":"diaa@example.com","description":"<p>Required. Valid email address.</p>\n","type":"text"},{"key":"password","value":"password123","description":"<p>Required. Minimum 8 characters.</p>\n","type":"text"},{"key":"rePassword","value":"password123","description":"<p>Required. Must match password.</p>\n","type":"text"},{"key":"age","value":"22","description":"<p>Required. Minimum 18.</p>\n","type":"text"},{"key":"gender","value":"male","description":"<p>Optional. Enum: male | female</p>\n","type":"text"},{"key":"phone","value":"01012345678","description":"<p>Optional. Egyptian number format: 010, 011, 012, or 015 followed by 8 digits.</p>\n","type":"text"},{"key":"image","description":"<p>Optional. Profile picture. Allowed types: PNG, JPG, JPEG.</p>\n","type":"file","value":null,"disabled":true}]},"url":"https://sarahah-app-back-end.vercel.app/users/signup","description":"<p>Register a new user account.</p>\n<p>Sends a 6-digit OTP to the provided email for verification. OTP is valid for <strong>2 minutes</strong>.</p>\n<p>After signup, the account is NOT active until email is confirmed via the <strong>Confirm Email</strong> endpoint.</p>\n<blockquote>\n<p><strong>Note:</strong> This endpoint accepts <code>multipart/form-data</code> because of the optional profile picture upload.</p>\n</blockquote>\n<hr />\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Body (form-data)</td>\n<td><code>userName</code></td>\n<td><code>Diaa Eldeen</code></td>\n<td>Required. 3–30 chars. Letters, numbers, spaces, <code>-</code> and <code>_</code> only.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>email</code></td>\n<td><code>diaa@example.com</code></td>\n<td>Required. Valid email address.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>password</code></td>\n<td><code>password123</code></td>\n<td>Required. Minimum 8 characters.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>rePassword</code></td>\n<td><code>password123</code></td>\n<td>Required. Must match <code>password</code>.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>age</code></td>\n<td><code>22</code></td>\n<td>Required. Minimum 18.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>gender</code></td>\n<td><code>male</code></td>\n<td>Optional. Enum: <code>male</code> or <code>female</code>.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>phone</code></td>\n<td><code>01012345678</code></td>\n<td>Optional. Egyptian format: 010/011/012/015 + 8 digits.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>image</code></td>\n<td><em>(file)</em></td>\n<td>Optional. Profile picture. Allowed: PNG, JPG, JPEG.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p><strong>Content-Type:</strong> <code>multipart/form-data</code> (required because of file upload)</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["users","signup"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"255ea11f-cc57-4d81-8530-0d8a6de58fdd","name":"201 - Created","originalRequest":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[{"key":"userName","value":"Diaa Eldeen","description":"Required. 3-30 chars. Letters, numbers, spaces, - and _ only.","type":"text"},{"key":"email","value":"diaa@example.com","description":"Required. Valid email address.","type":"text"},{"key":"password","value":"password123","description":"Required. Minimum 8 characters.","type":"text"},{"key":"rePassword","value":"password123","description":"Required. Must match password.","type":"text"},{"key":"age","value":"22","description":"Required. Minimum 18.","type":"text"},{"key":"gender","value":"male","description":"Optional. Enum: male | female","type":"text"},{"key":"phone","value":"01012345678","description":"Optional. Egyptian number format: 010, 011, 012, or 015 followed by 8 digits.","type":"text"},{"key":"image","description":"Optional. Profile picture. Allowed types: PNG, JPG, JPEG.","type":"file","value":null,"disabled":true}]},"url":"https://sarahah-app-back-end.vercel.app/users/signup","description":"Register a new user account.\n\nSends a 6-digit OTP to the provided email for verification. OTP is valid for **2 minutes**.\n\nAfter signup, the account is NOT active until email is confirmed via the **Confirm Email** endpoint.\n\n> **Note:** This endpoint accepts `multipart/form-data` because of the optional profile picture upload.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Body (form-data) | `userName` | `Diaa Eldeen` | Required. 3–30 chars. Letters, numbers, spaces, `-` and `_` only. |\n| Body (form-data) | `email` | `diaa@example.com` | Required. Valid email address. |\n| Body (form-data) | `password` | `password123` | Required. Minimum 8 characters. |\n| Body (form-data) | `rePassword` | `password123` | Required. Must match `password`. |\n| Body (form-data) | `age` | `22` | Required. Minimum 18. |\n| Body (form-data) | `gender` | `male` | Optional. Enum: `male` or `female`. |\n| Body (form-data) | `phone` | `01012345678` | Optional. Egyptian format: 010/011/012/015 + 8 digits. |\n| Body (form-data) | `image` | *(file)* | Optional. Profile picture. Allowed: PNG, JPG, JPEG. |\n\n> **Content-Type:** `multipart/form-data` (required because of file upload)"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": {\n    \"_id\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n    \"userName\": \"Diaa Eldeen\",\n    \"email\": \"diaa@example.com\",\n    \"age\": 22,\n    \"gender\": \"male\",\n    \"provider\": \"system\",\n    \"confirmed\": null,\n    \"totalViews\": 0,\n    \"role\": \"user\",\n    \"createdAt\": \"2026-04-01T10:00:00.000Z\",\n    \"updatedAt\": \"2026-04-01T10:00:00.000Z\"\n  }\n}"},{"id":"317b80a0-0c09-419a-bd5a-973868db6278","name":"409 - User Already Exists","originalRequest":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[{"key":"userName","value":"Diaa Eldeen","description":"Required. 3-30 chars. Letters, numbers, spaces, - and _ only.","type":"text"},{"key":"email","value":"diaa@example.com","description":"Required. Valid email address.","type":"text"},{"key":"password","value":"password123","description":"Required. Minimum 8 characters.","type":"text"},{"key":"rePassword","value":"password123","description":"Required. Must match password.","type":"text"},{"key":"age","value":"22","description":"Required. Minimum 18.","type":"text"},{"key":"gender","value":"male","description":"Optional. Enum: male | female","type":"text"},{"key":"phone","value":"01012345678","description":"Optional. Egyptian number format: 010, 011, 012, or 015 followed by 8 digits.","type":"text"},{"key":"image","description":"Optional. Profile picture. Allowed types: PNG, JPG, JPEG.","type":"file","value":null,"disabled":true}]},"url":"https://sarahah-app-back-end.vercel.app/users/signup","description":"Register a new user account.\n\nSends a 6-digit OTP to the provided email for verification. OTP is valid for **2 minutes**.\n\nAfter signup, the account is NOT active until email is confirmed via the **Confirm Email** endpoint.\n\n> **Note:** This endpoint accepts `multipart/form-data` because of the optional profile picture upload.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Body (form-data) | `userName` | `Diaa Eldeen` | Required. 3–30 chars. Letters, numbers, spaces, `-` and `_` only. |\n| Body (form-data) | `email` | `diaa@example.com` | Required. Valid email address. |\n| Body (form-data) | `password` | `password123` | Required. Minimum 8 characters. |\n| Body (form-data) | `rePassword` | `password123` | Required. Must match `password`. |\n| Body (form-data) | `age` | `22` | Required. Minimum 18. |\n| Body (form-data) | `gender` | `male` | Optional. Enum: `male` or `female`. |\n| Body (form-data) | `phone` | `01012345678` | Optional. Egyptian format: 010/011/012/015 + 8 digits. |\n| Body (form-data) | `image` | *(file)* | Optional. Profile picture. Allowed: PNG, JPG, JPEG. |\n\n> **Content-Type:** `multipart/form-data` (required because of file upload)"},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User Already Exist\"\n}"},{"id":"cd8d1c3a-40dc-4104-b469-cdfe276f3d6a","name":"422 - Validation Error","originalRequest":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[{"key":"userName","value":"Diaa Eldeen","description":"Required. 3-30 chars. Letters, numbers, spaces, - and _ only.","type":"text"},{"key":"email","value":"diaa@example.com","description":"Required. Valid email address.","type":"text"},{"key":"password","value":"password123","description":"Required. Minimum 8 characters.","type":"text"},{"key":"rePassword","value":"password123","description":"Required. Must match password.","type":"text"},{"key":"age","value":"22","description":"Required. Minimum 18.","type":"text"},{"key":"gender","value":"male","description":"Optional. Enum: male | female","type":"text"},{"key":"phone","value":"01012345678","description":"Optional. Egyptian number format: 010, 011, 012, or 015 followed by 8 digits.","type":"text"},{"key":"image","description":"Optional. Profile picture. Allowed types: PNG, JPG, JPEG.","type":"file","value":null,"disabled":true}]},"url":"https://sarahah-app-back-end.vercel.app/users/signup","description":"Register a new user account.\n\nSends a 6-digit OTP to the provided email for verification. OTP is valid for **2 minutes**.\n\nAfter signup, the account is NOT active until email is confirmed via the **Confirm Email** endpoint.\n\n> **Note:** This endpoint accepts `multipart/form-data` because of the optional profile picture upload.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Body (form-data) | `userName` | `Diaa Eldeen` | Required. 3–30 chars. Letters, numbers, spaces, `-` and `_` only. |\n| Body (form-data) | `email` | `diaa@example.com` | Required. Valid email address. |\n| Body (form-data) | `password` | `password123` | Required. Minimum 8 characters. |\n| Body (form-data) | `rePassword` | `password123` | Required. Must match `password`. |\n| Body (form-data) | `age` | `22` | Required. Minimum 18. |\n| Body (form-data) | `gender` | `male` | Optional. Enum: `male` or `female`. |\n| Body (form-data) | `phone` | `01012345678` | Optional. Egyptian format: 010/011/012/015 + 8 digits. |\n| Body (form-data) | `image` | *(file)* | Optional. Profile picture. Allowed: PNG, JPG, JPEG. |\n\n> **Content-Type:** `multipart/form-data` (required because of file upload)"},"status":"Unprocessable Entity","code":422,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"success\": false,\n  \"message\": \"Validation Error\",\n  \"errors\": [\n    \"userName is required\",\n    \"Password must be at least 8 characters\"\n  ]\n}"}],"_postman_id":"f3a4ac91-b9cc-4cbe-8cd9-592ac6f5dddc"},{"name":"Sign Up With Google","id":"eb5b2fd2-cfcb-4511-9809-209362f5e7e8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"idToken\": \"<google_id_token_from_oauth>\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/gmail","description":"<p>Register or login using Google OAuth2.</p>\n<p>Pass the <strong>Google ID Token</strong> obtained from the Google Sign-In flow on the client side.</p>\n<p>If the user already exists with a system account (email/password), this will return an error asking them to use system login.</p>\n<p>If the user is new, a new account is created automatically with the Google profile data (name, picture, email).</p>\n<h2 id=\"how-to-get-the-id-token-frontend-use-google-sign-in-sdk-and-call-googleusergetauthresponseid_token\"><strong>How to get the ID Token (Frontend):</strong>\nUse Google Sign-In SDK and call <code>googleUser.getAuthResponse().id_token</code>.</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>idToken</code></td>\n<td><code>&lt;google_id_token&gt;</code></td>\n<td>Required. Google ID Token from the OAuth2 sign-in flow on the client side.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","signup","gmail"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"f0f02ab4-cd89-441e-9beb-f5e1fa7fd7dd","name":"200 - Login Successful","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"idToken\": \"<google_id_token_from_oauth>\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/gmail","description":"Register or login using Google OAuth2.\n\nPass the **Google ID Token** obtained from the Google Sign-In flow on the client side.\n\nIf the user already exists with a system account (email/password), this will return an error asking them to use system login.\n\nIf the user is new, a new account is created automatically with the Google profile data (name, picture, email).\n\n**How to get the ID Token (Frontend):**\nUse Google Sign-In SDK and call `googleUser.getAuthResponse().id_token`.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `idToken` | `<google_id_token>` | Required. Google ID Token from the OAuth2 sign-in flow on the client side. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"LogIn Succefully\",\n  \"data\": {\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n  }\n}"},{"id":"f40d15df-a870-4c5c-b04f-cd9d5520a08b","name":"400 - System Account Exists","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"idToken\": \"<google_id_token_from_oauth>\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/gmail","description":"Register or login using Google OAuth2.\n\nPass the **Google ID Token** obtained from the Google Sign-In flow on the client side.\n\nIf the user already exists with a system account (email/password), this will return an error asking them to use system login.\n\nIf the user is new, a new account is created automatically with the Google profile data (name, picture, email).\n\n**How to get the ID Token (Frontend):**\nUse Google Sign-In SDK and call `googleUser.getAuthResponse().id_token`.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `idToken` | `<google_id_token>` | Required. Google ID Token from the OAuth2 sign-in flow on the client side. |"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Please Log In In System Only\"\n}"}],"_postman_id":"eb5b2fd2-cfcb-4511-9809-209362f5e7e8"},{"name":"Confirm Email","id":"ee800b16-e696-4e02-a917-d5ae334ead58","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/confirm-email","description":"<p>Confirm the user's email address using the 6-digit OTP sent during signup.</p>\n<p>OTP expires after <strong>2 minutes</strong>. If expired, use the <strong>Resend OTP</strong> endpoint.</p>\n<h2 id=\"once-confirmed-the-account-becomes-active-and-can-be-used-to-sign-in\">Once confirmed, the account becomes active and can be used to sign in.</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>email</code></td>\n<td><code>diaa@example.com</code></td>\n<td>Required. The email used during Sign Up.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>otp</code></td>\n<td><code>123456</code></td>\n<td>Required. 6-digit OTP sent to the email. Valid for 2 minutes.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","signup","confirm-email"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"3762848b-14f9-4cbe-9dc6-3c6500055628","name":"200 - Email Confirmed","originalRequest":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/confirm-email","description":"Confirm the user's email address using the 6-digit OTP sent during signup.\n\nOTP expires after **2 minutes**. If expired, use the **Resend OTP** endpoint.\n\nOnce confirmed, the account becomes active and can be used to sign in.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. The email used during Sign Up. |\n| Body (JSON) | `otp` | `123456` | Required. 6-digit OTP sent to the email. Valid for 2 minutes. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Email confirmed Succefully!\",\n  \"data\": null\n}"},{"id":"bb8d0c1b-5c11-4904-adf9-0d945440d69f","name":"500 - OTP Expired","originalRequest":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/confirm-email","description":"Confirm the user's email address using the 6-digit OTP sent during signup.\n\nOTP expires after **2 minutes**. If expired, use the **Resend OTP** endpoint.\n\nOnce confirmed, the account becomes active and can be used to sign in.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. The email used during Sign Up. |\n| Body (JSON) | `otp` | `123456` | Required. 6-digit OTP sent to the email. Valid for 2 minutes. |"},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Otp Expired\"\n}"},{"id":"9391bcda-e312-40b5-b896-5854fdd6e26c","name":"500 - Invalid OTP","originalRequest":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/confirm-email","description":"Confirm the user's email address using the 6-digit OTP sent during signup.\n\nOTP expires after **2 minutes**. If expired, use the **Resend OTP** endpoint.\n\nOnce confirmed, the account becomes active and can be used to sign in.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. The email used during Sign Up. |\n| Body (JSON) | `otp` | `123456` | Required. 6-digit OTP sent to the email. Valid for 2 minutes. |"},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid Otp\"\n}"}],"_postman_id":"ee800b16-e696-4e02-a917-d5ae334ead58"},{"name":"Resend OTP","id":"1869f4f1-14cc-469b-a492-1f4f6ae14025","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/resend_otp","description":"<p>Resend the OTP confirmation email for unconfirmed accounts.</p>\n<p><strong>Rate Limiting Rules:</strong></p>\n<ul>\n<li>You must wait for the current OTP to expire (2 min) before requesting a new one.</li>\n<li>After <strong>3 failed attempts</strong>, the email is blocked for <strong>5 minutes</strong>.</li>\n<li>Maximum <strong>3 OTP sends</strong> within the allowed window.</li>\n</ul>\n<h2 id=\"only-works-for-accounts-that-are-not-yet-confirmed\">Only works for accounts that are <strong>not yet confirmed</strong>.</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>email</code></td>\n<td><code>diaa@example.com</code></td>\n<td>Required. Must belong to an unconfirmed account.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","signup","resend_otp"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"ceaab1d4-e611-406b-b210-6ac65dbd4734","name":"200 - OTP Resent","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/resend_otp","description":"Resend the OTP confirmation email for unconfirmed accounts.\n\n**Rate Limiting Rules:**\n- You must wait for the current OTP to expire (2 min) before requesting a new one.\n- After **3 failed attempts**, the email is blocked for **5 minutes**.\n- Maximum **3 OTP sends** within the allowed window.\n\nOnly works for accounts that are **not yet confirmed**.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Must belong to an unconfirmed account. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Otp Resend Succefully!\",\n  \"data\": null\n}"},{"id":"22dfadce-54ad-4f53-bc80-0a483b61c8a7","name":"500 - Already Confirmed or Not Found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/resend_otp","description":"Resend the OTP confirmation email for unconfirmed accounts.\n\n**Rate Limiting Rules:**\n- You must wait for the current OTP to expire (2 min) before requesting a new one.\n- After **3 failed attempts**, the email is blocked for **5 minutes**.\n- Maximum **3 OTP sends** within the allowed window.\n\nOnly works for accounts that are **not yet confirmed**.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Must belong to an unconfirmed account. |"},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User Not Exist Or Already Confirmed\"\n}"},{"id":"0f84f0ec-e0a9-48d7-af69-7d65926eb6e5","name":"500 - Too Soon to Resend","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signup/resend_otp","description":"Resend the OTP confirmation email for unconfirmed accounts.\n\n**Rate Limiting Rules:**\n- You must wait for the current OTP to expire (2 min) before requesting a new one.\n- After **3 failed attempts**, the email is blocked for **5 minutes**.\n- Maximum **3 OTP sends** within the allowed window.\n\nOnly works for accounts that are **not yet confirmed**.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Must belong to an unconfirmed account. |"},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"You Can Resend Otp After 87 Second\"\n}"}],"_postman_id":"1869f4f1-14cc-469b-a492-1f4f6ae14025"},{"name":"Sign In","id":"f9a25cb6-cba3-4628-890f-4695e7bc83fd","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"password\": \"password123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signin","description":"<p>Sign in with email and password.</p>\n<p>Returns a <strong>JWT access token</strong> (expires in 1 hour) and a <strong>refresh token</strong> (expires in 1 year).</p>\n<p>After a successful sign in, copy the <code>token</code> and <code>refreshToken</code> from the response and use them manually in any endpoint that requires authentication.</p>\n<hr />\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>email</code></td>\n<td><code>diaa@example.com</code></td>\n<td>Required. Registered and confirmed email.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>password</code></td>\n<td><code>password123</code></td>\n<td>Required. Account password.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p>Account must be <strong>confirmed</strong> (email verified) and must be a <strong>system account</strong> (not Google OAuth).</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["users","signin"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"7979da13-0b5d-4ae4-83f6-5ce45904c6af","name":"200 - Login Successful","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"password\": \"password123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signin","description":"Sign in with email and password.\n\nReturns a **JWT access token** (expires in 1 hour) and a **refresh token** (expires in 1 year).\n\nAfter a successful sign in, copy the `token` and `refreshToken` from the response and use them manually in any endpoint that requires authentication.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Registered and confirmed email. |\n| Body (JSON) | `password` | `password123` | Required. Account password. |\n\n> Account must be **confirmed** (email verified) and must be a **system account** (not Google OAuth)."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"LogIn Succefully\",\n  \"data\": {\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    \"refreshToken\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n  }\n}"},{"id":"4cb0d5e7-e7da-40f6-9dab-0fde290b4676","name":"409 - Not Found or Not Confirmed","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"password\": \"password123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signin","description":"Sign in with email and password.\n\nReturns a **JWT access token** (expires in 1 hour) and a **refresh token** (expires in 1 year).\n\nAfter a successful sign in, copy the `token` and `refreshToken` from the response and use them manually in any endpoint that requires authentication.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Registered and confirmed email. |\n| Body (JSON) | `password` | `password123` | Required. Account password. |\n\n> Account must be **confirmed** (email verified) and must be a **system account** (not Google OAuth)."},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User Not Exist Or Not Confirmed Yet !\"\n}"},{"id":"ed8d67a5-afc2-4716-917d-98f7afd58c64","name":"400 - Invalid Password","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"password\": \"password123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/signin","description":"Sign in with email and password.\n\nReturns a **JWT access token** (expires in 1 hour) and a **refresh token** (expires in 1 year).\n\nAfter a successful sign in, copy the `token` and `refreshToken` from the response and use them manually in any endpoint that requires authentication.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Registered and confirmed email. |\n| Body (JSON) | `password` | `password123` | Required. Account password. |\n\n> Account must be **confirmed** (email verified) and must be a **system account** (not Google OAuth)."},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid Password\"\n}"}],"_postman_id":"f9a25cb6-cba3-4628-890f-4695e7bc83fd"},{"name":"Refresh Token","id":"eefa7510-2d78-4a8b-a066-80d45ae951ab","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"refreshtoken","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMH0.refresh456exampletoken","description":"<p>Required. Your refresh token.</p>\n"}],"url":"https://sarahah-app-back-end.vercel.app/users/refreshToken","description":"<p>Get a new access token using your refresh token.</p>\n<p>Call this when your access token expires (after 1 hour) instead of asking the user to sign in again. Copy the new token from the response and use it manually in subsequent requests.</p>\n<hr />\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>refreshtoken</code></td>\n<td><code>&lt;your_refresh_token&gt;</code></td>\n<td>Required. The refresh token received during Sign In.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p>The refresh token is valid for <strong>1 year</strong>. Returns the new access token as a plain string in <code>data</code>.</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["users","refreshToken"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"007fd67d-87fd-4691-9157-3bcb5ea8c6c0","name":"200 - Token Refreshed","originalRequest":{"method":"GET","header":[{"key":"refreshtoken","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMH0.refresh456exampletoken","description":"Required. Your refresh token."}],"url":"https://sarahah-app-back-end.vercel.app/users/refreshToken","description":"Get a new access token using your refresh token.\n\nCall this when your access token expires (after 1 hour) instead of asking the user to sign in again. Copy the new token from the response and use it manually in subsequent requests.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `refreshtoken` | `<your_refresh_token>` | Required. The refresh token received during Sign In. |\n\n> The refresh token is valid for **1 year**. Returns the new access token as a plain string in `data`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n}"},{"id":"823ca1a5-2bcb-4cb3-94fa-28beca21e358","name":"401 - Invalid or Expired Refresh Token","originalRequest":{"method":"GET","header":[{"key":"refreshtoken","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMH0.refresh456exampletoken","description":"Required. Your refresh token."}],"url":"https://sarahah-app-back-end.vercel.app/users/refreshToken","description":"Get a new access token using your refresh token.\n\nCall this when your access token expires (after 1 hour) instead of asking the user to sign in again. Copy the new token from the response and use it manually in subsequent requests.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `refreshtoken` | `<your_refresh_token>` | Required. The refresh token received during Sign In. |\n\n> The refresh token is valid for **1 year**. Returns the new access token as a plain string in `data`."},"status":"Unauthorized","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid or expired token\"\n}"}],"_postman_id":"eefa7510-2d78-4a8b-a066-80d45ae951ab"},{"name":"Forget Password","id":"3b64977a-c913-4ca3-99ad-ffefad2c846f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/forgetPassword","description":"<p>Step 1 of 3 in the password reset flow.</p>\n<p>Send a 6-digit OTP to the user's registered email.</p>\n<p><strong>Full Reset Flow:</strong></p>\n<ol>\n<li><code>PATCH /users/forgetPassword</code> - Request OTP</li>\n<li><code>POST /users/confirmPassword</code> - Verify OTP</li>\n<li><code>PATCH /users/resetPassword</code> - Set new password</li>\n</ol>\n<h2 id=\"only-works-for-system-accounts-not-google-oauth\">Only works for system accounts (not Google OAuth).</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>email</code></td>\n<td><code>diaa@example.com</code></td>\n<td>Required. Must be a registered system account (not Google OAuth).</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","forgetPassword"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"f47aa7ae-5da9-455c-847a-ecf08fb366ba","name":"200 - OTP Sent","originalRequest":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/forgetPassword","description":"Step 1 of 3 in the password reset flow.\n\nSend a 6-digit OTP to the user's registered email.\n\n**Full Reset Flow:**\n1. `PATCH /users/forgetPassword` - Request OTP\n2. `POST /users/confirmPassword` - Verify OTP\n3. `PATCH /users/resetPassword` - Set new password\n\nOnly works for system accounts (not Google OAuth).\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Must be a registered system account (not Google OAuth). |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Otp Send Succefully\",\n  \"data\": null\n}"},{"id":"f9594b07-742c-4cde-8809-f3c701ad9771","name":"409 - User Not Found","originalRequest":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/forgetPassword","description":"Step 1 of 3 in the password reset flow.\n\nSend a 6-digit OTP to the user's registered email.\n\n**Full Reset Flow:**\n1. `PATCH /users/forgetPassword` - Request OTP\n2. `POST /users/confirmPassword` - Verify OTP\n3. `PATCH /users/resetPassword` - Set new password\n\nOnly works for system accounts (not Google OAuth).\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Must be a registered system account (not Google OAuth). |"},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User Not Exist\"\n}"}],"_postman_id":"3b64977a-c913-4ca3-99ad-ffefad2c846f"},{"name":"Confirm Password (Verify OTP)","id":"6b8b3596-c3d1-4fc3-94a5-bf989a197e25","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/confirmPassword","description":"<p>Step 2 of 3 in the password reset flow.</p>\n<p>Verify the OTP sent to the email. On success, a temporary verification session is created (valid for <strong>5 minutes</strong>).</p>\n<p>You must call <code>PATCH /users/resetPassword</code> within this window.</p>\n<h2 id=\"full-reset-flow-1-patch-usersforgetpassword---request-otp-2-post-usersconfirmpassword---verify-otp--←-you-are-here-3-patch-usersresetpassword---set-new-password\"><strong>Full Reset Flow:</strong>\n1. <code>PATCH /users/forgetPassword</code> - Request OTP\n2. <code>POST /users/confirmPassword</code> - Verify OTP  ← You are here\n3. <code>PATCH /users/resetPassword</code> - Set new password</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>email</code></td>\n<td><code>diaa@example.com</code></td>\n<td>Required. Same email used in Forget Password step.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>otp</code></td>\n<td><code>123456</code></td>\n<td>Required. 6-digit OTP sent to the email.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","confirmPassword"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"f7a9eb25-ba2d-4e55-951e-ce7fce72498f","name":"200 - OTP Valid","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/confirmPassword","description":"Step 2 of 3 in the password reset flow.\n\nVerify the OTP sent to the email. On success, a temporary verification session is created (valid for **5 minutes**).\n\nYou must call `PATCH /users/resetPassword` within this window.\n\n**Full Reset Flow:**\n1. `PATCH /users/forgetPassword` - Request OTP\n2. `POST /users/confirmPassword` - Verify OTP  ← You are here\n3. `PATCH /users/resetPassword` - Set new password\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Same email used in Forget Password step. |\n| Body (JSON) | `otp` | `123456` | Required. 6-digit OTP sent to the email. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Otp Is Valid\",\n  \"data\": null\n}"},{"id":"f0fdb979-f0fb-48a8-9a78-ab470e026e60","name":"500 - Invalid OTP","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/confirmPassword","description":"Step 2 of 3 in the password reset flow.\n\nVerify the OTP sent to the email. On success, a temporary verification session is created (valid for **5 minutes**).\n\nYou must call `PATCH /users/resetPassword` within this window.\n\n**Full Reset Flow:**\n1. `PATCH /users/forgetPassword` - Request OTP\n2. `POST /users/confirmPassword` - Verify OTP  ← You are here\n3. `PATCH /users/resetPassword` - Set new password\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Same email used in Forget Password step. |\n| Body (JSON) | `otp` | `123456` | Required. 6-digit OTP sent to the email. |"},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Otp Is Invalid\"\n}"},{"id":"ac9f0102-b7be-446f-96e8-9463c381c83b","name":"500 - OTP Expired","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"otp\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/confirmPassword","description":"Step 2 of 3 in the password reset flow.\n\nVerify the OTP sent to the email. On success, a temporary verification session is created (valid for **5 minutes**).\n\nYou must call `PATCH /users/resetPassword` within this window.\n\n**Full Reset Flow:**\n1. `PATCH /users/forgetPassword` - Request OTP\n2. `POST /users/confirmPassword` - Verify OTP  ← You are here\n3. `PATCH /users/resetPassword` - Set new password\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Same email used in Forget Password step. |\n| Body (JSON) | `otp` | `123456` | Required. 6-digit OTP sent to the email. |"},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid or Expired OTP\"\n}"}],"_postman_id":"6b8b3596-c3d1-4fc3-94a5-bf989a197e25"},{"name":"Reset Password","id":"903c54c7-c899-4be4-ba65-d0e5d6d89c40","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"newPassword\": \"newPassword123\",\n  \"rePassword\": \"newPassword123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/resetPassword","description":"<p>Step 3 of 3 in the password reset flow.</p>\n<p>Set a new password after OTP verification. Must be called within <strong>5 minutes</strong> of confirming the OTP.</p>\n<p>All existing sessions are invalidated after a successful password reset (users are logged out everywhere).</p>\n<h2 id=\"full-reset-flow-1-patch-usersforgetpassword---request-otp-2-post-usersconfirmpassword---verify-otp-3-patch-usersresetpassword---set-new-password--←-you-are-here\"><strong>Full Reset Flow:</strong>\n1. <code>PATCH /users/forgetPassword</code> - Request OTP\n2. <code>POST /users/confirmPassword</code> - Verify OTP\n3. <code>PATCH /users/resetPassword</code> - Set new password  ← You are here</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>email</code></td>\n<td><code>diaa@example.com</code></td>\n<td>Required. Same email used throughout the reset flow.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>newPassword</code></td>\n<td><code>newPassword123</code></td>\n<td>Required. Minimum 8 characters.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>rePassword</code></td>\n<td><code>newPassword123</code></td>\n<td>Required. Must match <code>newPassword</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p>Must be called within <strong>5 minutes</strong> of completing the Confirm Password step.</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["users","resetPassword"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"de15580a-df9c-4644-a094-b3f8f89d7664","name":"200 - Password Reset","originalRequest":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"newPassword\": \"newPassword123\",\n  \"rePassword\": \"newPassword123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/resetPassword","description":"Step 3 of 3 in the password reset flow.\n\nSet a new password after OTP verification. Must be called within **5 minutes** of confirming the OTP.\n\nAll existing sessions are invalidated after a successful password reset (users are logged out everywhere).\n\n**Full Reset Flow:**\n1. `PATCH /users/forgetPassword` - Request OTP\n2. `POST /users/confirmPassword` - Verify OTP\n3. `PATCH /users/resetPassword` - Set new password  ← You are here\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Same email used throughout the reset flow. |\n| Body (JSON) | `newPassword` | `newPassword123` | Required. Minimum 8 characters. |\n| Body (JSON) | `rePassword` | `newPassword123` | Required. Must match `newPassword`. |\n\n> Must be called within **5 minutes** of completing the Confirm Password step."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Password Reset Succefully\",\n  \"data\": null\n}"},{"id":"a9b0d2ea-23a1-409e-aadb-bc67b35ca3a4","name":"500 - OTP Not Verified","originalRequest":{"method":"PATCH","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaa@example.com\",\n  \"newPassword\": \"newPassword123\",\n  \"rePassword\": \"newPassword123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/resetPassword","description":"Step 3 of 3 in the password reset flow.\n\nSet a new password after OTP verification. Must be called within **5 minutes** of confirming the OTP.\n\nAll existing sessions are invalidated after a successful password reset (users are logged out everywhere).\n\n**Full Reset Flow:**\n1. `PATCH /users/forgetPassword` - Request OTP\n2. `POST /users/confirmPassword` - Verify OTP\n3. `PATCH /users/resetPassword` - Set new password  ← You are here\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `email` | `diaa@example.com` | Required. Same email used throughout the reset flow. |\n| Body (JSON) | `newPassword` | `newPassword123` | Required. Minimum 8 characters. |\n| Body (JSON) | `rePassword` | `newPassword123` | Required. Must match `newPassword`. |\n\n> Must be called within **5 minutes** of completing the Confirm Password step."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Otp not verified\"\n}"}],"_postman_id":"903c54c7-c899-4be4-ba65-d0e5d6d89c40"},{"name":"Log Out (Current Device)","id":"13ba3e86-a29a-4c7f-975c-3f55af473b8c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required. Your access token.</p>\n"}],"url":"https://sarahah-app-back-end.vercel.app/users/logout?all=false","description":"<p>Log out from the <strong>current device only</strong>.</p>\n<p>Revokes the current token by adding it to a <strong>Redis blocklist</strong> until it naturally expires (1 hour).</p>\n<p>Other active sessions on other devices remain valid.</p>\n<hr />\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. Valid JWT access token.</td>\n</tr>\n<tr>\n<td>Query Param</td>\n<td><code>all</code></td>\n<td><code>false</code></td>\n<td>Required. Must be set to <code>false</code> for single-device logout.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","logout"],"host":["sarahah-app-back-end","vercel","app"],"query":[{"description":{"content":"<p>Logout from current device only.</p>\n","type":"text/plain"},"key":"all","value":"false"}],"variable":[]}},"response":[{"id":"5477b246-e7d6-4480-bd3f-5fbf7de06dc0","name":"200 - Logged Out","originalRequest":{"method":"POST","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. Your access token."}],"url":{"raw":"https://sarahah-app-back-end.vercel.app/users/logout?all=false","protocol":"https","host":["sarahah-app-back-end","vercel","app"],"path":["users","logout"],"query":[{"key":"all","value":"false","description":"Logout from current device only."}]},"description":"Log out from the **current device only**.\n\nRevokes the current token by adding it to a **Redis blocklist** until it naturally expires (1 hour).\n\nOther active sessions on other devices remain valid.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. Valid JWT access token. |\n| Query Param | `all` | `false` | Required. Must be set to `false` for single-device logout. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": null\n}"},{"id":"7dd45c7d-f8ad-4acf-b316-bc5592242ad8","name":"401 - Unauthorized","originalRequest":{"method":"POST","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. Your access token."}],"url":{"raw":"https://sarahah-app-back-end.vercel.app/users/logout?all=false","protocol":"https","host":["sarahah-app-back-end","vercel","app"],"path":["users","logout"],"query":[{"key":"all","value":"false","description":"Logout from current device only."}]},"description":"Log out from the **current device only**.\n\nRevokes the current token by adding it to a **Redis blocklist** until it naturally expires (1 hour).\n\nOther active sessions on other devices remain valid.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. Valid JWT access token. |\n| Query Param | `all` | `false` | Required. Must be set to `false` for single-device logout. |"},"status":"Unauthorized","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid or expired token\"\n}"}],"_postman_id":"13ba3e86-a29a-4c7f-975c-3f55af473b8c"},{"name":"Log Out (All Devices)","id":"f01edf8e-7819-4035-aebc-8541f82567d2","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required. Your access token.</p>\n"}],"url":"https://sarahah-app-back-end.vercel.app/users/logout?all=true","description":"<p>Log out from <strong>all devices at once</strong>.</p>\n<p>Invalidates <strong>all active sessions</strong> by updating the <code>logOutTime</code> timestamp on the user record. Any token issued before this timestamp is rejected.</p>\n<p>Use this when the user suspects their account is compromised or wants a full session reset.</p>\n<hr />\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. Valid JWT access token.</td>\n</tr>\n<tr>\n<td>Query Param</td>\n<td><code>all</code></td>\n<td><code>true</code></td>\n<td>Required. Must be set to <code>true</code> for all-devices logout.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","logout"],"host":["sarahah-app-back-end","vercel","app"],"query":[{"description":{"content":"<p>Logout from all devices.</p>\n","type":"text/plain"},"key":"all","value":"true"}],"variable":[]}},"response":[{"id":"473200a1-a811-4851-b694-ba95f564cceb","name":"200 - Logged Out From All Devices","originalRequest":{"method":"POST","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. Your access token."}],"url":{"raw":"https://sarahah-app-back-end.vercel.app/users/logout?all=true","protocol":"https","host":["sarahah-app-back-end","vercel","app"],"path":["users","logout"],"query":[{"key":"all","value":"true","description":"Logout from all devices."}]},"description":"Log out from **all devices at once**.\n\nInvalidates **all active sessions** by updating the `logOutTime` timestamp on the user record. Any token issued before this timestamp is rejected.\n\nUse this when the user suspects their account is compromised or wants a full session reset.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. Valid JWT access token. |\n| Query Param | `all` | `true` | Required. Must be set to `true` for all-devices logout. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": null\n}"},{"id":"3c8bb305-2d18-41c3-992a-5eb734e6ffc1","name":"401 - Unauthorized","originalRequest":{"method":"POST","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. Your access token."}],"url":{"raw":"https://sarahah-app-back-end.vercel.app/users/logout?all=true","protocol":"https","host":["sarahah-app-back-end","vercel","app"],"path":["users","logout"],"query":[{"key":"all","value":"true","description":"Logout from all devices."}]},"description":"Log out from **all devices at once**.\n\nInvalidates **all active sessions** by updating the `logOutTime` timestamp on the user record. Any token issued before this timestamp is rejected.\n\nUse this when the user suspects their account is compromised or wants a full session reset.\n\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. Valid JWT access token. |\n| Query Param | `all` | `true` | Required. Must be set to `true` for all-devices logout. |"},"status":"Unauthorized","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid or expired token\"\n}"}],"_postman_id":"f01edf8e-7819-4035-aebc-8541f82567d2"}],"id":"400981a6-0297-4b6d-944f-df8b07c3d8fa","description":"<p>All authentication-related endpoints including registration, login, OTP verification, password management, and Google OAuth.</p>\n","_postman_id":"400981a6-0297-4b6d-944f-df8b07c3d8fa"},{"name":"User","item":[{"name":"Get My Profile","id":"6cbd651b-406b-4a6b-832c-434e81cf84f8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required. Your access token.</p>\n"}],"url":"https://sarahah-app-back-end.vercel.app/users/profile","description":"<p>Get the authenticated user's full profile.</p>\n<p>Phone number is returned <strong>decrypted</strong> (it's stored encrypted in the database using AES-256-CBC).</p>\n<h2 id=\"requires-token-header\"><strong>Requires:</strong> <code>token</code> header</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. JWT access token received from Sign In.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","profile"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"d10a98b4-e5b9-46d8-822a-97c8d6076f5e","name":"200 - Profile Data","originalRequest":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. Your access token."}],"url":"https://sarahah-app-back-end.vercel.app/users/profile","description":"Get the authenticated user's full profile.\n\nPhone number is returned **decrypted** (it's stored encrypted in the database using AES-256-CBC).\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": {\n    \"_id\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n    \"firstName\": \"Diaa\",\n    \"lastName\": \"Eldeen\",\n    \"userName\": \"Diaa Eldeen\",\n    \"email\": \"diaa@example.com\",\n    \"age\": 22,\n    \"gender\": \"male\",\n    \"phone\": \"01012345678\",\n    \"provider\": \"system\",\n    \"confirmed\": true,\n    \"totalViews\": 15,\n    \"role\": \"user\",\n    \"profilePicture\": {\n      \"secure_url\": \"https://res.cloudinary.com/...\",\n      \"public_id\": \"SarahahApp/usersProfile/...\"\n    },\n    \"createdAt\": \"2026-04-01T10:00:00.000Z\",\n    \"updatedAt\": \"2026-04-01T10:00:00.000Z\"\n  }\n}"}],"_postman_id":"6cbd651b-406b-4a6b-832c-434e81cf84f8"},{"name":"Get User Profile By ID","id":"fe5794f1-71ad-415b-bf43-81d3c56aa1f4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Optional. If provided, the owner won't increment their own view count.</p>\n"}],"url":"https://sarahah-app-back-end.vercel.app/users/665f1a2b3c4d5e6f7a8b9c0d","description":"<p>Get any user's public profile by their MongoDB ID.</p>\n<p>This is the <strong>share profile</strong> endpoint. Users share this link with others to receive anonymous messages.</p>\n<p><strong>View Count:</strong></p>\n<ul>\n<li>If the request comes from a <strong>different user</strong> (or no token), <code>totalViews</code> is incremented by 1.</li>\n<li>If the request comes from the <strong>profile owner</strong>, view count is NOT incremented.</li>\n</ul>\n<p><strong>Password is excluded</strong> from the response.</p>\n<h2 id=\"token-is-optional---works-for-unauthenticated-visitors-too\"><strong>Token is optional</strong> - works for unauthenticated visitors too.</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Optional. If provided and matches the profile owner, view count won't increment.</td>\n</tr>\n<tr>\n<td>URL Param</td>\n<td><code>:id</code></td>\n<td><code>665f1a2b3c4d5e6f7a8b9c0d</code></td>\n<td>Required. MongoDB ObjectId of the target user.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","665f1a2b3c4d5e6f7a8b9c0d"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"7e4c2243-75d1-479f-80d3-082f7d9a82f0","name":"200 - User Profile","originalRequest":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Optional. If provided, the owner won't increment their own view count."}],"url":"https://sarahah-app-back-end.vercel.app/users/665f1a2b3c4d5e6f7a8b9c0d","description":"Get any user's public profile by their MongoDB ID.\n\nThis is the **share profile** endpoint. Users share this link with others to receive anonymous messages.\n\n**View Count:**\n- If the request comes from a **different user** (or no token), `totalViews` is incremented by 1.\n- If the request comes from the **profile owner**, view count is NOT incremented.\n\n**Password is excluded** from the response.\n\n**Token is optional** - works for unauthenticated visitors too.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Optional. If provided and matches the profile owner, view count won't increment. |\n| URL Param | `:id` | `665f1a2b3c4d5e6f7a8b9c0d` | Required. MongoDB ObjectId of the target user. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": {\n    \"_id\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n    \"firstName\": \"Diaa\",\n    \"lastName\": \"Eldeen\",\n    \"userName\": \"Diaa Eldeen\",\n    \"email\": \"diaa@example.com\",\n    \"gender\": \"male\",\n    \"provider\": \"system\",\n    \"confirmed\": true,\n    \"totalViews\": 16,\n    \"role\": \"user\",\n    \"profilePicture\": {\n      \"secure_url\": \"https://res.cloudinary.com/...\",\n      \"public_id\": \"SarahahApp/usersProfile/...\"\n    },\n    \"createdAt\": \"2026-04-01T10:00:00.000Z\",\n    \"updatedAt\": \"2026-04-01T10:00:00.000Z\"\n  }\n}"},{"id":"24d3a64d-4c34-45a9-a47d-718d0031c6ac","name":"404 - User Not Found","originalRequest":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Optional. If provided, the owner won't increment their own view count."}],"url":"https://sarahah-app-back-end.vercel.app/users/665f1a2b3c4d5e6f7a8b9c0d","description":"Get any user's public profile by their MongoDB ID.\n\nThis is the **share profile** endpoint. Users share this link with others to receive anonymous messages.\n\n**View Count:**\n- If the request comes from a **different user** (or no token), `totalViews` is incremented by 1.\n- If the request comes from the **profile owner**, view count is NOT incremented.\n\n**Password is excluded** from the response.\n\n**Token is optional** - works for unauthenticated visitors too.\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Optional. If provided and matches the profile owner, view count won't increment. |\n| URL Param | `:id` | `665f1a2b3c4d5e6f7a8b9c0d` | Required. MongoDB ObjectId of the target user. |"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User Not Found\"\n}"}],"_postman_id":"fe5794f1-71ad-415b-bf43-81d3c56aa1f4"},{"name":"Update Profile","id":"77f296e7-7339-4046-a02f-44c645b7201b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required.</p>\n"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"firstName\": \"Diaa\",\n  \"lastName\": \"Eldeen\",\n  \"gender\": \"male\",\n  \"phone\": \"01012345678\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/updateProfile","description":"<p>Update the authenticated user's profile information.</p>\n<p>All fields are optional - only send the fields you want to update.</p>\n<p>Phone number is encrypted before storage using <strong>AES-256-CBC</strong>.</p>\n<p><strong>Validation Rules:</strong></p>\n<ul>\n<li><code>firstName</code> / <code>lastName</code>: 3-30 chars, letters/numbers/spaces/dashes only</li>\n<li><code>gender</code>: <code>male</code> or <code>female</code></li>\n<li><code>phone</code>: Egyptian format (010, 011, 012, 015 + 8 digits)</li>\n</ul>\n<h2 id=\"requires-token-header\"><strong>Requires:</strong> <code>token</code> header</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. JWT access token received from Sign In.</td>\n</tr>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>firstName</code></td>\n<td><code>Diaa</code></td>\n<td>Optional. 3–30 chars, letters/numbers/spaces/dashes only.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>lastName</code></td>\n<td><code>Eldeen</code></td>\n<td>Optional. 3–30 chars, letters/numbers/spaces/dashes only.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>gender</code></td>\n<td><code>male</code></td>\n<td>Optional. Enum: <code>male</code> or <code>female</code>.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>phone</code></td>\n<td><code>01012345678</code></td>\n<td>Optional. Egyptian format: 010/011/012/015 + 8 digits. Stored encrypted.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p>All fields are optional — send only the fields you want to update.</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["users","updateProfile"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"cc6e3d52-fbad-49ed-80bd-0651b6765635","name":"200 - Profile Updated","originalRequest":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required."},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"firstName\": \"Diaa\",\n  \"lastName\": \"Eldeen\",\n  \"gender\": \"male\",\n  \"phone\": \"01012345678\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/updateProfile","description":"Update the authenticated user's profile information.\n\nAll fields are optional - only send the fields you want to update.\n\nPhone number is encrypted before storage using **AES-256-CBC**.\n\n**Validation Rules:**\n- `firstName` / `lastName`: 3-30 chars, letters/numbers/spaces/dashes only\n- `gender`: `male` or `female`\n- `phone`: Egyptian format (010, 011, 012, 015 + 8 digits)\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `firstName` | `Diaa` | Optional. 3–30 chars, letters/numbers/spaces/dashes only. |\n| Body (JSON) | `lastName` | `Eldeen` | Optional. 3–30 chars, letters/numbers/spaces/dashes only. |\n| Body (JSON) | `gender` | `male` | Optional. Enum: `male` or `female`. |\n| Body (JSON) | `phone` | `01012345678` | Optional. Egyptian format: 010/011/012/015 + 8 digits. Stored encrypted. |\n\n> All fields are optional — send only the fields you want to update."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": {\n    \"_id\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n    \"firstName\": \"Diaa\",\n    \"lastName\": \"Eldeen\",\n    \"email\": \"diaa@example.com\",\n    \"gender\": \"male\",\n    \"updatedAt\": \"2026-04-06T10:00:00.000Z\"\n  }\n}"}],"_postman_id":"77f296e7-7339-4046-a02f-44c645b7201b"},{"name":"Update Password","id":"64afd163-d5f9-4b21-a7b8-00e635be5d17","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required.</p>\n"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"oldPassword\": \"password123\",\n  \"newPassword\": \"newPassword456\",\n  \"confirmPassword\": \"newPassword456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/updatePassword","description":"<p>Change the authenticated user's password.</p>\n<p>Requires the current (old) password for verification. All active sessions are invalidated after the update.</p>\n<p><strong>Validation Rules:</strong></p>\n<ul>\n<li><code>oldPassword</code>: required</li>\n<li><code>newPassword</code>: minimum 8 characters</li>\n<li><code>confirmPassword</code>: must match <code>newPassword</code></li>\n</ul>\n<h2 id=\"requires-token-header\"><strong>Requires:</strong> <code>token</code> header</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. JWT access token received from Sign In.</td>\n</tr>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>oldPassword</code></td>\n<td><code>password123</code></td>\n<td>Required. Current account password for verification.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>newPassword</code></td>\n<td><code>newPassword456</code></td>\n<td>Required. Minimum 8 characters.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>confirmPassword</code></td>\n<td><code>newPassword456</code></td>\n<td>Required. Must match <code>newPassword</code>.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"protocol":"https","path":["users","updatePassword"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"c9312dd7-5500-47aa-9191-7317a28eff81","name":"200 - Password Updated","originalRequest":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required."},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"oldPassword\": \"password123\",\n  \"newPassword\": \"newPassword456\",\n  \"confirmPassword\": \"newPassword456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/updatePassword","description":"Change the authenticated user's password.\n\nRequires the current (old) password for verification. All active sessions are invalidated after the update.\n\n**Validation Rules:**\n- `oldPassword`: required\n- `newPassword`: minimum 8 characters\n- `confirmPassword`: must match `newPassword`\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `oldPassword` | `password123` | Required. Current account password for verification. |\n| Body (JSON) | `newPassword` | `newPassword456` | Required. Minimum 8 characters. |\n| Body (JSON) | `confirmPassword` | `newPassword456` | Required. Must match `newPassword`. |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": null\n}"},{"id":"6f703d22-a885-4a22-9590-b4b529c359db","name":"400 - Wrong Old Password","originalRequest":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required."},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"oldPassword\": \"password123\",\n  \"newPassword\": \"newPassword456\",\n  \"confirmPassword\": \"newPassword456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/users/updatePassword","description":"Change the authenticated user's password.\n\nRequires the current (old) password for verification. All active sessions are invalidated after the update.\n\n**Validation Rules:**\n- `oldPassword`: required\n- `newPassword`: minimum 8 characters\n- `confirmPassword`: must match `newPassword`\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `oldPassword` | `password123` | Required. Current account password for verification. |\n| Body (JSON) | `newPassword` | `newPassword456` | Required. Minimum 8 characters. |\n| Body (JSON) | `confirmPassword` | `newPassword456` | Required. Must match `newPassword`. |"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Invalid old Password\"\n}"}],"_postman_id":"64afd163-d5f9-4b21-a7b8-00e635be5d17"},{"name":"Update Profile Picture","id":"dd0b6fdb-f3f3-4bd4-b9fe-0e95d3a443e8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required.</p>\n"}],"body":{"mode":"formdata","formdata":[{"key":"image","description":"<p>Required. New profile picture. Allowed: PNG, JPG, JPEG.</p>\n","type":"file","value":null}]},"url":"https://sarahah-app-back-end.vercel.app/users/updateProfilePicture","description":"<p>Upload a new profile picture.</p>\n<p>The old picture is automatically deleted from Cloudinary before uploading the new one.</p>\n<p>Images are stored in Cloudinary under the folder <code>SarahahApp/usersProfile</code>.</p>\n<p><strong>Allowed formats:</strong> PNG, JPG, JPEG</p>\n<p><strong>Content-Type:</strong> <code>multipart/form-data</code></p>\n<h2 id=\"requires-token-header\"><strong>Requires:</strong> <code>token</code> header</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. JWT access token received from Sign In.</td>\n</tr>\n<tr>\n<td>Body (form-data)</td>\n<td><code>image</code></td>\n<td><em>(file)</em></td>\n<td>Required. New profile picture. Allowed: PNG, JPG, JPEG.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p><strong>Content-Type:</strong> <code>multipart/form-data</code> (required because of file upload)</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["users","updateProfilePicture"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"d4169f71-23bb-4e76-8d48-bc6f1f311594","name":"200 - Picture Updated","originalRequest":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required."}],"body":{"mode":"formdata","formdata":[{"key":"image","description":"Required. New profile picture. Allowed: PNG, JPG, JPEG.","type":"file","value":null}]},"url":"https://sarahah-app-back-end.vercel.app/users/updateProfilePicture","description":"Upload a new profile picture.\n\nThe old picture is automatically deleted from Cloudinary before uploading the new one.\n\nImages are stored in Cloudinary under the folder `SarahahApp/usersProfile`.\n\n**Allowed formats:** PNG, JPG, JPEG\n\n**Content-Type:** `multipart/form-data`\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n| Body (form-data) | `image` | *(file)* | Required. New profile picture. Allowed: PNG, JPG, JPEG. |\n\n> **Content-Type:** `multipart/form-data` (required because of file upload)"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Profile picture updated successfully\",\n  \"data\": null\n}"},{"id":"362ae5eb-fed8-4395-adf8-2fb2d14cb838","name":"400 - No Image Provided","originalRequest":{"method":"PATCH","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required."}],"body":{"mode":"formdata","formdata":[{"key":"image","description":"Required. New profile picture. Allowed: PNG, JPG, JPEG.","type":"file","value":null}]},"url":"https://sarahah-app-back-end.vercel.app/users/updateProfilePicture","description":"Upload a new profile picture.\n\nThe old picture is automatically deleted from Cloudinary before uploading the new one.\n\nImages are stored in Cloudinary under the folder `SarahahApp/usersProfile`.\n\n**Allowed formats:** PNG, JPG, JPEG\n\n**Content-Type:** `multipart/form-data`\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n| Body (form-data) | `image` | *(file)* | Required. New profile picture. Allowed: PNG, JPG, JPEG. |\n\n> **Content-Type:** `multipart/form-data` (required because of file upload)"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Image is required\"\n}"}],"_postman_id":"dd0b6fdb-f3f3-4bd4-b9fe-0e95d3a443e8"}],"id":"8cbaa486-15cd-4100-a6eb-14d886a13dd5","description":"<p>User profile management endpoints. All endpoints in this folder require authentication via the <code>token</code> header.</p>\n","_postman_id":"8cbaa486-15cd-4100-a6eb-14d886a13dd5"},{"name":"Messages","item":[{"name":"Send Anonymous Message","id":"6af169d3-1811-4bfb-ad80-36a803561cf9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"content\": \"You are an amazing developer!\",\n  \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/messages","description":"<p>Send an anonymous message to any user.</p>\n<p><strong>No authentication required</strong> - this is the core anonymous feature of the app.</p>\n<p>The <code>userId</code> is the MongoDB ID of the recipient. Users share their profile link (<code>GET /users/:id</code>) and others use this endpoint to send them messages.</p>\n<p><strong>Validation Rules:</strong></p>\n<ul>\n<li><code>content</code>: required, minimum 1 character</li>\n<li><code>userId</code>: required, valid 24-character MongoDB ObjectId</li>\n</ul>\n<h2 id=\"how-the-anonymous-flow-works-1-user-a-shares-their-profile-link-2-user-b-visits-the-profile-3-user-b-sends-a-message-via-this-endpoint-no-login-needed-4-user-a-sees-the-message-in-their-inbox\"><strong>How the anonymous flow works:</strong>\n1. User A shares their profile link\n2. User B visits the profile\n3. User B sends a message via this endpoint (no login needed)\n4. User A sees the message in their inbox</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>Content-Type</code></td>\n<td><code>application/json</code></td>\n<td>Required.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>content</code></td>\n<td><code>You are an amazing developer!</code></td>\n<td>Required. The anonymous message text. Minimum 1 character.</td>\n</tr>\n<tr>\n<td>Body (JSON)</td>\n<td><code>userId</code></td>\n<td><code>665f1a2b3c4d5e6f7a8b9c0d</code></td>\n<td>Required. MongoDB ObjectId of the recipient user.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p><strong>No authentication required</strong> — this endpoint is intentionally public.</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["messages"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"2c6e29ae-9713-46fb-a618-bf7af83bf1d7","name":"201 - Message Sent","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"content\": \"You are an amazing developer!\",\n  \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/messages","description":"Send an anonymous message to any user.\n\n**No authentication required** - this is the core anonymous feature of the app.\n\nThe `userId` is the MongoDB ID of the recipient. Users share their profile link (`GET /users/:id`) and others use this endpoint to send them messages.\n\n**Validation Rules:**\n- `content`: required, minimum 1 character\n- `userId`: required, valid 24-character MongoDB ObjectId\n\n**How the anonymous flow works:**\n1. User A shares their profile link\n2. User B visits the profile\n3. User B sends a message via this endpoint (no login needed)\n4. User A sees the message in their inbox\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `content` | `You are an amazing developer!` | Required. The anonymous message text. Minimum 1 character. |\n| Body (JSON) | `userId` | `665f1a2b3c4d5e6f7a8b9c0d` | Required. MongoDB ObjectId of the recipient user. |\n\n> **No authentication required** — this endpoint is intentionally public."},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Message Sent Succefully\",\n  \"data\": {\n    \"_id\": \"775f1a2b3c4d5e6f7a8b9c1e\",\n    \"content\": \"You are an amazing developer!\",\n    \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n    \"createdAt\": \"2026-04-06T10:00:00.000Z\",\n    \"updatedAt\": \"2026-04-06T10:00:00.000Z\"\n  }\n}"},{"id":"8fe101ea-9964-49a2-ac38-eb1a3c60f739","name":"409 - User Not Found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"content\": \"You are an amazing developer!\",\n  \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/messages","description":"Send an anonymous message to any user.\n\n**No authentication required** - this is the core anonymous feature of the app.\n\nThe `userId` is the MongoDB ID of the recipient. Users share their profile link (`GET /users/:id`) and others use this endpoint to send them messages.\n\n**Validation Rules:**\n- `content`: required, minimum 1 character\n- `userId`: required, valid 24-character MongoDB ObjectId\n\n**How the anonymous flow works:**\n1. User A shares their profile link\n2. User B visits the profile\n3. User B sends a message via this endpoint (no login needed)\n4. User A sees the message in their inbox\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `content` | `You are an amazing developer!` | Required. The anonymous message text. Minimum 1 character. |\n| Body (JSON) | `userId` | `665f1a2b3c4d5e6f7a8b9c0d` | Required. MongoDB ObjectId of the recipient user. |\n\n> **No authentication required** — this endpoint is intentionally public."},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"User Not Exist\"\n}"},{"id":"133b244c-cfa9-40f5-a681-04037404bd4c","name":"422 - Validation Error","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"content\": \"You are an amazing developer!\",\n  \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\"\n}","options":{"raw":{"language":"json"}}},"url":"https://sarahah-app-back-end.vercel.app/messages","description":"Send an anonymous message to any user.\n\n**No authentication required** - this is the core anonymous feature of the app.\n\nThe `userId` is the MongoDB ID of the recipient. Users share their profile link (`GET /users/:id`) and others use this endpoint to send them messages.\n\n**Validation Rules:**\n- `content`: required, minimum 1 character\n- `userId`: required, valid 24-character MongoDB ObjectId\n\n**How the anonymous flow works:**\n1. User A shares their profile link\n2. User B visits the profile\n3. User B sends a message via this endpoint (no login needed)\n4. User A sees the message in their inbox\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `Content-Type` | `application/json` | Required. |\n| Body (JSON) | `content` | `You are an amazing developer!` | Required. The anonymous message text. Minimum 1 character. |\n| Body (JSON) | `userId` | `665f1a2b3c4d5e6f7a8b9c0d` | Required. MongoDB ObjectId of the recipient user. |\n\n> **No authentication required** — this endpoint is intentionally public."},"status":"Unprocessable Entity","code":422,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"success\": false,\n  \"message\": \"Validation Error\",\n  \"errors\": [\n    \"Message is empty\",\n    \"userId is required\"\n  ]\n}"}],"_postman_id":"6af169d3-1811-4bfb-ad80-36a803561cf9"},{"name":"Get Single Message","id":"843e7a7c-de13-4b4c-a20a-d806a4454784","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required. You can only read your own messages.</p>\n"}],"url":"https://sarahah-app-back-end.vercel.app/messages/775f1a2b3c4d5e6f7a8b9c1e","description":"<p>Retrieve a single message by its ID.</p>\n<p>Only the message recipient (owner) can access it. A message is linked to a <code>userId</code>, and the authenticated user must match that <code>userId</code>.</p>\n<h2 id=\"requires-token-header\"><strong>Requires:</strong> <code>token</code> header</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. JWT access token received from Sign In.</td>\n</tr>\n<tr>\n<td>URL Param</td>\n<td><code>:messageId</code></td>\n<td><code>775f1a2b3c4d5e6f7a8b9c1e</code></td>\n<td>Required. MongoDB ObjectId of the message to retrieve.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p>You can only retrieve messages that were sent <strong>to you</strong>. Accessing another user's message returns an error.</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["messages","775f1a2b3c4d5e6f7a8b9c1e"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"4eed7f5d-1d49-49ad-a979-d3926255f40a","name":"200 - Message Data","originalRequest":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. You can only read your own messages."}],"url":"https://sarahah-app-back-end.vercel.app/messages/775f1a2b3c4d5e6f7a8b9c1e","description":"Retrieve a single message by its ID.\n\nOnly the message recipient (owner) can access it. A message is linked to a `userId`, and the authenticated user must match that `userId`.\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n| URL Param | `:messageId` | `775f1a2b3c4d5e6f7a8b9c1e` | Required. MongoDB ObjectId of the message to retrieve. |\n\n> You can only retrieve messages that were sent **to you**. Accessing another user's message returns an error."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": {\n    \"_id\": \"775f1a2b3c4d5e6f7a8b9c1e\",\n    \"content\": \"You are an amazing developer!\",\n    \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n    \"createdAt\": \"2026-04-06T10:00:00.000Z\",\n    \"updatedAt\": \"2026-04-06T10:00:00.000Z\"\n  }\n}"},{"id":"0571905b-a04a-4da5-813b-d7841e48cc77","name":"500 - Not Found or Not Owner","originalRequest":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. You can only read your own messages."}],"url":"https://sarahah-app-back-end.vercel.app/messages/775f1a2b3c4d5e6f7a8b9c1e","description":"Retrieve a single message by its ID.\n\nOnly the message recipient (owner) can access it. A message is linked to a `userId`, and the authenticated user must match that `userId`.\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n| URL Param | `:messageId` | `775f1a2b3c4d5e6f7a8b9c1e` | Required. MongoDB ObjectId of the message to retrieve. |\n\n> You can only retrieve messages that were sent **to you**. Accessing another user's message returns an error."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"Message Not Exist Or Not Auth\"\n}"}],"_postman_id":"843e7a7c-de13-4b4c-a20a-d806a4454784"},{"name":"Get All My Messages","id":"7cccdb34-960d-4e2c-bea5-024bfd81dc9e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"<p>Required. Returns only messages sent to the authenticated user.</p>\n"}],"url":"https://sarahah-app-back-end.vercel.app/messages","description":"<p>Retrieve all anonymous messages received by the authenticated user.</p>\n<p>Messages are filtered by the authenticated user's <code>_id</code>, so users only see their own inbox.</p>\n<h2 id=\"requires-token-header\"><strong>Requires:</strong> <code>token</code> header</h2>\n<h2 id=\"requirements\">Requirements</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Location</th>\n<th>Key</th>\n<th>Value</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Header</td>\n<td><code>token</code></td>\n<td><code>&lt;your_jwt_token&gt;</code></td>\n<td>Required. JWT access token received from Sign In.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p>Returns only messages addressed to the authenticated user's inbox.</p>\n</blockquote>\n","urlObject":{"protocol":"https","path":["messages"],"host":["sarahah-app-back-end","vercel","app"],"query":[],"variable":[]}},"response":[{"id":"70462bc2-44f8-44de-bafa-9d6783073e40","name":"200 - All Messages","originalRequest":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. Returns only messages sent to the authenticated user."}],"url":"https://sarahah-app-back-end.vercel.app/messages","description":"Retrieve all anonymous messages received by the authenticated user.\n\nMessages are filtered by the authenticated user's `_id`, so users only see their own inbox.\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n\n> Returns only messages addressed to the authenticated user's inbox."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": [\n    {\n      \"_id\": \"775f1a2b3c4d5e6f7a8b9c1e\",\n      \"content\": \"You are an amazing developer!\",\n      \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n      \"createdAt\": \"2026-04-06T10:00:00.000Z\",\n      \"updatedAt\": \"2026-04-06T10:00:00.000Z\"\n    },\n    {\n      \"_id\": \"885f1a2b3c4d5e6f7a8b9c2f\",\n      \"content\": \"Keep up the great work!\",\n      \"userId\": \"665f1a2b3c4d5e6f7a8b9c0d\",\n      \"createdAt\": \"2026-04-06T11:00:00.000Z\",\n      \"updatedAt\": \"2026-04-06T11:00:00.000Z\"\n    }\n  ]\n}"},{"id":"ae7aaa8b-a869-46c1-8cf4-b49f5e158af9","name":"200 - Empty Inbox","originalRequest":{"method":"GET","header":[{"key":"token","value":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2NWYxYTJiM2M0ZDVlNmY3YThiOWMwZCIsImlhdCI6MTcxNDk5MjAwMCwiZXhwIjoxNzE0OTk1NjAwfQ.abc123exampletoken","description":"Required. Returns only messages sent to the authenticated user."}],"url":"https://sarahah-app-back-end.vercel.app/messages","description":"Retrieve all anonymous messages received by the authenticated user.\n\nMessages are filtered by the authenticated user's `_id`, so users only see their own inbox.\n\n**Requires:** `token` header\n---\n\n## Requirements\n\n| Location | Key | Value | Notes |\n|----------|-----|-------|-------|\n| Header | `token` | `<your_jwt_token>` | Required. JWT access token received from Sign In. |\n\n> Returns only messages addressed to the authenticated user's inbox."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"message\": \"done!\",\n  \"data\": []\n}"}],"_postman_id":"7cccdb34-960d-4e2c-bea5-024bfd81dc9e"}],"id":"6342b3dd-d5e4-499f-acd1-b2666536abd5","description":"<p>Anonymous messaging endpoints.</p>\n<p>Anyone can send a message to a user — <strong>no authentication required</strong> for sending.</p>\n<p>Only the message owner (the recipient) can read their messages — <strong>authentication required</strong> for reading.</p>\n","_postman_id":"6342b3dd-d5e4-499f-acd1-b2666536abd5"}]}